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"
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, HandlesGroups)
182 gmx::Options options(NULL, NULL);
183 gmx::IOptionsContainer &group1 = options.addGroup();
184 gmx::IOptionsContainer &group2 = options.addGroup();
188 using gmx::IntegerOption;
189 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
190 ASSERT_NO_THROW(group1.addOption(IntegerOption("q").store(&value1)));
191 ASSERT_NO_THROW(group2.addOption(IntegerOption("r").store(&value2)));
193 gmx::OptionsAssigner assigner(&options);
194 EXPECT_NO_THROW(assigner.start());
195 ASSERT_NO_THROW(assigner.startOption("p"));
196 EXPECT_NO_THROW(assigner.appendValue("5"));
197 EXPECT_NO_THROW(assigner.finishOption());
198 ASSERT_NO_THROW(assigner.startOption("q"));
199 EXPECT_NO_THROW(assigner.appendValue("4"));
200 EXPECT_NO_THROW(assigner.finishOption());
201 ASSERT_NO_THROW(assigner.startOption("r"));
202 EXPECT_NO_THROW(assigner.appendValue("6"));
203 EXPECT_NO_THROW(assigner.finishOption());
204 EXPECT_NO_THROW(assigner.finish());
205 EXPECT_NO_THROW(options.finish());
208 EXPECT_EQ(4, value1);
209 EXPECT_EQ(6, value2);
212 TEST(OptionsAssignerTest, HandlesSubSections)
214 gmx::Options options(NULL, NULL);
215 gmx::Options sub1("section1", NULL);
216 gmx::Options sub2("section2", NULL);
220 using gmx::IntegerOption;
221 ASSERT_NO_THROW(options.addSubSection(&sub1));
222 ASSERT_NO_THROW(options.addSubSection(&sub2));
223 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
224 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
225 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
227 gmx::OptionsAssigner assigner(&options);
228 EXPECT_NO_THROW(assigner.start());
229 ASSERT_NO_THROW(assigner.startSubSection("section1"));
230 ASSERT_NO_THROW(assigner.startOption("p"));
231 EXPECT_NO_THROW(assigner.appendValue("5"));
232 EXPECT_NO_THROW(assigner.finishOption());
233 EXPECT_NO_THROW(assigner.finishSubSection());
234 ASSERT_NO_THROW(assigner.startOption("p"));
235 EXPECT_NO_THROW(assigner.appendValue("4"));
236 EXPECT_NO_THROW(assigner.finishOption());
237 ASSERT_NO_THROW(assigner.startSubSection("section2"));
238 ASSERT_NO_THROW(assigner.startOption("p"));
239 EXPECT_NO_THROW(assigner.appendValue("6"));
240 EXPECT_NO_THROW(assigner.finishOption());
241 EXPECT_NO_THROW(assigner.finishSubSection());
242 EXPECT_NO_THROW(assigner.finish());
243 EXPECT_NO_THROW(options.finish());
246 EXPECT_EQ(5, value1);
247 EXPECT_EQ(6, value2);
250 TEST(OptionsAssignerTest, HandlesMultipleSources)
252 gmx::Options options(NULL, NULL);
254 using gmx::IntegerOption;
255 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
258 gmx::OptionsAssigner assigner(&options);
259 EXPECT_NO_THROW(assigner.start());
260 ASSERT_NO_THROW(assigner.startOption("p"));
261 EXPECT_NO_THROW(assigner.appendValue("1"));
262 EXPECT_NO_THROW(assigner.finishOption());
263 EXPECT_NO_THROW(assigner.finish());
266 gmx::OptionsAssigner assigner2(&options);
267 EXPECT_NO_THROW(assigner2.start());
268 ASSERT_NO_THROW(assigner2.startOption("p"));
269 EXPECT_NO_THROW(assigner2.appendValue("2"));
270 EXPECT_NO_THROW(assigner2.finishOption());
271 EXPECT_NO_THROW(assigner2.finish());
273 EXPECT_NO_THROW(options.finish());
279 /********************************************************************
280 * Tests for boolean assignment
283 TEST(OptionsAssignerBooleanTest, StoresYesValue)
285 gmx::Options options(NULL, NULL);
287 using gmx::BooleanOption;
288 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
290 gmx::OptionsAssigner assigner(&options);
291 EXPECT_NO_THROW(assigner.start());
292 ASSERT_NO_THROW(assigner.startOption("p"));
293 EXPECT_NO_THROW(assigner.appendValue("yes"));
294 EXPECT_NO_THROW(assigner.finishOption());
295 EXPECT_NO_THROW(assigner.finish());
296 EXPECT_NO_THROW(options.finish());
301 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
303 gmx::Options options(NULL, NULL);
305 using gmx::BooleanOption;
306 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
308 gmx::OptionsAssigner assigner(&options);
309 EXPECT_NO_THROW(assigner.start());
310 ASSERT_NO_THROW(assigner.startOption("p"));
311 EXPECT_NO_THROW(assigner.finishOption());
312 EXPECT_NO_THROW(assigner.finish());
313 EXPECT_NO_THROW(options.finish());
318 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
320 gmx::Options options(NULL, NULL);
322 using gmx::BooleanOption;
323 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
325 gmx::OptionsAssigner assigner(&options);
326 assigner.setAcceptBooleanNoPrefix(true);
327 EXPECT_NO_THROW(assigner.start());
328 ASSERT_NO_THROW(assigner.startOption("nop"));
329 EXPECT_NO_THROW(assigner.finishOption());
330 EXPECT_NO_THROW(assigner.finish());
331 EXPECT_NO_THROW(options.finish());
336 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
338 gmx::Options options(NULL, NULL);
340 using gmx::BooleanOption;
341 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
343 gmx::OptionsAssigner assigner(&options);
344 assigner.setAcceptBooleanNoPrefix(true);
345 EXPECT_NO_THROW(assigner.start());
346 ASSERT_NO_THROW(assigner.startOption("nop"));
347 // It's OK to fail, but if it doesn't, it should work.
350 assigner.appendValue("no");
351 assigner.finishOption();
352 EXPECT_NO_THROW(assigner.finish());
355 catch (const gmx::InvalidInputError &)
361 /********************************************************************
362 * Tests for integer assignment
364 * These tests also contain tests for general default value handling.
367 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
369 gmx::Options options(NULL, NULL);
371 using gmx::IntegerOption;
372 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
374 gmx::OptionsAssigner assigner(&options);
375 EXPECT_NO_THROW(assigner.start());
376 ASSERT_NO_THROW(assigner.startOption("p"));
377 ASSERT_NO_THROW(assigner.appendValue("3"));
378 EXPECT_NO_THROW(assigner.finishOption());
379 EXPECT_NO_THROW(assigner.finish());
380 EXPECT_NO_THROW(options.finish());
385 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
387 gmx::Options options(NULL, NULL);
389 using gmx::IntegerOption;
390 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
392 gmx::OptionsAssigner assigner(&options);
393 EXPECT_NO_THROW(assigner.start());
394 ASSERT_NO_THROW(assigner.startOption("p"));
395 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
396 EXPECT_NO_THROW(assigner.finishOption());
397 EXPECT_NO_THROW(assigner.finish());
398 EXPECT_NO_THROW(options.finish());
403 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
405 gmx::Options options(NULL, NULL);
407 using gmx::IntegerOption;
408 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
410 gmx::OptionsAssigner assigner(&options);
411 EXPECT_NO_THROW(assigner.start());
412 ASSERT_NO_THROW(assigner.startOption("p"));
413 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
414 EXPECT_NO_THROW(assigner.finishOption());
415 EXPECT_NO_THROW(assigner.finish());
416 EXPECT_NO_THROW(options.finish());
421 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
423 gmx::Options options(NULL, NULL);
425 using gmx::IntegerOption;
426 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
428 gmx::OptionsAssigner assigner(&options);
429 EXPECT_NO_THROW(assigner.start());
430 ASSERT_NO_THROW(assigner.startOption("p"));
431 std::string overflowValue(
432 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
433 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
434 EXPECT_NO_THROW(assigner.finishOption());
435 EXPECT_NO_THROW(assigner.finish());
436 EXPECT_NO_THROW(options.finish());
441 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
443 gmx::Options options(NULL, NULL);
445 using gmx::IntegerOption;
446 ASSERT_NO_THROW(options.addOption(
447 IntegerOption("p").store(&value).defaultValue(2)));
450 gmx::OptionsAssigner assigner(&options);
451 EXPECT_NO_THROW(assigner.start());
452 EXPECT_NO_THROW(assigner.finish());
453 EXPECT_NO_THROW(options.finish());
458 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
460 gmx::Options options(NULL, NULL);
462 using gmx::IntegerOption;
463 ASSERT_NO_THROW(options.addOption(
464 IntegerOption("p").store(&value).defaultValueIfSet(2)));
465 EXPECT_EQ(-1, value);
467 gmx::OptionsAssigner assigner(&options);
468 EXPECT_NO_THROW(assigner.start());
469 ASSERT_NO_THROW(assigner.startOption("p"));
470 EXPECT_NO_THROW(assigner.finishOption());
471 EXPECT_NO_THROW(assigner.finish());
472 EXPECT_NO_THROW(options.finish());
477 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
479 gmx::Options options(NULL, NULL);
481 using gmx::IntegerOption;
482 ASSERT_NO_THROW(options.addOption(
483 IntegerOption("p").store(&value).defaultValueIfSet(2)));
484 EXPECT_EQ(-1, value);
486 gmx::OptionsAssigner assigner(&options);
487 EXPECT_NO_THROW(assigner.start());
488 EXPECT_NO_THROW(assigner.finish());
489 EXPECT_NO_THROW(options.finish());
491 EXPECT_EQ(-1, value);
494 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
496 gmx::Options options(NULL, NULL);
498 using gmx::IntegerOption;
499 ASSERT_NO_THROW(options.addOption(
500 IntegerOption("p").store(&value)
501 .defaultValue(1).defaultValueIfSet(2)));
504 gmx::OptionsAssigner assigner(&options);
505 EXPECT_NO_THROW(assigner.start());
506 ASSERT_NO_THROW(assigner.startOption("p"));
507 EXPECT_NO_THROW(assigner.finishOption());
508 EXPECT_NO_THROW(assigner.finish());
509 EXPECT_NO_THROW(options.finish());
514 TEST(OptionsAssignerIntegerTest, StoresToVector)
516 gmx::Options options(NULL, NULL);
517 std::vector<int> values;
518 using gmx::IntegerOption;
519 ASSERT_NO_THROW(options.addOption(
520 IntegerOption("p").storeVector(&values).multiValue()));
522 gmx::OptionsAssigner assigner(&options);
523 EXPECT_NO_THROW(assigner.start());
524 ASSERT_NO_THROW(assigner.startOption("p"));
525 ASSERT_NO_THROW(assigner.appendValue("-2"));
526 ASSERT_NO_THROW(assigner.appendValue("1"));
527 ASSERT_NO_THROW(assigner.appendValue("4"));
528 EXPECT_NO_THROW(assigner.finishOption());
529 EXPECT_NO_THROW(assigner.finish());
530 EXPECT_NO_THROW(options.finish());
532 EXPECT_EQ(3U, values.size());
533 EXPECT_EQ(-2, values[0]);
534 EXPECT_EQ(1, values[1]);
535 EXPECT_EQ(4, values[2]);
538 TEST(OptionsAssignerIntegerTest, HandlesVectors)
540 gmx::Options options(NULL, NULL);
541 int vec[3] = {0, 0, 0};
542 using gmx::IntegerOption;
543 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
545 gmx::OptionsAssigner assigner(&options);
546 EXPECT_NO_THROW(assigner.start());
547 ASSERT_NO_THROW(assigner.startOption("p"));
548 ASSERT_NO_THROW(assigner.appendValue("-2"));
549 ASSERT_NO_THROW(assigner.appendValue("1"));
550 ASSERT_NO_THROW(assigner.appendValue("4"));
551 EXPECT_NO_THROW(assigner.finishOption());
552 EXPECT_NO_THROW(assigner.finish());
553 EXPECT_NO_THROW(options.finish());
555 EXPECT_EQ(-2, vec[0]);
556 EXPECT_EQ(1, vec[1]);
557 EXPECT_EQ(4, vec[2]);
560 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
562 gmx::Options options(NULL, NULL);
563 int vec[3] = {0, 0, 0};
564 using gmx::IntegerOption;
565 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
567 gmx::OptionsAssigner assigner(&options);
568 EXPECT_NO_THROW(assigner.start());
569 ASSERT_NO_THROW(assigner.startOption("p"));
570 ASSERT_NO_THROW(assigner.appendValue("2"));
571 EXPECT_NO_THROW(assigner.finishOption());
572 EXPECT_NO_THROW(assigner.finish());
573 EXPECT_NO_THROW(options.finish());
575 EXPECT_EQ(2, vec[0]);
576 EXPECT_EQ(2, vec[1]);
577 EXPECT_EQ(2, vec[2]);
580 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
582 gmx::Options options(NULL, NULL);
583 int vec[3] = {3, 2, 1};
584 using gmx::IntegerOption;
585 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
587 EXPECT_NO_THROW(options.finish());
589 EXPECT_EQ(3, vec[0]);
590 EXPECT_EQ(2, vec[1]);
591 EXPECT_EQ(1, vec[2]);
594 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
596 gmx::Options options(NULL, NULL);
597 int vec[3] = {3, 2, 1};
598 std::vector<int> vec2(vec, vec+3);
599 using gmx::IntegerOption;
600 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec)
601 .storeVector(&vec2).vector()));
603 gmx::OptionsAssigner assigner(&options);
604 EXPECT_NO_THROW(assigner.start());
605 ASSERT_NO_THROW(assigner.startOption("p"));
606 EXPECT_NO_THROW(assigner.appendValue("1"));
607 EXPECT_NO_THROW(assigner.appendValue("3"));
608 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
609 EXPECT_NO_THROW(assigner.finish());
610 EXPECT_NO_THROW(options.finish());
612 EXPECT_EQ(3, vec[0]);
613 EXPECT_EQ(2, vec[1]);
614 EXPECT_EQ(1, vec[2]);
615 ASSERT_EQ(3U, vec2.size());
616 EXPECT_EQ(3, vec2[0]);
617 EXPECT_EQ(2, vec2[1]);
618 EXPECT_EQ(1, vec2[2]);
622 /********************************************************************
623 * Tests for double assignment
626 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
628 gmx::Options options(NULL, NULL);
630 using gmx::DoubleOption;
631 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
633 gmx::OptionsAssigner assigner(&options);
634 EXPECT_NO_THROW(assigner.start());
635 ASSERT_NO_THROW(assigner.startOption("p"));
636 ASSERT_NO_THROW(assigner.appendValue("2.7"));
637 EXPECT_NO_THROW(assigner.finishOption());
638 EXPECT_NO_THROW(assigner.finish());
639 EXPECT_NO_THROW(options.finish());
641 EXPECT_DOUBLE_EQ(2.7, value);
644 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
646 gmx::Options options(NULL, NULL);
648 using gmx::DoubleOption;
649 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
651 gmx::OptionsAssigner assigner(&options);
652 EXPECT_NO_THROW(assigner.start());
653 ASSERT_NO_THROW(assigner.startOption("p"));
654 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
655 EXPECT_NO_THROW(assigner.finishOption());
656 EXPECT_NO_THROW(assigner.finish());
657 EXPECT_NO_THROW(options.finish());
659 EXPECT_DOUBLE_EQ(1.0, value);
663 /********************************************************************
664 * Tests for string assignment
667 TEST(OptionsAssignerStringTest, StoresSingleValue)
669 gmx::Options options(NULL, NULL);
671 using gmx::StringOption;
672 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
674 gmx::OptionsAssigner assigner(&options);
675 EXPECT_NO_THROW(assigner.start());
676 ASSERT_NO_THROW(assigner.startOption("p"));
677 ASSERT_NO_THROW(assigner.appendValue("value"));
678 EXPECT_NO_THROW(assigner.finishOption());
679 EXPECT_NO_THROW(assigner.finish());
680 EXPECT_NO_THROW(options.finish());
682 EXPECT_EQ("value", value);
685 TEST(OptionsAssignerStringTest, HandlesEnumValue)
687 gmx::Options options(NULL, NULL);
689 const char * const allowed[] = { "none", "test", "value" };
691 using gmx::StringOption;
692 ASSERT_NO_THROW(options.addOption(
693 StringOption("p").store(&value)
694 .enumValue(allowed).storeEnumIndex(&index)));
696 gmx::OptionsAssigner assigner(&options);
697 EXPECT_NO_THROW(assigner.start());
698 ASSERT_NO_THROW(assigner.startOption("p"));
699 ASSERT_NO_THROW(assigner.appendValue("test"));
700 EXPECT_NO_THROW(assigner.finishOption());
701 EXPECT_NO_THROW(assigner.finish());
702 EXPECT_NO_THROW(options.finish());
704 EXPECT_EQ("test", value);
708 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
710 gmx::Options options(NULL, NULL);
712 const char * const allowed[] = { "none", "test", "value", NULL };
714 using gmx::StringOption;
715 ASSERT_NO_THROW(options.addOption(
716 StringOption("p").store(&value)
717 .enumValueFromNullTerminatedArray(allowed)
718 .storeEnumIndex(&index)));
720 gmx::OptionsAssigner assigner(&options);
721 EXPECT_NO_THROW(assigner.start());
722 ASSERT_NO_THROW(assigner.startOption("p"));
723 ASSERT_NO_THROW(assigner.appendValue("value"));
724 EXPECT_NO_THROW(assigner.finishOption());
725 EXPECT_NO_THROW(assigner.finish());
726 EXPECT_NO_THROW(options.finish());
728 EXPECT_EQ("value", value);
732 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
734 gmx::Options options(NULL, NULL);
736 const char * const allowed[] = { "none", "test", "value" };
738 using gmx::StringOption;
739 ASSERT_NO_THROW(options.addOption(
740 StringOption("p").store(&value)
741 .enumValue(allowed).storeEnumIndex(&index)));
743 gmx::OptionsAssigner assigner(&options);
744 EXPECT_NO_THROW(assigner.start());
745 ASSERT_NO_THROW(assigner.startOption("p"));
746 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
749 TEST(OptionsAssignerStringTest, CompletesEnumValue)
751 gmx::Options options(NULL, NULL);
753 const char * const allowed[] = { "none", "test", "value" };
755 using gmx::StringOption;
756 ASSERT_NO_THROW(options.addOption(
757 StringOption("p").store(&value)
758 .enumValue(allowed).storeEnumIndex(&index)));
760 gmx::OptionsAssigner assigner(&options);
761 EXPECT_NO_THROW(assigner.start());
762 ASSERT_NO_THROW(assigner.startOption("p"));
763 ASSERT_NO_THROW(assigner.appendValue("te"));
764 EXPECT_NO_THROW(assigner.finishOption());
765 EXPECT_NO_THROW(assigner.finish());
766 EXPECT_NO_THROW(options.finish());
768 EXPECT_EQ("test", value);
772 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
774 gmx::Options options(NULL, NULL);
776 const char * const allowed[] = { "none", "test", "value" };
778 using gmx::StringOption;
779 ASSERT_NO_THROW(options.addOption(
780 StringOption("p").store(&value)
781 .enumValue(allowed).storeEnumIndex(&index)));
782 EXPECT_TRUE(value.empty());
783 EXPECT_EQ(-1, index);
785 ASSERT_NO_THROW(options.finish());
787 EXPECT_TRUE(value.empty());
788 EXPECT_EQ(-1, index);
791 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
793 gmx::Options options(NULL, NULL);
795 const char * const allowed[] = { "none", "test", "value" };
797 using gmx::StringOption;
798 ASSERT_NO_THROW(options.addOption(
799 StringOption("p").store(&value)
800 .enumValue(allowed).defaultValue("test")
801 .storeEnumIndex(&index)));
802 EXPECT_EQ("test", value);
805 gmx::OptionsAssigner assigner(&options);
806 EXPECT_NO_THROW(assigner.start());
807 EXPECT_NO_THROW(assigner.finish());
808 EXPECT_NO_THROW(options.finish());
810 EXPECT_EQ("test", value);
814 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable)
816 gmx::Options options(NULL, NULL);
817 std::string value("test");
818 const char * const allowed[] = { "none", "test", "value" };
820 using gmx::StringOption;
821 ASSERT_NO_THROW(options.addOption(
822 StringOption("p").store(&value)
823 .enumValue(allowed).storeEnumIndex(&index)));
824 EXPECT_EQ("test", value);
827 gmx::OptionsAssigner assigner(&options);
828 EXPECT_NO_THROW(assigner.start());
829 EXPECT_NO_THROW(assigner.finish());
830 EXPECT_NO_THROW(options.finish());
832 EXPECT_EQ("test", value);
836 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector)
838 gmx::Options options(NULL, NULL);
839 std::vector<std::string> value;
840 value.push_back("test");
841 value.push_back("value");
842 const char * const allowed[] = { "none", "test", "value" };
843 int index[2] = {-1, -1};
844 using gmx::StringOption;
845 ASSERT_NO_THROW(options.addOption(
846 StringOption("p").storeVector(&value).valueCount(2)
847 .enumValue(allowed).storeEnumIndex(index)));
848 EXPECT_EQ("test", value[0]);
849 EXPECT_EQ("value", value[1]);
850 EXPECT_EQ(1, index[0]);
851 EXPECT_EQ(2, index[1]);
853 gmx::OptionsAssigner assigner(&options);
854 EXPECT_NO_THROW(assigner.start());
855 EXPECT_NO_THROW(assigner.finish());
856 EXPECT_NO_THROW(options.finish());
858 EXPECT_EQ("test", value[0]);
859 EXPECT_EQ("value", value[1]);
860 EXPECT_EQ(1, index[0]);
861 EXPECT_EQ(2, index[1]);
864 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
866 gmx::Options options(NULL, NULL);
868 const char * const allowed[] = { "none", "test", "value" };
870 using gmx::StringOption;
871 ASSERT_NO_THROW(options.addOption(
872 StringOption("p").store(&value)
873 .enumValue(allowed).defaultEnumIndex(1)
874 .storeEnumIndex(&index)));
875 EXPECT_EQ("test", value);
878 gmx::OptionsAssigner assigner(&options);
879 EXPECT_NO_THROW(assigner.start());
880 EXPECT_NO_THROW(assigner.finish());
881 EXPECT_NO_THROW(options.finish());
883 EXPECT_EQ("test", value);
887 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndexFromVariable)
889 gmx::Options options(NULL, NULL);
890 const char * const allowed[] = { "none", "test", "value" };
892 using gmx::StringOption;
893 ASSERT_NO_THROW(options.addOption(
895 .enumValue(allowed).storeEnumIndex(&index)));
898 gmx::OptionsAssigner assigner(&options);
899 EXPECT_NO_THROW(assigner.start());
900 EXPECT_NO_THROW(assigner.finish());
901 EXPECT_NO_THROW(options.finish());