2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014,2015, 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"
62 #include "testutils/testasserts.h"
67 /********************************************************************
68 * General assignment tests
71 TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
73 gmx::Options options(NULL, NULL);
75 using gmx::IntegerOption;
76 ASSERT_NO_THROW(options.addOption(
77 IntegerOption("p").store(&value).required()));
79 EXPECT_THROW(options.finish(), gmx::InvalidInputError);
82 TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
84 gmx::Options options(NULL, NULL);
86 using gmx::IntegerOption;
87 ASSERT_NO_THROW(options.addOption(
88 IntegerOption("p").store(&value).required()
91 EXPECT_NO_THROW(options.finish());
95 TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
97 gmx::Options options(NULL, NULL);
98 std::vector<int> values;
100 using gmx::IntegerOption;
101 ASSERT_NO_THROW(options.addOption(
103 .storeVector(&values).storeIsSet(&bIsSet)
106 gmx::OptionsAssigner assigner(&options);
107 EXPECT_NO_THROW(assigner.start());
108 ASSERT_NO_THROW(assigner.startOption("p"));
109 ASSERT_NO_THROW(assigner.appendValue("1"));
110 ASSERT_NO_THROW(assigner.finishOption());
111 EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
112 EXPECT_NO_THROW(assigner.finish());
113 EXPECT_NO_THROW(options.finish());
116 ASSERT_EQ(1U, values.size());
117 EXPECT_EQ(1, values[0]);
120 TEST(OptionsAssignerTest, HandlesMultipleParameter)
122 gmx::Options options(NULL, NULL);
123 std::vector<int> values;
125 using gmx::IntegerOption;
126 ASSERT_NO_THROW(options.addOption(
128 .storeVector(&values).storeIsSet(&bIsSet)
131 gmx::OptionsAssigner assigner(&options);
132 EXPECT_NO_THROW_GMX(assigner.start());
133 ASSERT_NO_THROW_GMX(assigner.startOption("p"));
134 ASSERT_NO_THROW_GMX(assigner.appendValue("1"));
135 EXPECT_NO_THROW_GMX(assigner.finishOption());
136 ASSERT_NO_THROW_GMX(assigner.startOption("p"));
137 ASSERT_NO_THROW_GMX(assigner.appendValue("2"));
138 EXPECT_NO_THROW_GMX(assigner.finishOption());
139 EXPECT_NO_THROW_GMX(assigner.finish());
140 EXPECT_NO_THROW_GMX(options.finish());
143 ASSERT_EQ(2U, values.size());
144 EXPECT_EQ(1, values[0]);
145 EXPECT_EQ(2, values[1]);
148 TEST(OptionsAssignerTest, HandlesMissingValue)
150 gmx::Options options(NULL, NULL);
151 int value1 = 0, value2 = 0;
152 using gmx::IntegerOption;
153 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
154 ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
156 gmx::OptionsAssigner assigner(&options);
157 EXPECT_NO_THROW(assigner.start());
158 ASSERT_NO_THROW(assigner.startOption("p"));
159 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
160 ASSERT_NO_THROW(assigner.startOption("q"));
161 ASSERT_NO_THROW(assigner.appendValue("2"));
162 EXPECT_NO_THROW(assigner.finishOption());
163 EXPECT_NO_THROW(assigner.finish());
164 EXPECT_NO_THROW(options.finish());
166 EXPECT_EQ(2, value2);
169 TEST(OptionsAssignerTest, HandlesExtraValue)
171 gmx::Options options(NULL, NULL);
173 using gmx::IntegerOption;
174 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
176 gmx::OptionsAssigner assigner(&options);
177 EXPECT_NO_THROW(assigner.start());
178 ASSERT_NO_THROW(assigner.startOption("p"));
179 ASSERT_NO_THROW(assigner.appendValue("2"));
180 EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
181 EXPECT_NO_THROW(assigner.finishOption());
182 EXPECT_NO_THROW(assigner.finish());
183 EXPECT_NO_THROW(options.finish());
185 EXPECT_EQ(0, value1);
188 TEST(OptionsAssignerTest, HandlesGroups)
190 gmx::Options options(NULL, NULL);
191 gmx::IOptionsContainer &group1 = options.addGroup();
192 gmx::IOptionsContainer &group2 = options.addGroup();
196 using gmx::IntegerOption;
197 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
198 ASSERT_NO_THROW(group1.addOption(IntegerOption("q").store(&value1)));
199 ASSERT_NO_THROW(group2.addOption(IntegerOption("r").store(&value2)));
201 gmx::OptionsAssigner assigner(&options);
202 EXPECT_NO_THROW(assigner.start());
203 ASSERT_NO_THROW(assigner.startOption("p"));
204 EXPECT_NO_THROW(assigner.appendValue("5"));
205 EXPECT_NO_THROW(assigner.finishOption());
206 ASSERT_NO_THROW(assigner.startOption("q"));
207 EXPECT_NO_THROW(assigner.appendValue("4"));
208 EXPECT_NO_THROW(assigner.finishOption());
209 ASSERT_NO_THROW(assigner.startOption("r"));
210 EXPECT_NO_THROW(assigner.appendValue("6"));
211 EXPECT_NO_THROW(assigner.finishOption());
212 EXPECT_NO_THROW(assigner.finish());
213 EXPECT_NO_THROW(options.finish());
216 EXPECT_EQ(4, value1);
217 EXPECT_EQ(6, value2);
220 TEST(OptionsAssignerTest, HandlesSubSections)
222 gmx::Options options(NULL, NULL);
223 gmx::Options sub1("section1", NULL);
224 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(&value)));
232 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
233 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
235 gmx::OptionsAssigner assigner(&options);
236 EXPECT_NO_THROW(assigner.start());
237 ASSERT_NO_THROW(assigner.startSubSection("section1"));
238 ASSERT_NO_THROW(assigner.startOption("p"));
239 EXPECT_NO_THROW(assigner.appendValue("5"));
240 EXPECT_NO_THROW(assigner.finishOption());
241 EXPECT_NO_THROW(assigner.finishSubSection());
242 ASSERT_NO_THROW(assigner.startOption("p"));
243 EXPECT_NO_THROW(assigner.appendValue("4"));
244 EXPECT_NO_THROW(assigner.finishOption());
245 ASSERT_NO_THROW(assigner.startSubSection("section2"));
246 ASSERT_NO_THROW(assigner.startOption("p"));
247 EXPECT_NO_THROW(assigner.appendValue("6"));
248 EXPECT_NO_THROW(assigner.finishOption());
249 EXPECT_NO_THROW(assigner.finishSubSection());
250 EXPECT_NO_THROW(assigner.finish());
251 EXPECT_NO_THROW(options.finish());
254 EXPECT_EQ(5, value1);
255 EXPECT_EQ(6, value2);
258 TEST(OptionsAssignerTest, HandlesMultipleSources)
260 gmx::Options options(NULL, NULL);
262 using gmx::IntegerOption;
263 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
266 gmx::OptionsAssigner assigner(&options);
267 EXPECT_NO_THROW(assigner.start());
268 ASSERT_NO_THROW(assigner.startOption("p"));
269 EXPECT_NO_THROW(assigner.appendValue("1"));
270 EXPECT_NO_THROW(assigner.finishOption());
271 EXPECT_NO_THROW(assigner.finish());
274 gmx::OptionsAssigner assigner2(&options);
275 EXPECT_NO_THROW(assigner2.start());
276 ASSERT_NO_THROW(assigner2.startOption("p"));
277 EXPECT_NO_THROW(assigner2.appendValue("2"));
278 EXPECT_NO_THROW(assigner2.finishOption());
279 EXPECT_NO_THROW(assigner2.finish());
281 EXPECT_NO_THROW(options.finish());
287 /********************************************************************
288 * Tests for boolean assignment
291 TEST(OptionsAssignerBooleanTest, StoresYesValue)
293 gmx::Options options(NULL, NULL);
295 using gmx::BooleanOption;
296 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
298 gmx::OptionsAssigner assigner(&options);
299 EXPECT_NO_THROW(assigner.start());
300 ASSERT_NO_THROW(assigner.startOption("p"));
301 EXPECT_NO_THROW(assigner.appendValue("yes"));
302 EXPECT_NO_THROW(assigner.finishOption());
303 EXPECT_NO_THROW(assigner.finish());
304 EXPECT_NO_THROW(options.finish());
309 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
311 gmx::Options options(NULL, NULL);
313 using gmx::BooleanOption;
314 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
316 gmx::OptionsAssigner assigner(&options);
317 EXPECT_NO_THROW(assigner.start());
318 ASSERT_NO_THROW(assigner.startOption("p"));
319 EXPECT_NO_THROW(assigner.finishOption());
320 EXPECT_NO_THROW(assigner.finish());
321 EXPECT_NO_THROW(options.finish());
326 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
328 gmx::Options options(NULL, NULL);
330 using gmx::BooleanOption;
331 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
333 gmx::OptionsAssigner assigner(&options);
334 assigner.setAcceptBooleanNoPrefix(true);
335 EXPECT_NO_THROW(assigner.start());
336 ASSERT_NO_THROW(assigner.startOption("nop"));
337 EXPECT_NO_THROW(assigner.finishOption());
338 EXPECT_NO_THROW(assigner.finish());
339 EXPECT_NO_THROW(options.finish());
344 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
346 gmx::Options options(NULL, NULL);
348 using gmx::BooleanOption;
349 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
351 gmx::OptionsAssigner assigner(&options);
352 assigner.setAcceptBooleanNoPrefix(true);
353 EXPECT_NO_THROW(assigner.start());
354 ASSERT_NO_THROW(assigner.startOption("nop"));
355 // It's OK to fail, but if it doesn't, it should work.
358 assigner.appendValue("no");
359 assigner.finishOption();
360 EXPECT_NO_THROW(assigner.finish());
363 catch (const gmx::InvalidInputError &)
369 /********************************************************************
370 * Tests for integer assignment
372 * These tests also contain tests for general default value handling.
375 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
377 gmx::Options options(NULL, NULL);
379 using gmx::IntegerOption;
380 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
382 gmx::OptionsAssigner assigner(&options);
383 EXPECT_NO_THROW(assigner.start());
384 ASSERT_NO_THROW(assigner.startOption("p"));
385 ASSERT_NO_THROW(assigner.appendValue("3"));
386 EXPECT_NO_THROW(assigner.finishOption());
387 EXPECT_NO_THROW(assigner.finish());
388 EXPECT_NO_THROW(options.finish());
393 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
395 gmx::Options options(NULL, NULL);
397 using gmx::IntegerOption;
398 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
400 gmx::OptionsAssigner assigner(&options);
401 EXPECT_NO_THROW(assigner.start());
402 ASSERT_NO_THROW(assigner.startOption("p"));
403 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
404 EXPECT_NO_THROW(assigner.finishOption());
405 EXPECT_NO_THROW(assigner.finish());
406 EXPECT_NO_THROW(options.finish());
411 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
413 gmx::Options options(NULL, NULL);
415 using gmx::IntegerOption;
416 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
418 gmx::OptionsAssigner assigner(&options);
419 EXPECT_NO_THROW(assigner.start());
420 ASSERT_NO_THROW(assigner.startOption("p"));
421 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
422 EXPECT_NO_THROW(assigner.finishOption());
423 EXPECT_NO_THROW(assigner.finish());
424 EXPECT_NO_THROW(options.finish());
429 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
431 gmx::Options options(NULL, NULL);
433 using gmx::IntegerOption;
434 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
436 gmx::OptionsAssigner assigner(&options);
437 EXPECT_NO_THROW(assigner.start());
438 ASSERT_NO_THROW(assigner.startOption("p"));
439 std::string overflowValue(
440 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
441 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
442 EXPECT_NO_THROW(assigner.finishOption());
443 EXPECT_NO_THROW(assigner.finish());
444 EXPECT_NO_THROW(options.finish());
449 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
451 gmx::Options options(NULL, NULL);
453 using gmx::IntegerOption;
454 ASSERT_NO_THROW(options.addOption(
455 IntegerOption("p").store(&value).defaultValue(2)));
458 gmx::OptionsAssigner assigner(&options);
459 EXPECT_NO_THROW(assigner.start());
460 EXPECT_NO_THROW(assigner.finish());
461 EXPECT_NO_THROW(options.finish());
466 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
468 gmx::Options options(NULL, NULL);
470 using gmx::IntegerOption;
471 ASSERT_NO_THROW(options.addOption(
472 IntegerOption("p").store(&value).defaultValueIfSet(2)));
473 EXPECT_EQ(-1, value);
475 gmx::OptionsAssigner assigner(&options);
476 EXPECT_NO_THROW(assigner.start());
477 ASSERT_NO_THROW(assigner.startOption("p"));
478 EXPECT_NO_THROW(assigner.finishOption());
479 EXPECT_NO_THROW(assigner.finish());
480 EXPECT_NO_THROW(options.finish());
485 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
487 gmx::Options options(NULL, NULL);
489 using gmx::IntegerOption;
490 ASSERT_NO_THROW(options.addOption(
491 IntegerOption("p").store(&value).defaultValueIfSet(2)));
492 EXPECT_EQ(-1, value);
494 gmx::OptionsAssigner assigner(&options);
495 EXPECT_NO_THROW(assigner.start());
496 EXPECT_NO_THROW(assigner.finish());
497 EXPECT_NO_THROW(options.finish());
499 EXPECT_EQ(-1, value);
502 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
504 gmx::Options options(NULL, NULL);
506 using gmx::IntegerOption;
507 ASSERT_NO_THROW(options.addOption(
508 IntegerOption("p").store(&value)
509 .defaultValue(1).defaultValueIfSet(2)));
512 gmx::OptionsAssigner assigner(&options);
513 EXPECT_NO_THROW(assigner.start());
514 ASSERT_NO_THROW(assigner.startOption("p"));
515 EXPECT_NO_THROW(assigner.finishOption());
516 EXPECT_NO_THROW(assigner.finish());
517 EXPECT_NO_THROW(options.finish());
522 TEST(OptionsAssignerIntegerTest, StoresToVector)
524 gmx::Options options(NULL, NULL);
525 std::vector<int> values;
526 using gmx::IntegerOption;
527 ASSERT_NO_THROW(options.addOption(
528 IntegerOption("p").storeVector(&values).multiValue()));
530 gmx::OptionsAssigner assigner(&options);
531 EXPECT_NO_THROW(assigner.start());
532 ASSERT_NO_THROW(assigner.startOption("p"));
533 ASSERT_NO_THROW(assigner.appendValue("-2"));
534 ASSERT_NO_THROW(assigner.appendValue("1"));
535 ASSERT_NO_THROW(assigner.appendValue("4"));
536 EXPECT_NO_THROW(assigner.finishOption());
537 EXPECT_NO_THROW(assigner.finish());
538 EXPECT_NO_THROW(options.finish());
540 EXPECT_EQ(3U, values.size());
541 EXPECT_EQ(-2, values[0]);
542 EXPECT_EQ(1, values[1]);
543 EXPECT_EQ(4, values[2]);
546 TEST(OptionsAssignerIntegerTest, HandlesVectors)
548 gmx::Options options(NULL, NULL);
549 int vec[3] = {0, 0, 0};
550 using gmx::IntegerOption;
551 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
553 gmx::OptionsAssigner assigner(&options);
554 EXPECT_NO_THROW(assigner.start());
555 ASSERT_NO_THROW(assigner.startOption("p"));
556 ASSERT_NO_THROW(assigner.appendValue("-2"));
557 ASSERT_NO_THROW(assigner.appendValue("1"));
558 ASSERT_NO_THROW(assigner.appendValue("4"));
559 EXPECT_NO_THROW(assigner.finishOption());
560 EXPECT_NO_THROW(assigner.finish());
561 EXPECT_NO_THROW(options.finish());
563 EXPECT_EQ(-2, vec[0]);
564 EXPECT_EQ(1, vec[1]);
565 EXPECT_EQ(4, vec[2]);
568 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
570 gmx::Options options(NULL, NULL);
571 int vec[3] = {0, 0, 0};
572 using gmx::IntegerOption;
573 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
575 gmx::OptionsAssigner assigner(&options);
576 EXPECT_NO_THROW(assigner.start());
577 ASSERT_NO_THROW(assigner.startOption("p"));
578 ASSERT_NO_THROW(assigner.appendValue("2"));
579 EXPECT_NO_THROW(assigner.finishOption());
580 EXPECT_NO_THROW(assigner.finish());
581 EXPECT_NO_THROW(options.finish());
583 EXPECT_EQ(2, vec[0]);
584 EXPECT_EQ(2, vec[1]);
585 EXPECT_EQ(2, vec[2]);
588 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
590 gmx::Options options(NULL, NULL);
591 int vec[3] = {3, 2, 1};
592 using gmx::IntegerOption;
593 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
595 EXPECT_NO_THROW(options.finish());
597 EXPECT_EQ(3, vec[0]);
598 EXPECT_EQ(2, vec[1]);
599 EXPECT_EQ(1, vec[2]);
602 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
604 gmx::Options options(NULL, NULL);
605 int vec[3] = {3, 2, 1};
606 std::vector<int> vec2(vec, vec+3);
607 using gmx::IntegerOption;
608 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec)
609 .storeVector(&vec2).vector()));
611 gmx::OptionsAssigner assigner(&options);
612 EXPECT_NO_THROW(assigner.start());
613 ASSERT_NO_THROW(assigner.startOption("p"));
614 EXPECT_NO_THROW(assigner.appendValue("1"));
615 EXPECT_NO_THROW(assigner.appendValue("3"));
616 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
617 EXPECT_NO_THROW(assigner.finish());
618 EXPECT_NO_THROW(options.finish());
620 EXPECT_EQ(3, vec[0]);
621 EXPECT_EQ(2, vec[1]);
622 EXPECT_EQ(1, vec[2]);
623 ASSERT_EQ(3U, vec2.size());
624 EXPECT_EQ(3, vec2[0]);
625 EXPECT_EQ(2, vec2[1]);
626 EXPECT_EQ(1, vec2[2]);
630 /********************************************************************
631 * Tests for double assignment
634 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
636 gmx::Options options(NULL, NULL);
638 using gmx::DoubleOption;
639 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
641 gmx::OptionsAssigner assigner(&options);
642 EXPECT_NO_THROW(assigner.start());
643 ASSERT_NO_THROW(assigner.startOption("p"));
644 ASSERT_NO_THROW(assigner.appendValue("2.7"));
645 EXPECT_NO_THROW(assigner.finishOption());
646 EXPECT_NO_THROW(assigner.finish());
647 EXPECT_NO_THROW(options.finish());
649 EXPECT_DOUBLE_EQ(2.7, value);
652 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
654 gmx::Options options(NULL, NULL);
656 using gmx::DoubleOption;
657 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
659 gmx::OptionsAssigner assigner(&options);
660 EXPECT_NO_THROW(assigner.start());
661 ASSERT_NO_THROW(assigner.startOption("p"));
662 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
663 EXPECT_NO_THROW(assigner.finishOption());
664 EXPECT_NO_THROW(assigner.finish());
665 EXPECT_NO_THROW(options.finish());
667 EXPECT_DOUBLE_EQ(1.0, value);
671 /********************************************************************
672 * Tests for string assignment
675 TEST(OptionsAssignerStringTest, StoresSingleValue)
677 gmx::Options options(NULL, NULL);
679 using gmx::StringOption;
680 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
682 gmx::OptionsAssigner assigner(&options);
683 EXPECT_NO_THROW(assigner.start());
684 ASSERT_NO_THROW(assigner.startOption("p"));
685 ASSERT_NO_THROW(assigner.appendValue("value"));
686 EXPECT_NO_THROW(assigner.finishOption());
687 EXPECT_NO_THROW(assigner.finish());
688 EXPECT_NO_THROW(options.finish());
690 EXPECT_EQ("value", value);
693 TEST(OptionsAssignerStringTest, HandlesEnumValue)
695 gmx::Options options(NULL, NULL);
697 const char * const allowed[] = { "none", "test", "value" };
699 using gmx::StringOption;
700 ASSERT_NO_THROW(options.addOption(
701 StringOption("p").store(&value)
702 .enumValue(allowed).storeEnumIndex(&index)));
704 gmx::OptionsAssigner assigner(&options);
705 EXPECT_NO_THROW(assigner.start());
706 ASSERT_NO_THROW(assigner.startOption("p"));
707 ASSERT_NO_THROW(assigner.appendValue("test"));
708 EXPECT_NO_THROW(assigner.finishOption());
709 EXPECT_NO_THROW(assigner.finish());
710 EXPECT_NO_THROW(options.finish());
712 EXPECT_EQ("test", value);
716 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
718 gmx::Options options(NULL, NULL);
720 const char * const allowed[] = { "none", "test", "value", NULL };
722 using gmx::StringOption;
723 ASSERT_NO_THROW(options.addOption(
724 StringOption("p").store(&value)
725 .enumValueFromNullTerminatedArray(allowed)
726 .storeEnumIndex(&index)));
728 gmx::OptionsAssigner assigner(&options);
729 EXPECT_NO_THROW(assigner.start());
730 ASSERT_NO_THROW(assigner.startOption("p"));
731 ASSERT_NO_THROW(assigner.appendValue("value"));
732 EXPECT_NO_THROW(assigner.finishOption());
733 EXPECT_NO_THROW(assigner.finish());
734 EXPECT_NO_THROW(options.finish());
736 EXPECT_EQ("value", value);
740 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
742 gmx::Options options(NULL, NULL);
744 const char * const allowed[] = { "none", "test", "value" };
746 using gmx::StringOption;
747 ASSERT_NO_THROW(options.addOption(
748 StringOption("p").store(&value)
749 .enumValue(allowed).storeEnumIndex(&index)));
751 gmx::OptionsAssigner assigner(&options);
752 EXPECT_NO_THROW(assigner.start());
753 ASSERT_NO_THROW(assigner.startOption("p"));
754 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
757 TEST(OptionsAssignerStringTest, CompletesEnumValue)
759 gmx::Options options(NULL, NULL);
761 const char * const allowed[] = { "none", "test", "value" };
763 using gmx::StringOption;
764 ASSERT_NO_THROW(options.addOption(
765 StringOption("p").store(&value)
766 .enumValue(allowed).storeEnumIndex(&index)));
768 gmx::OptionsAssigner assigner(&options);
769 EXPECT_NO_THROW(assigner.start());
770 ASSERT_NO_THROW(assigner.startOption("p"));
771 ASSERT_NO_THROW(assigner.appendValue("te"));
772 EXPECT_NO_THROW(assigner.finishOption());
773 EXPECT_NO_THROW(assigner.finish());
774 EXPECT_NO_THROW(options.finish());
776 EXPECT_EQ("test", value);
780 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
782 gmx::Options options(NULL, NULL);
784 const char * const allowed[] = { "none", "test", "value" };
786 using gmx::StringOption;
787 ASSERT_NO_THROW(options.addOption(
788 StringOption("p").store(&value)
789 .enumValue(allowed).storeEnumIndex(&index)));
790 EXPECT_TRUE(value.empty());
791 EXPECT_EQ(-1, index);
793 ASSERT_NO_THROW(options.finish());
795 EXPECT_TRUE(value.empty());
796 EXPECT_EQ(-1, index);
799 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
801 gmx::Options options(NULL, NULL);
803 const char * const allowed[] = { "none", "test", "value" };
805 using gmx::StringOption;
806 ASSERT_NO_THROW(options.addOption(
807 StringOption("p").store(&value)
808 .enumValue(allowed).defaultValue("test")
809 .storeEnumIndex(&index)));
810 EXPECT_EQ("test", value);
813 gmx::OptionsAssigner assigner(&options);
814 EXPECT_NO_THROW(assigner.start());
815 EXPECT_NO_THROW(assigner.finish());
816 EXPECT_NO_THROW(options.finish());
818 EXPECT_EQ("test", value);
822 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable)
824 gmx::Options options(NULL, NULL);
825 std::string value("test");
826 const char * const allowed[] = { "none", "test", "value" };
828 using gmx::StringOption;
829 ASSERT_NO_THROW(options.addOption(
830 StringOption("p").store(&value)
831 .enumValue(allowed).storeEnumIndex(&index)));
832 EXPECT_EQ("test", value);
835 gmx::OptionsAssigner assigner(&options);
836 EXPECT_NO_THROW(assigner.start());
837 EXPECT_NO_THROW(assigner.finish());
838 EXPECT_NO_THROW(options.finish());
840 EXPECT_EQ("test", value);
844 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector)
846 gmx::Options options(NULL, NULL);
847 std::vector<std::string> value;
848 value.push_back("test");
849 value.push_back("value");
850 const char * const allowed[] = { "none", "test", "value" };
851 int index[2] = {-1, -1};
852 using gmx::StringOption;
853 ASSERT_NO_THROW(options.addOption(
854 StringOption("p").storeVector(&value).valueCount(2)
855 .enumValue(allowed).storeEnumIndex(index)));
856 EXPECT_EQ("test", value[0]);
857 EXPECT_EQ("value", value[1]);
858 EXPECT_EQ(1, index[0]);
859 EXPECT_EQ(2, index[1]);
861 gmx::OptionsAssigner assigner(&options);
862 EXPECT_NO_THROW(assigner.start());
863 EXPECT_NO_THROW(assigner.finish());
864 EXPECT_NO_THROW(options.finish());
866 EXPECT_EQ("test", value[0]);
867 EXPECT_EQ("value", value[1]);
868 EXPECT_EQ(1, index[0]);
869 EXPECT_EQ(2, index[1]);
872 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
874 gmx::Options options(NULL, NULL);
876 const char * const allowed[] = { "none", "test", "value" };
878 using gmx::StringOption;
879 ASSERT_NO_THROW(options.addOption(
880 StringOption("p").store(&value)
881 .enumValue(allowed).defaultEnumIndex(1)
882 .storeEnumIndex(&index)));
883 EXPECT_EQ("test", value);
886 gmx::OptionsAssigner assigner(&options);
887 EXPECT_NO_THROW(assigner.start());
888 EXPECT_NO_THROW(assigner.finish());
889 EXPECT_NO_THROW(options.finish());
891 EXPECT_EQ("test", value);
895 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndexFromVariable)
897 gmx::Options options(NULL, NULL);
898 const char * const allowed[] = { "none", "test", "value" };
900 using gmx::StringOption;
901 ASSERT_NO_THROW(options.addOption(
903 .enumValue(allowed).storeEnumIndex(&index)));
906 gmx::OptionsAssigner assigner(&options);
907 EXPECT_NO_THROW(assigner.start());
908 EXPECT_NO_THROW(assigner.finish());
909 EXPECT_NO_THROW(options.finish());