2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Tests option assignment.
39 * In addition to testing gmx::OptionsAssigner, these are the main
40 * tests for the classes from basicoptions.h and basicoptionstorage.h (and
41 * their base classes) that actually implement the behavior, as well as for the
42 * internal implementation of the gmx::Options and gmx::AbstractOptionStorage
45 * \author Teemu Murtola <teemu.murtola@gmail.com>
46 * \ingroup module_options
50 #include "gromacs/options/optionsassigner.h"
55 #include <gtest/gtest.h>
57 #include "gromacs/options/basicoptions.h"
58 #include "gromacs/options/options.h"
59 #include "gromacs/utility/exceptions.h"
60 #include "gromacs/utility/stringutil.h"
65 /********************************************************************
66 * General assignment tests
69 TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
71 gmx::Options options(NULL, NULL);
73 using gmx::IntegerOption;
74 ASSERT_NO_THROW(options.addOption(
75 IntegerOption("p").store(&value).required()));
77 EXPECT_THROW(options.finish(), gmx::InvalidInputError);
80 TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
82 gmx::Options options(NULL, NULL);
84 using gmx::IntegerOption;
85 ASSERT_NO_THROW(options.addOption(
86 IntegerOption("p").store(&value).required()
89 EXPECT_NO_THROW(options.finish());
93 TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
95 gmx::Options options(NULL, NULL);
96 std::vector<int> values;
97 using gmx::IntegerOption;
98 ASSERT_NO_THROW(options.addOption(
99 IntegerOption("p").storeVector(&values).multiValue()));
101 gmx::OptionsAssigner assigner(&options);
102 EXPECT_NO_THROW(assigner.start());
103 ASSERT_NO_THROW(assigner.startOption("p"));
104 ASSERT_NO_THROW(assigner.appendValue("1"));
105 ASSERT_NO_THROW(assigner.finishOption());
106 EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
107 EXPECT_NO_THROW(assigner.finish());
108 EXPECT_NO_THROW(options.finish());
110 EXPECT_TRUE(options.isSet("p"));
111 ASSERT_EQ(1U, values.size());
112 EXPECT_EQ(1, values[0]);
115 TEST(OptionsAssignerTest, HandlesMultipleParameter)
117 gmx::Options options(NULL, NULL);
118 std::vector<int> values;
119 using gmx::IntegerOption;
120 ASSERT_NO_THROW(options.addOption(
121 IntegerOption("p").storeVector(&values).allowMultiple()));
123 gmx::OptionsAssigner assigner(&options);
124 EXPECT_NO_THROW(assigner.start());
125 ASSERT_NO_THROW(assigner.startOption("p"));
126 ASSERT_NO_THROW(assigner.appendValue("1"));
127 EXPECT_NO_THROW(assigner.finishOption());
128 ASSERT_NO_THROW(assigner.startOption("p"));
129 ASSERT_NO_THROW(assigner.appendValue("2"));
130 EXPECT_NO_THROW(assigner.finishOption());
131 EXPECT_NO_THROW(assigner.finish());
132 EXPECT_NO_THROW(options.finish());
134 EXPECT_TRUE(options.isSet("p"));
135 ASSERT_EQ(2U, values.size());
136 EXPECT_EQ(1, values[0]);
137 EXPECT_EQ(2, values[1]);
140 TEST(OptionsAssignerTest, HandlesMissingValue)
142 gmx::Options options(NULL, NULL);
143 int value1 = 0, value2 = 0;
144 using gmx::IntegerOption;
145 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
146 ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
148 gmx::OptionsAssigner assigner(&options);
149 EXPECT_NO_THROW(assigner.start());
150 ASSERT_NO_THROW(assigner.startOption("p"));
151 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
152 ASSERT_NO_THROW(assigner.startOption("q"));
153 ASSERT_NO_THROW(assigner.appendValue("2"));
154 EXPECT_NO_THROW(assigner.finishOption());
155 EXPECT_NO_THROW(assigner.finish());
156 EXPECT_NO_THROW(options.finish());
158 EXPECT_EQ(2, value2);
161 TEST(OptionsAssignerTest, HandlesExtraValue)
163 gmx::Options options(NULL, NULL);
165 using gmx::IntegerOption;
166 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
168 gmx::OptionsAssigner assigner(&options);
169 EXPECT_NO_THROW(assigner.start());
170 ASSERT_NO_THROW(assigner.startOption("p"));
171 ASSERT_NO_THROW(assigner.appendValue("2"));
172 EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
173 EXPECT_NO_THROW(assigner.finishOption());
174 EXPECT_NO_THROW(assigner.finish());
175 EXPECT_NO_THROW(options.finish());
177 EXPECT_EQ(0, value1);
180 TEST(OptionsAssignerTest, HandlesSubSections)
182 gmx::Options options(NULL, NULL);
183 gmx::Options sub1("section1", NULL);
184 gmx::Options sub2("section2", NULL);
188 using gmx::IntegerOption;
189 ASSERT_NO_THROW(options.addSubSection(&sub1));
190 ASSERT_NO_THROW(options.addSubSection(&sub2));
191 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
192 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
193 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
195 gmx::OptionsAssigner assigner(&options);
196 EXPECT_NO_THROW(assigner.start());
197 ASSERT_NO_THROW(assigner.startSubSection("section1"));
198 ASSERT_NO_THROW(assigner.startOption("p"));
199 EXPECT_NO_THROW(assigner.appendValue("5"));
200 EXPECT_NO_THROW(assigner.finishOption());
201 EXPECT_NO_THROW(assigner.finishSubSection());
202 ASSERT_NO_THROW(assigner.startOption("p"));
203 EXPECT_NO_THROW(assigner.appendValue("4"));
204 EXPECT_NO_THROW(assigner.finishOption());
205 ASSERT_NO_THROW(assigner.startSubSection("section2"));
206 ASSERT_NO_THROW(assigner.startOption("p"));
207 EXPECT_NO_THROW(assigner.appendValue("6"));
208 EXPECT_NO_THROW(assigner.finishOption());
209 EXPECT_NO_THROW(assigner.finishSubSection());
210 EXPECT_NO_THROW(assigner.finish());
211 EXPECT_NO_THROW(options.finish());
214 EXPECT_EQ(5, value1);
215 EXPECT_EQ(6, value2);
218 TEST(OptionsAssignerTest, HandlesNoStrictSubSections)
220 gmx::Options options(NULL, NULL);
221 gmx::Options sub1("section1", NULL);
222 gmx::Options sub2("section2", NULL);
228 using gmx::IntegerOption;
229 ASSERT_NO_THROW(options.addSubSection(&sub1));
230 ASSERT_NO_THROW(options.addSubSection(&sub2));
231 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
232 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
233 ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
234 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
235 ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
237 gmx::OptionsAssigner assigner(&options);
238 assigner.setNoStrictSectioning(true);
239 EXPECT_NO_THROW(assigner.start());
240 ASSERT_NO_THROW(assigner.startOption("q"));
241 EXPECT_NO_THROW(assigner.appendValue("6"));
242 EXPECT_NO_THROW(assigner.finishOption());
243 ASSERT_NO_THROW(assigner.startOption("p"));
244 EXPECT_NO_THROW(assigner.appendValue("7"));
245 EXPECT_NO_THROW(assigner.finishOption());
246 ASSERT_NO_THROW(assigner.startOption("r"));
247 EXPECT_NO_THROW(assigner.appendValue("8"));
248 EXPECT_NO_THROW(assigner.finishOption());
249 ASSERT_NO_THROW(assigner.startOption("p"));
250 EXPECT_NO_THROW(assigner.appendValue("9"));
251 EXPECT_NO_THROW(assigner.finishOption());
252 EXPECT_NO_THROW(assigner.finishSubSection());
253 ASSERT_NO_THROW(assigner.startOption("p"));
254 EXPECT_NO_THROW(assigner.appendValue("10"));
255 EXPECT_NO_THROW(assigner.finishOption());
256 EXPECT_NO_THROW(assigner.finish());
257 EXPECT_NO_THROW(options.finish());
259 EXPECT_EQ(6, qvalue);
260 EXPECT_EQ(7, pvalue1);
261 EXPECT_EQ(8, rvalue);
262 EXPECT_EQ(9, pvalue2);
263 EXPECT_EQ(10, pvalue);
266 TEST(OptionsAssignerTest, HandlesMultipleSources)
268 gmx::Options options(NULL, NULL);
270 using gmx::IntegerOption;
271 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
274 gmx::OptionsAssigner assigner(&options);
275 EXPECT_NO_THROW(assigner.start());
276 ASSERT_NO_THROW(assigner.startOption("p"));
277 EXPECT_NO_THROW(assigner.appendValue("1"));
278 EXPECT_NO_THROW(assigner.finishOption());
279 EXPECT_NO_THROW(assigner.finish());
282 gmx::OptionsAssigner assigner2(&options);
283 EXPECT_NO_THROW(assigner2.start());
284 ASSERT_NO_THROW(assigner2.startOption("p"));
285 EXPECT_NO_THROW(assigner2.appendValue("2"));
286 EXPECT_NO_THROW(assigner2.finishOption());
287 EXPECT_NO_THROW(assigner2.finish());
289 EXPECT_NO_THROW(options.finish());
295 /********************************************************************
296 * Tests for boolean assignment
299 TEST(OptionsAssignerBooleanTest, StoresYesValue)
301 gmx::Options options(NULL, NULL);
303 using gmx::BooleanOption;
304 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
306 gmx::OptionsAssigner assigner(&options);
307 EXPECT_NO_THROW(assigner.start());
308 ASSERT_NO_THROW(assigner.startOption("p"));
309 EXPECT_NO_THROW(assigner.appendValue("yes"));
310 EXPECT_NO_THROW(assigner.finishOption());
311 EXPECT_NO_THROW(assigner.finish());
312 EXPECT_NO_THROW(options.finish());
317 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
319 gmx::Options options(NULL, NULL);
321 using gmx::BooleanOption;
322 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
324 gmx::OptionsAssigner assigner(&options);
325 EXPECT_NO_THROW(assigner.start());
326 ASSERT_NO_THROW(assigner.startOption("p"));
327 EXPECT_NO_THROW(assigner.finishOption());
328 EXPECT_NO_THROW(assigner.finish());
329 EXPECT_NO_THROW(options.finish());
334 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
336 gmx::Options options(NULL, NULL);
338 using gmx::BooleanOption;
339 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
341 gmx::OptionsAssigner assigner(&options);
342 assigner.setAcceptBooleanNoPrefix(true);
343 EXPECT_NO_THROW(assigner.start());
344 ASSERT_NO_THROW(assigner.startOption("nop"));
345 EXPECT_NO_THROW(assigner.finishOption());
346 EXPECT_NO_THROW(assigner.finish());
347 EXPECT_NO_THROW(options.finish());
352 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
354 gmx::Options options(NULL, NULL);
356 using gmx::BooleanOption;
357 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
359 gmx::OptionsAssigner assigner(&options);
360 assigner.setAcceptBooleanNoPrefix(true);
361 EXPECT_NO_THROW(assigner.start());
362 ASSERT_NO_THROW(assigner.startOption("nop"));
363 // It's OK to fail, but if it doesn't, it should work.
366 assigner.appendValue("no");
367 assigner.finishOption();
368 EXPECT_NO_THROW(assigner.finish());
371 catch (const gmx::InvalidInputError &)
377 /********************************************************************
378 * Tests for integer assignment
380 * These tests also contain tests for general default value handling.
383 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
385 gmx::Options options(NULL, NULL);
387 using gmx::IntegerOption;
388 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
390 gmx::OptionsAssigner assigner(&options);
391 EXPECT_NO_THROW(assigner.start());
392 ASSERT_NO_THROW(assigner.startOption("p"));
393 ASSERT_NO_THROW(assigner.appendValue("3"));
394 EXPECT_NO_THROW(assigner.finishOption());
395 EXPECT_NO_THROW(assigner.finish());
396 EXPECT_NO_THROW(options.finish());
401 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
403 gmx::Options options(NULL, NULL);
405 using gmx::IntegerOption;
406 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
408 gmx::OptionsAssigner assigner(&options);
409 EXPECT_NO_THROW(assigner.start());
410 ASSERT_NO_THROW(assigner.startOption("p"));
411 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
412 EXPECT_NO_THROW(assigner.finishOption());
413 EXPECT_NO_THROW(assigner.finish());
414 EXPECT_NO_THROW(options.finish());
419 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
421 gmx::Options options(NULL, NULL);
423 using gmx::IntegerOption;
424 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
426 gmx::OptionsAssigner assigner(&options);
427 EXPECT_NO_THROW(assigner.start());
428 ASSERT_NO_THROW(assigner.startOption("p"));
429 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
430 EXPECT_NO_THROW(assigner.finishOption());
431 EXPECT_NO_THROW(assigner.finish());
432 EXPECT_NO_THROW(options.finish());
437 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
439 gmx::Options options(NULL, NULL);
441 using gmx::IntegerOption;
442 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
444 gmx::OptionsAssigner assigner(&options);
445 EXPECT_NO_THROW(assigner.start());
446 ASSERT_NO_THROW(assigner.startOption("p"));
447 std::string overflowValue(
448 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
449 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
450 EXPECT_NO_THROW(assigner.finishOption());
451 EXPECT_NO_THROW(assigner.finish());
452 EXPECT_NO_THROW(options.finish());
457 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
459 gmx::Options options(NULL, NULL);
461 using gmx::IntegerOption;
462 ASSERT_NO_THROW(options.addOption(
463 IntegerOption("p").store(&value).defaultValue(2)));
466 gmx::OptionsAssigner assigner(&options);
467 EXPECT_NO_THROW(assigner.start());
468 EXPECT_NO_THROW(assigner.finish());
469 EXPECT_NO_THROW(options.finish());
474 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
476 gmx::Options options(NULL, NULL);
478 using gmx::IntegerOption;
479 ASSERT_NO_THROW(options.addOption(
480 IntegerOption("p").store(&value).defaultValueIfSet(2)));
481 EXPECT_EQ(-1, value);
483 gmx::OptionsAssigner assigner(&options);
484 EXPECT_NO_THROW(assigner.start());
485 ASSERT_NO_THROW(assigner.startOption("p"));
486 EXPECT_NO_THROW(assigner.finishOption());
487 EXPECT_NO_THROW(assigner.finish());
488 EXPECT_NO_THROW(options.finish());
493 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
495 gmx::Options options(NULL, NULL);
497 using gmx::IntegerOption;
498 ASSERT_NO_THROW(options.addOption(
499 IntegerOption("p").store(&value).defaultValueIfSet(2)));
500 EXPECT_EQ(-1, value);
502 gmx::OptionsAssigner assigner(&options);
503 EXPECT_NO_THROW(assigner.start());
504 EXPECT_NO_THROW(assigner.finish());
505 EXPECT_NO_THROW(options.finish());
507 EXPECT_EQ(-1, value);
510 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
512 gmx::Options options(NULL, NULL);
514 using gmx::IntegerOption;
515 ASSERT_NO_THROW(options.addOption(
516 IntegerOption("p").store(&value)
517 .defaultValue(1).defaultValueIfSet(2)));
520 gmx::OptionsAssigner assigner(&options);
521 EXPECT_NO_THROW(assigner.start());
522 ASSERT_NO_THROW(assigner.startOption("p"));
523 EXPECT_NO_THROW(assigner.finishOption());
524 EXPECT_NO_THROW(assigner.finish());
525 EXPECT_NO_THROW(options.finish());
530 TEST(OptionsAssignerIntegerTest, StoresToVector)
532 gmx::Options options(NULL, NULL);
533 std::vector<int> values;
534 using gmx::IntegerOption;
535 ASSERT_NO_THROW(options.addOption(
536 IntegerOption("p").storeVector(&values).multiValue()));
538 gmx::OptionsAssigner assigner(&options);
539 EXPECT_NO_THROW(assigner.start());
540 ASSERT_NO_THROW(assigner.startOption("p"));
541 ASSERT_NO_THROW(assigner.appendValue("-2"));
542 ASSERT_NO_THROW(assigner.appendValue("1"));
543 ASSERT_NO_THROW(assigner.appendValue("4"));
544 EXPECT_NO_THROW(assigner.finishOption());
545 EXPECT_NO_THROW(assigner.finish());
546 EXPECT_NO_THROW(options.finish());
548 EXPECT_EQ(3U, values.size());
549 EXPECT_EQ(-2, values[0]);
550 EXPECT_EQ(1, values[1]);
551 EXPECT_EQ(4, values[2]);
554 TEST(OptionsAssignerIntegerTest, HandlesVectors)
556 gmx::Options options(NULL, NULL);
557 int vec[3] = {0, 0, 0};
558 using gmx::IntegerOption;
559 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
561 gmx::OptionsAssigner assigner(&options);
562 EXPECT_NO_THROW(assigner.start());
563 ASSERT_NO_THROW(assigner.startOption("p"));
564 ASSERT_NO_THROW(assigner.appendValue("-2"));
565 ASSERT_NO_THROW(assigner.appendValue("1"));
566 ASSERT_NO_THROW(assigner.appendValue("4"));
567 EXPECT_NO_THROW(assigner.finishOption());
568 EXPECT_NO_THROW(assigner.finish());
569 EXPECT_NO_THROW(options.finish());
571 EXPECT_EQ(-2, vec[0]);
572 EXPECT_EQ(1, vec[1]);
573 EXPECT_EQ(4, vec[2]);
576 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
578 gmx::Options options(NULL, NULL);
579 int vec[3] = {0, 0, 0};
580 using gmx::IntegerOption;
581 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
583 gmx::OptionsAssigner assigner(&options);
584 EXPECT_NO_THROW(assigner.start());
585 ASSERT_NO_THROW(assigner.startOption("p"));
586 ASSERT_NO_THROW(assigner.appendValue("2"));
587 EXPECT_NO_THROW(assigner.finishOption());
588 EXPECT_NO_THROW(assigner.finish());
589 EXPECT_NO_THROW(options.finish());
591 EXPECT_EQ(2, vec[0]);
592 EXPECT_EQ(2, vec[1]);
593 EXPECT_EQ(2, vec[2]);
596 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
598 gmx::Options options(NULL, NULL);
599 int vec[3] = {3, 2, 1};
600 using gmx::IntegerOption;
601 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
603 EXPECT_NO_THROW(options.finish());
605 EXPECT_EQ(3, vec[0]);
606 EXPECT_EQ(2, vec[1]);
607 EXPECT_EQ(1, vec[2]);
610 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
612 gmx::Options options(NULL, NULL);
613 int vec[3] = {3, 2, 1};
614 std::vector<int> vec2(vec, vec+3);
615 using gmx::IntegerOption;
616 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec)
617 .storeVector(&vec2).vector()));
619 gmx::OptionsAssigner assigner(&options);
620 EXPECT_NO_THROW(assigner.start());
621 ASSERT_NO_THROW(assigner.startOption("p"));
622 EXPECT_NO_THROW(assigner.appendValue("1"));
623 EXPECT_NO_THROW(assigner.appendValue("3"));
624 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
625 EXPECT_NO_THROW(assigner.finish());
626 EXPECT_NO_THROW(options.finish());
628 EXPECT_EQ(3, vec[0]);
629 EXPECT_EQ(2, vec[1]);
630 EXPECT_EQ(1, vec[2]);
631 ASSERT_EQ(3U, vec2.size());
632 EXPECT_EQ(3, vec2[0]);
633 EXPECT_EQ(2, vec2[1]);
634 EXPECT_EQ(1, vec2[2]);
638 /********************************************************************
639 * Tests for double assignment
642 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
644 gmx::Options options(NULL, NULL);
646 using gmx::DoubleOption;
647 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
649 gmx::OptionsAssigner assigner(&options);
650 EXPECT_NO_THROW(assigner.start());
651 ASSERT_NO_THROW(assigner.startOption("p"));
652 ASSERT_NO_THROW(assigner.appendValue("2.7"));
653 EXPECT_NO_THROW(assigner.finishOption());
654 EXPECT_NO_THROW(assigner.finish());
655 EXPECT_NO_THROW(options.finish());
657 EXPECT_DOUBLE_EQ(2.7, value);
660 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
662 gmx::Options options(NULL, NULL);
664 using gmx::DoubleOption;
665 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
667 gmx::OptionsAssigner assigner(&options);
668 EXPECT_NO_THROW(assigner.start());
669 ASSERT_NO_THROW(assigner.startOption("p"));
670 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
671 EXPECT_NO_THROW(assigner.finishOption());
672 EXPECT_NO_THROW(assigner.finish());
673 EXPECT_NO_THROW(options.finish());
675 EXPECT_DOUBLE_EQ(1.0, value);
679 /********************************************************************
680 * Tests for string assignment
683 TEST(OptionsAssignerStringTest, StoresSingleValue)
685 gmx::Options options(NULL, NULL);
687 using gmx::StringOption;
688 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
690 gmx::OptionsAssigner assigner(&options);
691 EXPECT_NO_THROW(assigner.start());
692 ASSERT_NO_THROW(assigner.startOption("p"));
693 ASSERT_NO_THROW(assigner.appendValue("value"));
694 EXPECT_NO_THROW(assigner.finishOption());
695 EXPECT_NO_THROW(assigner.finish());
696 EXPECT_NO_THROW(options.finish());
698 EXPECT_EQ("value", value);
701 TEST(OptionsAssignerStringTest, HandlesEnumValue)
703 gmx::Options options(NULL, NULL);
705 const char * const allowed[] = { "none", "test", "value" };
707 using gmx::StringOption;
708 ASSERT_NO_THROW(options.addOption(
709 StringOption("p").store(&value)
710 .enumValue(allowed).storeEnumIndex(&index)));
712 gmx::OptionsAssigner assigner(&options);
713 EXPECT_NO_THROW(assigner.start());
714 ASSERT_NO_THROW(assigner.startOption("p"));
715 ASSERT_NO_THROW(assigner.appendValue("test"));
716 EXPECT_NO_THROW(assigner.finishOption());
717 EXPECT_NO_THROW(assigner.finish());
718 EXPECT_NO_THROW(options.finish());
720 EXPECT_EQ("test", value);
724 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
726 gmx::Options options(NULL, NULL);
728 const char * const allowed[] = { "none", "test", "value", NULL };
730 using gmx::StringOption;
731 ASSERT_NO_THROW(options.addOption(
732 StringOption("p").store(&value)
733 .enumValueFromNullTerminatedArray(allowed)
734 .storeEnumIndex(&index)));
736 gmx::OptionsAssigner assigner(&options);
737 EXPECT_NO_THROW(assigner.start());
738 ASSERT_NO_THROW(assigner.startOption("p"));
739 ASSERT_NO_THROW(assigner.appendValue("value"));
740 EXPECT_NO_THROW(assigner.finishOption());
741 EXPECT_NO_THROW(assigner.finish());
742 EXPECT_NO_THROW(options.finish());
744 EXPECT_EQ("value", value);
748 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
750 gmx::Options options(NULL, NULL);
752 const char * const allowed[] = { "none", "test", "value" };
754 using gmx::StringOption;
755 ASSERT_NO_THROW(options.addOption(
756 StringOption("p").store(&value)
757 .enumValue(allowed).storeEnumIndex(&index)));
759 gmx::OptionsAssigner assigner(&options);
760 EXPECT_NO_THROW(assigner.start());
761 ASSERT_NO_THROW(assigner.startOption("p"));
762 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
765 TEST(OptionsAssignerStringTest, CompletesEnumValue)
767 gmx::Options options(NULL, NULL);
769 const char * const allowed[] = { "none", "test", "value" };
771 using gmx::StringOption;
772 ASSERT_NO_THROW(options.addOption(
773 StringOption("p").store(&value)
774 .enumValue(allowed).storeEnumIndex(&index)));
776 gmx::OptionsAssigner assigner(&options);
777 EXPECT_NO_THROW(assigner.start());
778 ASSERT_NO_THROW(assigner.startOption("p"));
779 ASSERT_NO_THROW(assigner.appendValue("te"));
780 EXPECT_NO_THROW(assigner.finishOption());
781 EXPECT_NO_THROW(assigner.finish());
782 EXPECT_NO_THROW(options.finish());
784 EXPECT_EQ("test", value);
788 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
790 gmx::Options options(NULL, NULL);
792 const char * const allowed[] = { "none", "test", "value" };
794 using gmx::StringOption;
795 ASSERT_NO_THROW(options.addOption(
796 StringOption("p").store(&value)
797 .enumValue(allowed).storeEnumIndex(&index)));
798 EXPECT_TRUE(value.empty());
799 EXPECT_EQ(-1, index);
801 ASSERT_NO_THROW(options.finish());
803 EXPECT_TRUE(value.empty());
804 EXPECT_EQ(-1, index);
807 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
809 gmx::Options options(NULL, NULL);
811 const char * const allowed[] = { "none", "test", "value" };
813 using gmx::StringOption;
814 ASSERT_NO_THROW(options.addOption(
815 StringOption("p").store(&value)
816 .enumValue(allowed).defaultValue("test")
817 .storeEnumIndex(&index)));
818 EXPECT_EQ("test", value);
821 gmx::OptionsAssigner assigner(&options);
822 EXPECT_NO_THROW(assigner.start());
823 EXPECT_NO_THROW(assigner.finish());
824 EXPECT_NO_THROW(options.finish());
826 EXPECT_EQ("test", value);
830 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable)
832 gmx::Options options(NULL, NULL);
833 std::string value("test");
834 const char * const allowed[] = { "none", "test", "value" };
836 using gmx::StringOption;
837 ASSERT_NO_THROW(options.addOption(
838 StringOption("p").store(&value)
839 .enumValue(allowed).storeEnumIndex(&index)));
840 EXPECT_EQ("test", value);
843 gmx::OptionsAssigner assigner(&options);
844 EXPECT_NO_THROW(assigner.start());
845 EXPECT_NO_THROW(assigner.finish());
846 EXPECT_NO_THROW(options.finish());
848 EXPECT_EQ("test", value);
852 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector)
854 gmx::Options options(NULL, NULL);
855 std::vector<std::string> value;
856 value.push_back("test");
857 value.push_back("value");
858 const char * const allowed[] = { "none", "test", "value" };
859 int index[2] = {-1, -1};
860 using gmx::StringOption;
861 ASSERT_NO_THROW(options.addOption(
862 StringOption("p").storeVector(&value).valueCount(2)
863 .enumValue(allowed).storeEnumIndex(index)));
864 EXPECT_EQ("test", value[0]);
865 EXPECT_EQ("value", value[1]);
866 EXPECT_EQ(1, index[0]);
867 EXPECT_EQ(2, index[1]);
869 gmx::OptionsAssigner assigner(&options);
870 EXPECT_NO_THROW(assigner.start());
871 EXPECT_NO_THROW(assigner.finish());
872 EXPECT_NO_THROW(options.finish());
874 EXPECT_EQ("test", value[0]);
875 EXPECT_EQ("value", value[1]);
876 EXPECT_EQ(1, index[0]);
877 EXPECT_EQ(2, index[1]);
880 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
882 gmx::Options options(NULL, NULL);
884 const char * const allowed[] = { "none", "test", "value" };
886 using gmx::StringOption;
887 ASSERT_NO_THROW(options.addOption(
888 StringOption("p").store(&value)
889 .enumValue(allowed).defaultEnumIndex(1)
890 .storeEnumIndex(&index)));
891 EXPECT_EQ("test", value);
894 gmx::OptionsAssigner assigner(&options);
895 EXPECT_NO_THROW(assigner.start());
896 EXPECT_NO_THROW(assigner.finish());
897 EXPECT_NO_THROW(options.finish());
899 EXPECT_EQ("test", value);
903 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndexFromVariable)
905 gmx::Options options(NULL, NULL);
906 const char * const allowed[] = { "none", "test", "value" };
908 using gmx::StringOption;
909 ASSERT_NO_THROW(options.addOption(
911 .enumValue(allowed).storeEnumIndex(&index)));
914 gmx::OptionsAssigner assigner(&options);
915 EXPECT_NO_THROW(assigner.start());
916 EXPECT_NO_THROW(assigner.finish());
917 EXPECT_NO_THROW(options.finish());