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
51 #include <gtest/gtest.h>
53 #include "gromacs/options/basicoptions.h"
54 #include "gromacs/options/options.h"
55 #include "gromacs/options/optionsassigner.h"
56 #include "gromacs/utility/exceptions.h"
57 #include "gromacs/utility/stringutil.h"
62 /********************************************************************
63 * General assignment tests
66 TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
68 gmx::Options options(NULL, NULL);
70 using gmx::IntegerOption;
71 ASSERT_NO_THROW(options.addOption(
72 IntegerOption("p").store(&value).required()));
74 EXPECT_THROW(options.finish(), gmx::InvalidInputError);
77 TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
79 gmx::Options options(NULL, NULL);
81 using gmx::IntegerOption;
82 ASSERT_NO_THROW(options.addOption(
83 IntegerOption("p").store(&value).required()
86 EXPECT_NO_THROW(options.finish());
90 TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
92 gmx::Options options(NULL, NULL);
93 std::vector<int> values;
94 using gmx::IntegerOption;
95 ASSERT_NO_THROW(options.addOption(
96 IntegerOption("p").storeVector(&values).multiValue()));
98 gmx::OptionsAssigner assigner(&options);
99 EXPECT_NO_THROW(assigner.start());
100 ASSERT_NO_THROW(assigner.startOption("p"));
101 ASSERT_NO_THROW(assigner.appendValue("1"));
102 ASSERT_NO_THROW(assigner.finishOption());
103 EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
104 EXPECT_NO_THROW(assigner.finish());
105 EXPECT_NO_THROW(options.finish());
107 EXPECT_TRUE(options.isSet("p"));
108 ASSERT_EQ(1U, values.size());
109 EXPECT_EQ(1, values[0]);
112 TEST(OptionsAssignerTest, HandlesMultipleParameter)
114 gmx::Options options(NULL, NULL);
115 std::vector<int> values;
116 using gmx::IntegerOption;
117 ASSERT_NO_THROW(options.addOption(
118 IntegerOption("p").storeVector(&values).allowMultiple()));
120 gmx::OptionsAssigner assigner(&options);
121 EXPECT_NO_THROW(assigner.start());
122 ASSERT_NO_THROW(assigner.startOption("p"));
123 ASSERT_NO_THROW(assigner.appendValue("1"));
124 EXPECT_NO_THROW(assigner.finishOption());
125 ASSERT_NO_THROW(assigner.startOption("p"));
126 ASSERT_NO_THROW(assigner.appendValue("2"));
127 EXPECT_NO_THROW(assigner.finishOption());
128 EXPECT_NO_THROW(assigner.finish());
129 EXPECT_NO_THROW(options.finish());
131 EXPECT_TRUE(options.isSet("p"));
132 ASSERT_EQ(2U, values.size());
133 EXPECT_EQ(1, values[0]);
134 EXPECT_EQ(2, values[1]);
137 TEST(OptionsAssignerTest, HandlesMissingValue)
139 gmx::Options options(NULL, NULL);
140 int value1 = 0, value2 = 0;
141 using gmx::IntegerOption;
142 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
143 ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
145 gmx::OptionsAssigner assigner(&options);
146 EXPECT_NO_THROW(assigner.start());
147 ASSERT_NO_THROW(assigner.startOption("p"));
148 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
149 ASSERT_NO_THROW(assigner.startOption("q"));
150 ASSERT_NO_THROW(assigner.appendValue("2"));
151 EXPECT_NO_THROW(assigner.finishOption());
152 EXPECT_NO_THROW(assigner.finish());
153 EXPECT_NO_THROW(options.finish());
155 EXPECT_EQ(2, value2);
158 TEST(OptionsAssignerTest, HandlesExtraValue)
160 gmx::Options options(NULL, NULL);
162 using gmx::IntegerOption;
163 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
165 gmx::OptionsAssigner assigner(&options);
166 EXPECT_NO_THROW(assigner.start());
167 ASSERT_NO_THROW(assigner.startOption("p"));
168 ASSERT_NO_THROW(assigner.appendValue("2"));
169 EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
170 EXPECT_NO_THROW(assigner.finishOption());
171 EXPECT_NO_THROW(assigner.finish());
172 EXPECT_NO_THROW(options.finish());
174 EXPECT_EQ(0, value1);
177 TEST(OptionsAssignerTest, HandlesSubSections)
179 gmx::Options options(NULL, NULL);
180 gmx::Options sub1("section1", NULL);
181 gmx::Options sub2("section2", NULL);
185 using gmx::IntegerOption;
186 ASSERT_NO_THROW(options.addSubSection(&sub1));
187 ASSERT_NO_THROW(options.addSubSection(&sub2));
188 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
189 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
190 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
192 gmx::OptionsAssigner assigner(&options);
193 EXPECT_NO_THROW(assigner.start());
194 ASSERT_NO_THROW(assigner.startSubSection("section1"));
195 ASSERT_NO_THROW(assigner.startOption("p"));
196 EXPECT_NO_THROW(assigner.appendValue("5"));
197 EXPECT_NO_THROW(assigner.finishOption());
198 EXPECT_NO_THROW(assigner.finishSubSection());
199 ASSERT_NO_THROW(assigner.startOption("p"));
200 EXPECT_NO_THROW(assigner.appendValue("4"));
201 EXPECT_NO_THROW(assigner.finishOption());
202 ASSERT_NO_THROW(assigner.startSubSection("section2"));
203 ASSERT_NO_THROW(assigner.startOption("p"));
204 EXPECT_NO_THROW(assigner.appendValue("6"));
205 EXPECT_NO_THROW(assigner.finishOption());
206 EXPECT_NO_THROW(assigner.finishSubSection());
207 EXPECT_NO_THROW(assigner.finish());
208 EXPECT_NO_THROW(options.finish());
211 EXPECT_EQ(5, value1);
212 EXPECT_EQ(6, value2);
215 TEST(OptionsAssignerTest, HandlesNoStrictSubSections)
217 gmx::Options options(NULL, NULL);
218 gmx::Options sub1("section1", NULL);
219 gmx::Options sub2("section2", NULL);
225 using gmx::IntegerOption;
226 ASSERT_NO_THROW(options.addSubSection(&sub1));
227 ASSERT_NO_THROW(options.addSubSection(&sub2));
228 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
229 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
230 ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
231 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
232 ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
234 gmx::OptionsAssigner assigner(&options);
235 assigner.setNoStrictSectioning(true);
236 EXPECT_NO_THROW(assigner.start());
237 ASSERT_NO_THROW(assigner.startOption("q"));
238 EXPECT_NO_THROW(assigner.appendValue("6"));
239 EXPECT_NO_THROW(assigner.finishOption());
240 ASSERT_NO_THROW(assigner.startOption("p"));
241 EXPECT_NO_THROW(assigner.appendValue("7"));
242 EXPECT_NO_THROW(assigner.finishOption());
243 ASSERT_NO_THROW(assigner.startOption("r"));
244 EXPECT_NO_THROW(assigner.appendValue("8"));
245 EXPECT_NO_THROW(assigner.finishOption());
246 ASSERT_NO_THROW(assigner.startOption("p"));
247 EXPECT_NO_THROW(assigner.appendValue("9"));
248 EXPECT_NO_THROW(assigner.finishOption());
249 EXPECT_NO_THROW(assigner.finishSubSection());
250 ASSERT_NO_THROW(assigner.startOption("p"));
251 EXPECT_NO_THROW(assigner.appendValue("10"));
252 EXPECT_NO_THROW(assigner.finishOption());
253 EXPECT_NO_THROW(assigner.finish());
254 EXPECT_NO_THROW(options.finish());
256 EXPECT_EQ(6, qvalue);
257 EXPECT_EQ(7, pvalue1);
258 EXPECT_EQ(8, rvalue);
259 EXPECT_EQ(9, pvalue2);
260 EXPECT_EQ(10, pvalue);
263 TEST(OptionsAssignerTest, HandlesMultipleSources)
265 gmx::Options options(NULL, NULL);
267 using gmx::IntegerOption;
268 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
271 gmx::OptionsAssigner assigner(&options);
272 EXPECT_NO_THROW(assigner.start());
273 ASSERT_NO_THROW(assigner.startOption("p"));
274 EXPECT_NO_THROW(assigner.appendValue("1"));
275 EXPECT_NO_THROW(assigner.finishOption());
276 EXPECT_NO_THROW(assigner.finish());
279 gmx::OptionsAssigner assigner2(&options);
280 EXPECT_NO_THROW(assigner2.start());
281 ASSERT_NO_THROW(assigner2.startOption("p"));
282 EXPECT_NO_THROW(assigner2.appendValue("2"));
283 EXPECT_NO_THROW(assigner2.finishOption());
284 EXPECT_NO_THROW(assigner2.finish());
286 EXPECT_NO_THROW(options.finish());
292 /********************************************************************
293 * Tests for boolean assignment
296 TEST(OptionsAssignerBooleanTest, StoresYesValue)
298 gmx::Options options(NULL, NULL);
300 using gmx::BooleanOption;
301 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
303 gmx::OptionsAssigner assigner(&options);
304 EXPECT_NO_THROW(assigner.start());
305 ASSERT_NO_THROW(assigner.startOption("p"));
306 EXPECT_NO_THROW(assigner.appendValue("yes"));
307 EXPECT_NO_THROW(assigner.finishOption());
308 EXPECT_NO_THROW(assigner.finish());
309 EXPECT_NO_THROW(options.finish());
314 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
316 gmx::Options options(NULL, NULL);
318 using gmx::BooleanOption;
319 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
321 gmx::OptionsAssigner assigner(&options);
322 EXPECT_NO_THROW(assigner.start());
323 ASSERT_NO_THROW(assigner.startOption("p"));
324 EXPECT_NO_THROW(assigner.finishOption());
325 EXPECT_NO_THROW(assigner.finish());
326 EXPECT_NO_THROW(options.finish());
331 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
333 gmx::Options options(NULL, NULL);
335 using gmx::BooleanOption;
336 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
338 gmx::OptionsAssigner assigner(&options);
339 assigner.setAcceptBooleanNoPrefix(true);
340 EXPECT_NO_THROW(assigner.start());
341 ASSERT_NO_THROW(assigner.startOption("nop"));
342 EXPECT_NO_THROW(assigner.finishOption());
343 EXPECT_NO_THROW(assigner.finish());
344 EXPECT_NO_THROW(options.finish());
349 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
351 gmx::Options options(NULL, NULL);
353 using gmx::BooleanOption;
354 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
356 gmx::OptionsAssigner assigner(&options);
357 assigner.setAcceptBooleanNoPrefix(true);
358 EXPECT_NO_THROW(assigner.start());
359 ASSERT_NO_THROW(assigner.startOption("nop"));
360 // It's OK to fail, but if it doesn't, it should work.
363 assigner.appendValue("no");
364 assigner.finishOption();
365 EXPECT_NO_THROW(assigner.finish());
368 catch (const gmx::InvalidInputError &)
374 /********************************************************************
375 * Tests for integer assignment
377 * These tests also contain tests for general default value handling.
380 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
382 gmx::Options options(NULL, NULL);
384 using gmx::IntegerOption;
385 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
387 gmx::OptionsAssigner assigner(&options);
388 EXPECT_NO_THROW(assigner.start());
389 ASSERT_NO_THROW(assigner.startOption("p"));
390 ASSERT_NO_THROW(assigner.appendValue("3"));
391 EXPECT_NO_THROW(assigner.finishOption());
392 EXPECT_NO_THROW(assigner.finish());
393 EXPECT_NO_THROW(options.finish());
398 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
400 gmx::Options options(NULL, NULL);
402 using gmx::IntegerOption;
403 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
405 gmx::OptionsAssigner assigner(&options);
406 EXPECT_NO_THROW(assigner.start());
407 ASSERT_NO_THROW(assigner.startOption("p"));
408 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
409 EXPECT_NO_THROW(assigner.finishOption());
410 EXPECT_NO_THROW(assigner.finish());
411 EXPECT_NO_THROW(options.finish());
416 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
418 gmx::Options options(NULL, NULL);
420 using gmx::IntegerOption;
421 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
423 gmx::OptionsAssigner assigner(&options);
424 EXPECT_NO_THROW(assigner.start());
425 ASSERT_NO_THROW(assigner.startOption("p"));
426 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
427 EXPECT_NO_THROW(assigner.finishOption());
428 EXPECT_NO_THROW(assigner.finish());
429 EXPECT_NO_THROW(options.finish());
434 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
436 gmx::Options options(NULL, NULL);
438 using gmx::IntegerOption;
439 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
441 gmx::OptionsAssigner assigner(&options);
442 EXPECT_NO_THROW(assigner.start());
443 ASSERT_NO_THROW(assigner.startOption("p"));
444 std::string overflowValue(
445 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
446 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
447 EXPECT_NO_THROW(assigner.finishOption());
448 EXPECT_NO_THROW(assigner.finish());
449 EXPECT_NO_THROW(options.finish());
454 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
456 gmx::Options options(NULL, NULL);
458 using gmx::IntegerOption;
459 ASSERT_NO_THROW(options.addOption(
460 IntegerOption("p").store(&value).defaultValue(2)));
463 gmx::OptionsAssigner assigner(&options);
464 EXPECT_NO_THROW(assigner.start());
465 EXPECT_NO_THROW(assigner.finish());
466 EXPECT_NO_THROW(options.finish());
471 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
473 gmx::Options options(NULL, NULL);
475 using gmx::IntegerOption;
476 ASSERT_NO_THROW(options.addOption(
477 IntegerOption("p").store(&value).defaultValueIfSet(2)));
478 EXPECT_EQ(-1, value);
480 gmx::OptionsAssigner assigner(&options);
481 EXPECT_NO_THROW(assigner.start());
482 ASSERT_NO_THROW(assigner.startOption("p"));
483 EXPECT_NO_THROW(assigner.finishOption());
484 EXPECT_NO_THROW(assigner.finish());
485 EXPECT_NO_THROW(options.finish());
490 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
492 gmx::Options options(NULL, NULL);
494 using gmx::IntegerOption;
495 ASSERT_NO_THROW(options.addOption(
496 IntegerOption("p").store(&value).defaultValueIfSet(2)));
497 EXPECT_EQ(-1, value);
499 gmx::OptionsAssigner assigner(&options);
500 EXPECT_NO_THROW(assigner.start());
501 EXPECT_NO_THROW(assigner.finish());
502 EXPECT_NO_THROW(options.finish());
504 EXPECT_EQ(-1, value);
507 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
509 gmx::Options options(NULL, NULL);
511 using gmx::IntegerOption;
512 ASSERT_NO_THROW(options.addOption(
513 IntegerOption("p").store(&value)
514 .defaultValue(1).defaultValueIfSet(2)));
517 gmx::OptionsAssigner assigner(&options);
518 EXPECT_NO_THROW(assigner.start());
519 ASSERT_NO_THROW(assigner.startOption("p"));
520 EXPECT_NO_THROW(assigner.finishOption());
521 EXPECT_NO_THROW(assigner.finish());
522 EXPECT_NO_THROW(options.finish());
527 TEST(OptionsAssignerIntegerTest, StoresToVector)
529 gmx::Options options(NULL, NULL);
530 std::vector<int> values;
531 using gmx::IntegerOption;
532 ASSERT_NO_THROW(options.addOption(
533 IntegerOption("p").storeVector(&values).multiValue()));
535 gmx::OptionsAssigner assigner(&options);
536 EXPECT_NO_THROW(assigner.start());
537 ASSERT_NO_THROW(assigner.startOption("p"));
538 ASSERT_NO_THROW(assigner.appendValue("-2"));
539 ASSERT_NO_THROW(assigner.appendValue("1"));
540 ASSERT_NO_THROW(assigner.appendValue("4"));
541 EXPECT_NO_THROW(assigner.finishOption());
542 EXPECT_NO_THROW(assigner.finish());
543 EXPECT_NO_THROW(options.finish());
545 EXPECT_EQ(3U, values.size());
546 EXPECT_EQ(-2, values[0]);
547 EXPECT_EQ(1, values[1]);
548 EXPECT_EQ(4, values[2]);
551 TEST(OptionsAssignerIntegerTest, HandlesVectors)
553 gmx::Options options(NULL, NULL);
554 int vec[3] = {0, 0, 0};
555 using gmx::IntegerOption;
556 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
558 gmx::OptionsAssigner assigner(&options);
559 EXPECT_NO_THROW(assigner.start());
560 ASSERT_NO_THROW(assigner.startOption("p"));
561 ASSERT_NO_THROW(assigner.appendValue("-2"));
562 ASSERT_NO_THROW(assigner.appendValue("1"));
563 ASSERT_NO_THROW(assigner.appendValue("4"));
564 EXPECT_NO_THROW(assigner.finishOption());
565 EXPECT_NO_THROW(assigner.finish());
566 EXPECT_NO_THROW(options.finish());
568 EXPECT_EQ(-2, vec[0]);
569 EXPECT_EQ(1, vec[1]);
570 EXPECT_EQ(4, vec[2]);
573 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
575 gmx::Options options(NULL, NULL);
576 int vec[3] = {0, 0, 0};
577 using gmx::IntegerOption;
578 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
580 gmx::OptionsAssigner assigner(&options);
581 EXPECT_NO_THROW(assigner.start());
582 ASSERT_NO_THROW(assigner.startOption("p"));
583 ASSERT_NO_THROW(assigner.appendValue("2"));
584 EXPECT_NO_THROW(assigner.finishOption());
585 EXPECT_NO_THROW(assigner.finish());
586 EXPECT_NO_THROW(options.finish());
588 EXPECT_EQ(2, vec[0]);
589 EXPECT_EQ(2, vec[1]);
590 EXPECT_EQ(2, vec[2]);
593 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
595 gmx::Options options(NULL, NULL);
596 int vec[3] = {3, 2, 1};
597 using gmx::IntegerOption;
598 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
600 EXPECT_NO_THROW(options.finish());
602 EXPECT_EQ(3, vec[0]);
603 EXPECT_EQ(2, vec[1]);
604 EXPECT_EQ(1, vec[2]);
607 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
609 gmx::Options options(NULL, NULL);
610 int vec[3] = {3, 2, 1};
611 std::vector<int> vec2(vec, vec+3);
612 using gmx::IntegerOption;
613 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec)
614 .storeVector(&vec2).vector()));
616 gmx::OptionsAssigner assigner(&options);
617 EXPECT_NO_THROW(assigner.start());
618 ASSERT_NO_THROW(assigner.startOption("p"));
619 EXPECT_NO_THROW(assigner.appendValue("1"));
620 EXPECT_NO_THROW(assigner.appendValue("3"));
621 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
622 EXPECT_NO_THROW(assigner.finish());
623 EXPECT_NO_THROW(options.finish());
625 EXPECT_EQ(3, vec[0]);
626 EXPECT_EQ(2, vec[1]);
627 EXPECT_EQ(1, vec[2]);
628 ASSERT_EQ(3U, vec2.size());
629 EXPECT_EQ(3, vec2[0]);
630 EXPECT_EQ(2, vec2[1]);
631 EXPECT_EQ(1, vec2[2]);
635 /********************************************************************
636 * Tests for double assignment
639 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
641 gmx::Options options(NULL, NULL);
643 using gmx::DoubleOption;
644 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
646 gmx::OptionsAssigner assigner(&options);
647 EXPECT_NO_THROW(assigner.start());
648 ASSERT_NO_THROW(assigner.startOption("p"));
649 ASSERT_NO_THROW(assigner.appendValue("2.7"));
650 EXPECT_NO_THROW(assigner.finishOption());
651 EXPECT_NO_THROW(assigner.finish());
652 EXPECT_NO_THROW(options.finish());
654 EXPECT_DOUBLE_EQ(2.7, value);
657 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
659 gmx::Options options(NULL, NULL);
661 using gmx::DoubleOption;
662 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
664 gmx::OptionsAssigner assigner(&options);
665 EXPECT_NO_THROW(assigner.start());
666 ASSERT_NO_THROW(assigner.startOption("p"));
667 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
668 EXPECT_NO_THROW(assigner.finishOption());
669 EXPECT_NO_THROW(assigner.finish());
670 EXPECT_NO_THROW(options.finish());
672 EXPECT_DOUBLE_EQ(1.0, value);
676 /********************************************************************
677 * Tests for string assignment
680 TEST(OptionsAssignerStringTest, StoresSingleValue)
682 gmx::Options options(NULL, NULL);
684 using gmx::StringOption;
685 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
687 gmx::OptionsAssigner assigner(&options);
688 EXPECT_NO_THROW(assigner.start());
689 ASSERT_NO_THROW(assigner.startOption("p"));
690 ASSERT_NO_THROW(assigner.appendValue("value"));
691 EXPECT_NO_THROW(assigner.finishOption());
692 EXPECT_NO_THROW(assigner.finish());
693 EXPECT_NO_THROW(options.finish());
695 EXPECT_EQ("value", value);
698 TEST(OptionsAssignerStringTest, HandlesEnumValue)
700 gmx::Options options(NULL, NULL);
702 const char * const allowed[] = { "none", "test", "value" };
704 using gmx::StringOption;
705 ASSERT_NO_THROW(options.addOption(
706 StringOption("p").store(&value)
707 .enumValue(allowed).storeEnumIndex(&index)));
709 gmx::OptionsAssigner assigner(&options);
710 EXPECT_NO_THROW(assigner.start());
711 ASSERT_NO_THROW(assigner.startOption("p"));
712 ASSERT_NO_THROW(assigner.appendValue("test"));
713 EXPECT_NO_THROW(assigner.finishOption());
714 EXPECT_NO_THROW(assigner.finish());
715 EXPECT_NO_THROW(options.finish());
717 EXPECT_EQ("test", value);
721 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
723 gmx::Options options(NULL, NULL);
725 const char * const allowed[] = { "none", "test", "value", NULL };
727 using gmx::StringOption;
728 ASSERT_NO_THROW(options.addOption(
729 StringOption("p").store(&value)
730 .enumValueFromNullTerminatedArray(allowed)
731 .storeEnumIndex(&index)));
733 gmx::OptionsAssigner assigner(&options);
734 EXPECT_NO_THROW(assigner.start());
735 ASSERT_NO_THROW(assigner.startOption("p"));
736 ASSERT_NO_THROW(assigner.appendValue("value"));
737 EXPECT_NO_THROW(assigner.finishOption());
738 EXPECT_NO_THROW(assigner.finish());
739 EXPECT_NO_THROW(options.finish());
741 EXPECT_EQ("value", value);
745 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
747 gmx::Options options(NULL, NULL);
749 const char * const allowed[] = { "none", "test", "value" };
751 using gmx::StringOption;
752 ASSERT_NO_THROW(options.addOption(
753 StringOption("p").store(&value)
754 .enumValue(allowed).storeEnumIndex(&index)));
756 gmx::OptionsAssigner assigner(&options);
757 EXPECT_NO_THROW(assigner.start());
758 ASSERT_NO_THROW(assigner.startOption("p"));
759 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
762 TEST(OptionsAssignerStringTest, CompletesEnumValue)
764 gmx::Options options(NULL, NULL);
766 const char * const allowed[] = { "none", "test", "value" };
768 using gmx::StringOption;
769 ASSERT_NO_THROW(options.addOption(
770 StringOption("p").store(&value)
771 .enumValue(allowed).storeEnumIndex(&index)));
773 gmx::OptionsAssigner assigner(&options);
774 EXPECT_NO_THROW(assigner.start());
775 ASSERT_NO_THROW(assigner.startOption("p"));
776 ASSERT_NO_THROW(assigner.appendValue("te"));
777 EXPECT_NO_THROW(assigner.finishOption());
778 EXPECT_NO_THROW(assigner.finish());
779 EXPECT_NO_THROW(options.finish());
781 EXPECT_EQ("test", value);
785 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
787 gmx::Options options(NULL, NULL);
789 const char * const allowed[] = { "none", "test", "value" };
791 using gmx::StringOption;
792 ASSERT_NO_THROW(options.addOption(
793 StringOption("p").store(&value)
794 .enumValue(allowed).storeEnumIndex(&index)));
795 EXPECT_TRUE(value.empty());
796 EXPECT_EQ(-1, index);
798 ASSERT_NO_THROW(options.finish());
800 EXPECT_TRUE(value.empty());
801 EXPECT_EQ(-1, index);
804 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
806 gmx::Options options(NULL, NULL);
808 const char * const allowed[] = { "none", "test", "value" };
810 using gmx::StringOption;
811 ASSERT_NO_THROW(options.addOption(
812 StringOption("p").store(&value)
813 .enumValue(allowed).defaultValue("test")
814 .storeEnumIndex(&index)));
815 EXPECT_EQ("test", value);
818 gmx::OptionsAssigner assigner(&options);
819 EXPECT_NO_THROW(assigner.start());
820 EXPECT_NO_THROW(assigner.finish());
821 EXPECT_NO_THROW(options.finish());
823 EXPECT_EQ("test", value);
827 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
829 gmx::Options options(NULL, NULL);
831 const char * const allowed[] = { "none", "test", "value" };
833 using gmx::StringOption;
834 ASSERT_NO_THROW(options.addOption(
835 StringOption("p").store(&value)
836 .enumValue(allowed).defaultEnumIndex(1)
837 .storeEnumIndex(&index)));
838 EXPECT_EQ("test", value);
841 gmx::OptionsAssigner assigner(&options);
842 EXPECT_NO_THROW(assigner.start());
843 EXPECT_NO_THROW(assigner.finish());
844 EXPECT_NO_THROW(options.finish());
846 EXPECT_EQ("test", value);