2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2019, 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/options/optionsection.h"
60 #include "gromacs/utility/any.h"
61 #include "gromacs/utility/exceptions.h"
62 #include "gromacs/utility/stringutil.h"
64 #include "testutils/testasserts.h"
69 /********************************************************************
70 * General assignment tests
73 TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
77 using gmx::IntegerOption;
78 ASSERT_NO_THROW(options.addOption(
79 IntegerOption("p").store(&value).required()));
81 EXPECT_THROW(options.finish(), gmx::InvalidInputError);
84 TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
88 using gmx::IntegerOption;
89 ASSERT_NO_THROW(options.addOption(
90 IntegerOption("p").store(&value).required()
93 EXPECT_NO_THROW(options.finish());
97 TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
100 std::vector<int> values;
102 using gmx::IntegerOption;
103 ASSERT_NO_THROW(options.addOption(
105 .storeVector(&values).storeIsSet(&bIsSet)
108 gmx::OptionsAssigner assigner(&options);
109 EXPECT_NO_THROW(assigner.start());
110 ASSERT_NO_THROW(assigner.startOption("p"));
111 ASSERT_NO_THROW(assigner.appendValue("1"));
112 ASSERT_NO_THROW(assigner.finishOption());
113 EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
114 EXPECT_NO_THROW(assigner.finish());
115 EXPECT_NO_THROW(options.finish());
118 ASSERT_EQ(1U, values.size());
119 EXPECT_EQ(1, values[0]);
122 TEST(OptionsAssignerTest, HandlesMultipleParameter)
124 gmx::Options options;
125 std::vector<int> values;
127 using gmx::IntegerOption;
128 ASSERT_NO_THROW(options.addOption(
130 .storeVector(&values).storeIsSet(&bIsSet)
133 gmx::OptionsAssigner assigner(&options);
134 EXPECT_NO_THROW_GMX(assigner.start());
135 ASSERT_NO_THROW_GMX(assigner.startOption("p"));
136 ASSERT_NO_THROW_GMX(assigner.appendValue("1"));
137 EXPECT_NO_THROW_GMX(assigner.finishOption());
138 ASSERT_NO_THROW_GMX(assigner.startOption("p"));
139 ASSERT_NO_THROW_GMX(assigner.appendValue("2"));
140 EXPECT_NO_THROW_GMX(assigner.finishOption());
141 EXPECT_NO_THROW_GMX(assigner.finish());
142 EXPECT_NO_THROW_GMX(options.finish());
145 ASSERT_EQ(2U, values.size());
146 EXPECT_EQ(1, values[0]);
147 EXPECT_EQ(2, values[1]);
150 TEST(OptionsAssignerTest, HandlesMissingValue)
152 gmx::Options options;
153 int value1 = 0, value2 = 0;
154 using gmx::IntegerOption;
155 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
156 ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
158 gmx::OptionsAssigner assigner(&options);
159 EXPECT_NO_THROW(assigner.start());
160 ASSERT_NO_THROW(assigner.startOption("p"));
161 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
162 ASSERT_NO_THROW(assigner.startOption("q"));
163 ASSERT_NO_THROW(assigner.appendValue("2"));
164 EXPECT_NO_THROW(assigner.finishOption());
165 EXPECT_NO_THROW(assigner.finish());
166 EXPECT_NO_THROW(options.finish());
168 EXPECT_EQ(2, value2);
171 TEST(OptionsAssignerTest, HandlesExtraValue)
173 gmx::Options options;
175 using gmx::IntegerOption;
176 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
178 gmx::OptionsAssigner assigner(&options);
179 EXPECT_NO_THROW(assigner.start());
180 ASSERT_NO_THROW(assigner.startOption("p"));
181 ASSERT_NO_THROW(assigner.appendValue("2"));
182 EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
183 EXPECT_NO_THROW(assigner.finishOption());
184 EXPECT_NO_THROW(assigner.finish());
185 EXPECT_NO_THROW(options.finish());
187 EXPECT_EQ(0, value1);
190 TEST(OptionsAssignerTest, HandlesGroups)
192 gmx::Options options;
193 gmx::IOptionsContainer &group1 = options.addGroup();
194 gmx::IOptionsContainer &group2 = options.addGroup();
198 using gmx::IntegerOption;
199 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
200 ASSERT_NO_THROW(group1.addOption(IntegerOption("q").store(&value1)));
201 ASSERT_NO_THROW(group2.addOption(IntegerOption("r").store(&value2)));
203 gmx::OptionsAssigner assigner(&options);
204 EXPECT_NO_THROW(assigner.start());
205 ASSERT_NO_THROW(assigner.startOption("p"));
206 EXPECT_NO_THROW(assigner.appendValue("5"));
207 EXPECT_NO_THROW(assigner.finishOption());
208 ASSERT_NO_THROW(assigner.startOption("q"));
209 EXPECT_NO_THROW(assigner.appendValue("4"));
210 EXPECT_NO_THROW(assigner.finishOption());
211 ASSERT_NO_THROW(assigner.startOption("r"));
212 EXPECT_NO_THROW(assigner.appendValue("6"));
213 EXPECT_NO_THROW(assigner.finishOption());
214 EXPECT_NO_THROW(assigner.finish());
215 EXPECT_NO_THROW(options.finish());
218 EXPECT_EQ(4, value1);
219 EXPECT_EQ(6, value2);
222 TEST(OptionsAssignerTest, HandlesSections)
224 using gmx::OptionSection;
225 gmx::Options options;
226 auto sub1 = options.addSection(OptionSection("section1"));
227 auto sub2 = options.addSection(OptionSection("section2"));
231 using gmx::IntegerOption;
232 ASSERT_NO_THROW_GMX(options.addOption(IntegerOption("p").store(&value)));
233 ASSERT_NO_THROW_GMX(sub1.addOption(IntegerOption("p").store(&value1)));
234 ASSERT_NO_THROW_GMX(sub2.addOption(IntegerOption("p").store(&value2)));
236 gmx::OptionsAssigner assigner(&options);
237 EXPECT_NO_THROW(assigner.start());
238 ASSERT_NO_THROW(assigner.startSection("section1"));
239 ASSERT_NO_THROW(assigner.startOption("p"));
240 EXPECT_NO_THROW(assigner.appendValue("5"));
241 EXPECT_NO_THROW(assigner.finishOption());
242 EXPECT_NO_THROW(assigner.finishSection());
243 ASSERT_NO_THROW(assigner.startOption("p"));
244 EXPECT_NO_THROW(assigner.appendValue("4"));
245 EXPECT_NO_THROW(assigner.finishOption());
246 ASSERT_NO_THROW(assigner.startSection("section2"));
247 ASSERT_NO_THROW(assigner.startOption("p"));
248 EXPECT_NO_THROW(assigner.appendValue("6"));
249 EXPECT_NO_THROW(assigner.finishOption());
250 EXPECT_NO_THROW(assigner.finishSection());
251 EXPECT_NO_THROW(assigner.finish());
252 EXPECT_NO_THROW(options.finish());
255 EXPECT_EQ(5, value1);
256 EXPECT_EQ(6, value2);
259 TEST(OptionsAssignerTest, HandlesMultipleSources)
261 gmx::Options options;
263 using gmx::IntegerOption;
264 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
267 gmx::OptionsAssigner assigner(&options);
268 EXPECT_NO_THROW(assigner.start());
269 ASSERT_NO_THROW(assigner.startOption("p"));
270 EXPECT_NO_THROW(assigner.appendValue("1"));
271 EXPECT_NO_THROW(assigner.finishOption());
272 EXPECT_NO_THROW(assigner.finish());
275 gmx::OptionsAssigner assigner2(&options);
276 EXPECT_NO_THROW(assigner2.start());
277 ASSERT_NO_THROW(assigner2.startOption("p"));
278 EXPECT_NO_THROW(assigner2.appendValue("2"));
279 EXPECT_NO_THROW(assigner2.finishOption());
280 EXPECT_NO_THROW(assigner2.finish());
282 EXPECT_NO_THROW(options.finish());
288 /********************************************************************
289 * Tests for boolean assignment
292 TEST(OptionsAssignerBooleanTest, StoresYesValue)
294 gmx::Options options;
296 using gmx::BooleanOption;
297 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
299 gmx::OptionsAssigner assigner(&options);
300 EXPECT_NO_THROW(assigner.start());
301 ASSERT_NO_THROW(assigner.startOption("p"));
302 EXPECT_NO_THROW(assigner.appendValue("yes"));
303 EXPECT_NO_THROW(assigner.finishOption());
304 EXPECT_NO_THROW(assigner.finish());
305 EXPECT_NO_THROW(options.finish());
310 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
312 gmx::Options options;
314 using gmx::BooleanOption;
315 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
317 gmx::OptionsAssigner assigner(&options);
318 EXPECT_NO_THROW(assigner.start());
319 ASSERT_NO_THROW(assigner.startOption("p"));
320 EXPECT_NO_THROW(assigner.finishOption());
321 EXPECT_NO_THROW(assigner.finish());
322 EXPECT_NO_THROW(options.finish());
327 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
329 gmx::Options options;
331 using gmx::BooleanOption;
332 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
334 gmx::OptionsAssigner assigner(&options);
335 assigner.setAcceptBooleanNoPrefix(true);
336 EXPECT_NO_THROW(assigner.start());
337 ASSERT_NO_THROW(assigner.startOption("nop"));
338 EXPECT_NO_THROW(assigner.finishOption());
339 EXPECT_NO_THROW(assigner.finish());
340 EXPECT_NO_THROW(options.finish());
345 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
347 gmx::Options options;
349 using gmx::BooleanOption;
350 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
352 gmx::OptionsAssigner assigner(&options);
353 assigner.setAcceptBooleanNoPrefix(true);
354 EXPECT_NO_THROW(assigner.start());
355 ASSERT_NO_THROW(assigner.startOption("nop"));
356 // It's OK to fail, but if it doesn't, it should work.
359 assigner.appendValue("no");
360 assigner.finishOption();
361 EXPECT_NO_THROW(assigner.finish());
364 catch (const gmx::InvalidInputError &)
370 /********************************************************************
371 * Tests for integer assignment
373 * These tests also contain tests for general default value handling.
376 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
378 gmx::Options options;
380 using gmx::IntegerOption;
381 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
383 gmx::OptionsAssigner assigner(&options);
384 EXPECT_NO_THROW(assigner.start());
385 ASSERT_NO_THROW(assigner.startOption("p"));
386 ASSERT_NO_THROW(assigner.appendValue("3"));
387 EXPECT_NO_THROW(assigner.finishOption());
388 EXPECT_NO_THROW(assigner.finish());
389 EXPECT_NO_THROW(options.finish());
394 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
396 gmx::Options options;
398 using gmx::IntegerOption;
399 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
401 gmx::OptionsAssigner assigner(&options);
402 EXPECT_NO_THROW(assigner.start());
403 ASSERT_NO_THROW(assigner.startOption("p"));
404 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
405 EXPECT_NO_THROW(assigner.finishOption());
406 EXPECT_NO_THROW(assigner.finish());
407 EXPECT_NO_THROW(options.finish());
412 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
414 gmx::Options options;
416 using gmx::IntegerOption;
417 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
419 gmx::OptionsAssigner assigner(&options);
420 EXPECT_NO_THROW(assigner.start());
421 ASSERT_NO_THROW(assigner.startOption("p"));
422 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
423 EXPECT_NO_THROW(assigner.finishOption());
424 EXPECT_NO_THROW(assigner.finish());
425 EXPECT_NO_THROW(options.finish());
430 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
432 gmx::Options options;
434 using gmx::IntegerOption;
435 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
437 gmx::OptionsAssigner assigner(&options);
438 EXPECT_NO_THROW(assigner.start());
439 ASSERT_NO_THROW(assigner.startOption("p"));
440 std::string overflowValue(
441 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
442 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
443 EXPECT_NO_THROW(assigner.finishOption());
444 EXPECT_NO_THROW(assigner.finish());
445 EXPECT_NO_THROW(options.finish());
450 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
452 gmx::Options options;
454 using gmx::IntegerOption;
455 ASSERT_NO_THROW(options.addOption(
456 IntegerOption("p").store(&value).defaultValue(2)));
459 gmx::OptionsAssigner assigner(&options);
460 EXPECT_NO_THROW(assigner.start());
461 EXPECT_NO_THROW(assigner.finish());
462 EXPECT_NO_THROW(options.finish());
467 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
469 gmx::Options options;
471 using gmx::IntegerOption;
472 ASSERT_NO_THROW(options.addOption(
473 IntegerOption("p").store(&value).defaultValueIfSet(2)));
474 EXPECT_EQ(-1, value);
476 gmx::OptionsAssigner assigner(&options);
477 EXPECT_NO_THROW(assigner.start());
478 ASSERT_NO_THROW(assigner.startOption("p"));
479 EXPECT_NO_THROW(assigner.finishOption());
480 EXPECT_NO_THROW(assigner.finish());
481 EXPECT_NO_THROW(options.finish());
486 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
488 gmx::Options options;
490 using gmx::IntegerOption;
491 ASSERT_NO_THROW(options.addOption(
492 IntegerOption("p").store(&value).defaultValueIfSet(2)));
493 EXPECT_EQ(-1, value);
495 gmx::OptionsAssigner assigner(&options);
496 EXPECT_NO_THROW(assigner.start());
497 EXPECT_NO_THROW(assigner.finish());
498 EXPECT_NO_THROW(options.finish());
500 EXPECT_EQ(-1, value);
503 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
505 gmx::Options options;
507 using gmx::IntegerOption;
508 ASSERT_NO_THROW(options.addOption(
509 IntegerOption("p").store(&value)
510 .defaultValue(1).defaultValueIfSet(2)));
513 gmx::OptionsAssigner assigner(&options);
514 EXPECT_NO_THROW(assigner.start());
515 ASSERT_NO_THROW(assigner.startOption("p"));
516 EXPECT_NO_THROW(assigner.finishOption());
517 EXPECT_NO_THROW(assigner.finish());
518 EXPECT_NO_THROW(options.finish());
523 TEST(OptionsAssignerIntegerTest, StoresToVector)
525 gmx::Options options;
526 std::vector<int> values;
527 using gmx::IntegerOption;
528 ASSERT_NO_THROW(options.addOption(
529 IntegerOption("p").storeVector(&values).multiValue()));
531 gmx::OptionsAssigner assigner(&options);
532 EXPECT_NO_THROW(assigner.start());
533 ASSERT_NO_THROW(assigner.startOption("p"));
534 ASSERT_NO_THROW(assigner.appendValue("-2"));
535 ASSERT_NO_THROW(assigner.appendValue("1"));
536 ASSERT_NO_THROW(assigner.appendValue("4"));
537 EXPECT_NO_THROW(assigner.finishOption());
538 EXPECT_NO_THROW(assigner.finish());
539 EXPECT_NO_THROW(options.finish());
541 EXPECT_EQ(3U, values.size());
542 EXPECT_EQ(-2, values[0]);
543 EXPECT_EQ(1, values[1]);
544 EXPECT_EQ(4, values[2]);
547 TEST(OptionsAssignerIntegerTest, HandlesVectors)
549 gmx::Options options;
550 int vec[3] = {0, 0, 0};
551 using gmx::IntegerOption;
552 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
554 gmx::OptionsAssigner assigner(&options);
555 EXPECT_NO_THROW(assigner.start());
556 ASSERT_NO_THROW(assigner.startOption("p"));
557 ASSERT_NO_THROW(assigner.appendValue("-2"));
558 ASSERT_NO_THROW(assigner.appendValue("1"));
559 ASSERT_NO_THROW(assigner.appendValue("4"));
560 EXPECT_NO_THROW(assigner.finishOption());
561 EXPECT_NO_THROW(assigner.finish());
562 EXPECT_NO_THROW(options.finish());
564 EXPECT_EQ(-2, vec[0]);
565 EXPECT_EQ(1, vec[1]);
566 EXPECT_EQ(4, vec[2]);
569 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
571 gmx::Options options;
572 int vec[3] = {0, 0, 0};
573 using gmx::IntegerOption;
574 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
576 gmx::OptionsAssigner assigner(&options);
577 EXPECT_NO_THROW(assigner.start());
578 ASSERT_NO_THROW(assigner.startOption("p"));
579 ASSERT_NO_THROW(assigner.appendValue("2"));
580 EXPECT_NO_THROW(assigner.finishOption());
581 EXPECT_NO_THROW(assigner.finish());
582 EXPECT_NO_THROW(options.finish());
584 EXPECT_EQ(2, vec[0]);
585 EXPECT_EQ(2, vec[1]);
586 EXPECT_EQ(2, vec[2]);
589 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
591 gmx::Options options;
592 int vec[3] = {3, 2, 1};
593 using gmx::IntegerOption;
594 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
596 EXPECT_NO_THROW(options.finish());
598 EXPECT_EQ(3, vec[0]);
599 EXPECT_EQ(2, vec[1]);
600 EXPECT_EQ(1, vec[2]);
603 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
605 gmx::Options options;
606 int vec[3] = {3, 2, 1};
607 using gmx::IntegerOption;
608 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
610 gmx::OptionsAssigner assigner(&options);
611 EXPECT_NO_THROW(assigner.start());
612 ASSERT_NO_THROW(assigner.startOption("p"));
613 EXPECT_NO_THROW(assigner.appendValue("1"));
614 EXPECT_NO_THROW(assigner.appendValue("3"));
615 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
616 EXPECT_NO_THROW(assigner.finish());
617 EXPECT_NO_THROW(options.finish());
619 EXPECT_EQ(3, vec[0]);
620 EXPECT_EQ(2, vec[1]);
621 EXPECT_EQ(1, vec[2]);
625 /********************************************************************
626 * Tests for double assignment
629 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
631 gmx::Options options;
633 using gmx::DoubleOption;
634 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
636 gmx::OptionsAssigner assigner(&options);
637 EXPECT_NO_THROW(assigner.start());
638 ASSERT_NO_THROW(assigner.startOption("p"));
639 ASSERT_NO_THROW(assigner.appendValue("2.7"));
640 EXPECT_NO_THROW(assigner.finishOption());
641 EXPECT_NO_THROW(assigner.finish());
642 EXPECT_NO_THROW(options.finish());
644 EXPECT_DOUBLE_EQ(2.7, value);
647 TEST(OptionsAssignerDoubleTest, StoresValueFromFloat)
649 gmx::Options options;
651 using gmx::DoubleOption;
652 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
654 gmx::OptionsAssigner assigner(&options);
655 EXPECT_NO_THROW(assigner.start());
656 ASSERT_NO_THROW(assigner.startOption("p"));
657 ASSERT_NO_THROW(assigner.appendValue(gmx::Any::create<float>(2.7)));
658 EXPECT_NO_THROW(assigner.finishOption());
659 EXPECT_NO_THROW(assigner.finish());
660 EXPECT_NO_THROW(options.finish());
662 EXPECT_FLOAT_EQ(2.7, value);
665 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
667 gmx::Options options;
669 using gmx::DoubleOption;
670 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
672 gmx::OptionsAssigner assigner(&options);
673 EXPECT_NO_THROW(assigner.start());
674 ASSERT_NO_THROW(assigner.startOption("p"));
675 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
676 EXPECT_NO_THROW(assigner.finishOption());
677 EXPECT_NO_THROW(assigner.finish());
678 EXPECT_NO_THROW(options.finish());
680 EXPECT_DOUBLE_EQ(1.0, value);
683 TEST(OptionsAssignerDoubleTest, HandlesPreSetScaleValue)
685 gmx::Options options;
687 using gmx::DoubleOption;
688 gmx::DoubleOptionInfo *info = options.addOption(DoubleOption("p").store(&value));
689 EXPECT_NO_THROW(info->setScaleFactor(10));
691 gmx::OptionsAssigner assigner(&options);
692 EXPECT_NO_THROW(assigner.start());
693 ASSERT_NO_THROW(assigner.startOption("p"));
694 ASSERT_NO_THROW(assigner.appendValue("2.7"));
695 EXPECT_NO_THROW(assigner.finishOption());
696 EXPECT_NO_THROW(assigner.finish());
697 EXPECT_NO_THROW(options.finish());
699 EXPECT_DOUBLE_EQ(27, value);
702 TEST(OptionsAssignerDoubleTest, HandlesPostSetScaleValue)
704 gmx::Options options;
706 using gmx::DoubleOption;
707 gmx::DoubleOptionInfo *info = options.addOption(DoubleOption("p").store(&value));
709 gmx::OptionsAssigner assigner(&options);
710 EXPECT_NO_THROW(assigner.start());
711 ASSERT_NO_THROW(assigner.startOption("p"));
712 ASSERT_NO_THROW(assigner.appendValue("2.7"));
713 EXPECT_NO_THROW(assigner.finishOption());
714 EXPECT_NO_THROW(assigner.finish());
715 EXPECT_NO_THROW(info->setScaleFactor(10));
716 EXPECT_NO_THROW(options.finish());
718 EXPECT_DOUBLE_EQ(27, value);
722 /********************************************************************
723 * Tests for string assignment
726 //! Set of allowed values for enum option tests.
727 const char *const c_allowed[] = { "none", "test", "value" };
729 TEST(OptionsAssignerStringTest, StoresSingleValue)
731 gmx::Options options;
733 using gmx::StringOption;
734 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
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);
747 TEST(OptionsAssignerStringTest, HandlesEnumValue)
749 gmx::Options options;
751 using gmx::StringOption;
752 ASSERT_NO_THROW(options.addOption(
753 StringOption("p").store(&value)
754 .enumValue(c_allowed)));
756 gmx::OptionsAssigner assigner(&options);
757 EXPECT_NO_THROW(assigner.start());
758 ASSERT_NO_THROW(assigner.startOption("p"));
759 ASSERT_NO_THROW(assigner.appendValue("test"));
760 EXPECT_NO_THROW(assigner.finishOption());
761 EXPECT_NO_THROW(assigner.finish());
762 EXPECT_NO_THROW(options.finish());
764 EXPECT_EQ("test", value);
767 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
769 gmx::Options options;
771 const char * const allowed[] = { "none", "test", "value", nullptr };
772 using gmx::StringOption;
773 ASSERT_NO_THROW(options.addOption(
774 StringOption("p").store(&value)
775 .enumValueFromNullTerminatedArray(allowed)));
777 gmx::OptionsAssigner assigner(&options);
778 EXPECT_NO_THROW(assigner.start());
779 ASSERT_NO_THROW(assigner.startOption("p"));
780 ASSERT_NO_THROW(assigner.appendValue("value"));
781 EXPECT_NO_THROW(assigner.finishOption());
782 EXPECT_NO_THROW(assigner.finish());
783 EXPECT_NO_THROW(options.finish());
785 EXPECT_EQ("value", value);
788 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
790 gmx::Options options;
792 using gmx::StringOption;
793 ASSERT_NO_THROW(options.addOption(
794 StringOption("p").store(&value)
795 .enumValue(c_allowed)));
797 gmx::OptionsAssigner assigner(&options);
798 EXPECT_NO_THROW(assigner.start());
799 ASSERT_NO_THROW(assigner.startOption("p"));
800 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
803 TEST(OptionsAssignerStringTest, CompletesEnumValue)
805 gmx::Options options;
807 using gmx::StringOption;
808 ASSERT_NO_THROW(options.addOption(
809 StringOption("p").store(&value)
810 .enumValue(c_allowed)));
812 gmx::OptionsAssigner assigner(&options);
813 EXPECT_NO_THROW(assigner.start());
814 ASSERT_NO_THROW(assigner.startOption("p"));
815 ASSERT_NO_THROW(assigner.appendValue("te"));
816 EXPECT_NO_THROW(assigner.finishOption());
817 EXPECT_NO_THROW(assigner.finish());
818 EXPECT_NO_THROW(options.finish());
820 EXPECT_EQ("test", value);
823 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
825 gmx::Options options;
827 using gmx::StringOption;
828 ASSERT_NO_THROW(options.addOption(
829 StringOption("p").store(&value)
830 .enumValue(c_allowed)));
831 EXPECT_TRUE(value.empty());
833 ASSERT_NO_THROW(options.finish());
835 EXPECT_TRUE(value.empty());
838 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
840 gmx::Options options;
842 using gmx::StringOption;
843 ASSERT_NO_THROW(options.addOption(
844 StringOption("p").store(&value)
845 .enumValue(c_allowed).defaultValue("test")));
846 EXPECT_EQ("test", value);
848 gmx::OptionsAssigner assigner(&options);
849 EXPECT_NO_THROW(assigner.start());
850 EXPECT_NO_THROW(assigner.finish());
851 EXPECT_NO_THROW(options.finish());
853 EXPECT_EQ("test", value);
856 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable)
858 gmx::Options options;
859 std::string value("test");
860 using gmx::StringOption;
861 ASSERT_NO_THROW(options.addOption(
862 StringOption("p").store(&value)
863 .enumValue(c_allowed)));
864 EXPECT_EQ("test", value);
866 gmx::OptionsAssigner assigner(&options);
867 EXPECT_NO_THROW(assigner.start());
868 EXPECT_NO_THROW(assigner.finish());
869 EXPECT_NO_THROW(options.finish());
871 EXPECT_EQ("test", value);
874 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector)
876 gmx::Options options;
877 std::vector<std::string> value;
878 value.emplace_back("test");
879 value.emplace_back("value");
880 using gmx::StringOption;
881 ASSERT_NO_THROW(options.addOption(
882 StringOption("p").storeVector(&value).valueCount(2)
883 .enumValue(c_allowed)));
884 ASSERT_EQ(2U, value.size());
885 EXPECT_EQ("test", value[0]);
886 EXPECT_EQ("value", value[1]);
888 gmx::OptionsAssigner assigner(&options);
889 EXPECT_NO_THROW(assigner.start());
890 EXPECT_NO_THROW(assigner.finish());
891 EXPECT_NO_THROW(options.finish());
893 ASSERT_EQ(2U, value.size());
894 EXPECT_EQ("test", value[0]);
895 EXPECT_EQ("value", value[1]);
899 /********************************************************************
900 * Tests for enum options
903 //! Enum type for EnumOption tests.
912 TEST(OptionsAssignerEnumTest, StoresSingleValue)
914 gmx::Options options;
915 TestEnum value = etestNone;
916 using gmx::EnumOption;
917 ASSERT_NO_THROW(options.addOption(
918 EnumOption<TestEnum>("p").store(&value)
919 .enumValue(c_allowed)));
920 EXPECT_EQ(etestNone, value);
922 gmx::OptionsAssigner assigner(&options);
923 EXPECT_NO_THROW(assigner.start());
924 ASSERT_NO_THROW(assigner.startOption("p"));
925 ASSERT_NO_THROW(assigner.appendValue("test"));
926 EXPECT_NO_THROW(assigner.finishOption());
927 EXPECT_NO_THROW(assigner.finish());
928 EXPECT_NO_THROW(options.finish());
930 EXPECT_EQ(etestTest, value);
933 TEST(OptionsAssignerEnumTest, StoresVectorValues)
935 gmx::Options options;
936 std::vector<TestEnum> values;
937 using gmx::EnumOption;
938 ASSERT_NO_THROW(options.addOption(
939 EnumOption<TestEnum>("p").storeVector(&values)
940 .multiValue().enumValue(c_allowed)));
941 EXPECT_TRUE(values.empty());
943 gmx::OptionsAssigner assigner(&options);
944 EXPECT_NO_THROW(assigner.start());
945 ASSERT_NO_THROW(assigner.startOption("p"));
946 ASSERT_NO_THROW(assigner.appendValue("test"));
947 ASSERT_NO_THROW(assigner.appendValue("value"));
948 EXPECT_NO_THROW(assigner.finishOption());
949 EXPECT_NO_THROW(assigner.finish());
950 EXPECT_NO_THROW(options.finish());
952 ASSERT_EQ(2U, values.size());
953 EXPECT_EQ(etestTest, values[0]);
954 EXPECT_EQ(etestValue, values[1]);
957 TEST(OptionsAssignerEnumTest, HandlesInitialValueOutOfRange)
959 gmx::Options options;
960 TestEnum value = etestNR;
961 using gmx::EnumOption;
962 ASSERT_NO_THROW(options.addOption(
963 EnumOption<TestEnum>("p").store(&value)
964 .enumValue(c_allowed)));
965 EXPECT_EQ(etestNR, value);
967 gmx::OptionsAssigner assigner(&options);
968 EXPECT_NO_THROW(assigner.start());
969 EXPECT_NO_THROW(assigner.finish());
970 EXPECT_NO_THROW(options.finish());
972 EXPECT_EQ(etestNR, value);
975 TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValue)
977 gmx::Options options;
978 TestEnum value = etestNone;
979 using gmx::EnumOption;
980 ASSERT_NO_THROW(options.addOption(
981 EnumOption<TestEnum>("p").store(&value)
982 .enumValue(c_allowed).defaultValue(etestTest)));
983 EXPECT_EQ(etestTest, value);
985 gmx::OptionsAssigner assigner(&options);
986 EXPECT_NO_THROW(assigner.start());
987 EXPECT_NO_THROW(assigner.finish());
988 EXPECT_NO_THROW(options.finish());
990 EXPECT_EQ(etestTest, value);
993 TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVariable)
995 gmx::Options options;
996 TestEnum value = etestTest;
997 using gmx::EnumOption;
998 ASSERT_NO_THROW(options.addOption(
999 EnumOption<TestEnum>("p").store(&value)
1000 .enumValue(c_allowed)));
1001 EXPECT_EQ(etestTest, value);
1003 gmx::OptionsAssigner assigner(&options);
1004 EXPECT_NO_THROW(assigner.start());
1005 EXPECT_NO_THROW(assigner.finish());
1006 EXPECT_NO_THROW(options.finish());
1008 EXPECT_EQ(etestTest, value);
1011 TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVector)
1013 gmx::Options options;
1014 std::vector<TestEnum> value;
1015 value.push_back(etestNone);
1016 value.push_back(etestTest);
1017 using gmx::EnumOption;
1018 ASSERT_NO_THROW(options.addOption(
1019 EnumOption<TestEnum>("p").storeVector(&value).valueCount(2)
1020 .enumValue(c_allowed)));
1021 ASSERT_EQ(2U, value.size());
1022 EXPECT_EQ(etestNone, value[0]);
1023 EXPECT_EQ(etestTest, value[1]);
1025 gmx::OptionsAssigner assigner(&options);
1026 EXPECT_NO_THROW(assigner.start());
1027 EXPECT_NO_THROW(assigner.finish());
1028 EXPECT_NO_THROW(options.finish());
1030 ASSERT_EQ(2U, value.size());
1031 EXPECT_EQ(etestNone, value[0]);
1032 EXPECT_EQ(etestTest, value[1]);