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
53 #include <gtest/gtest.h>
55 #include "gromacs/options/basicoptions.h"
56 #include "gromacs/options/options.h"
57 #include "gromacs/options/optionsassigner.h"
58 #include "gromacs/utility/exceptions.h"
59 #include "gromacs/utility/stringutil.h"
64 /********************************************************************
65 * General assignment tests
68 TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
70 gmx::Options options(NULL, NULL);
72 using gmx::IntegerOption;
73 ASSERT_NO_THROW(options.addOption(
74 IntegerOption("p").store(&value).required()));
76 EXPECT_THROW(options.finish(), gmx::InvalidInputError);
79 TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
81 gmx::Options options(NULL, NULL);
83 using gmx::IntegerOption;
84 ASSERT_NO_THROW(options.addOption(
85 IntegerOption("p").store(&value).required()
88 EXPECT_NO_THROW(options.finish());
92 TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
94 gmx::Options options(NULL, NULL);
95 std::vector<int> values;
96 using gmx::IntegerOption;
97 ASSERT_NO_THROW(options.addOption(
98 IntegerOption("p").storeVector(&values).multiValue()));
100 gmx::OptionsAssigner assigner(&options);
101 EXPECT_NO_THROW(assigner.start());
102 ASSERT_NO_THROW(assigner.startOption("p"));
103 ASSERT_NO_THROW(assigner.appendValue("1"));
104 ASSERT_NO_THROW(assigner.finishOption());
105 EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
106 EXPECT_NO_THROW(assigner.finish());
107 EXPECT_NO_THROW(options.finish());
109 EXPECT_TRUE(options.isSet("p"));
110 ASSERT_EQ(1U, values.size());
111 EXPECT_EQ(1, values[0]);
114 TEST(OptionsAssignerTest, HandlesMultipleParameter)
116 gmx::Options options(NULL, NULL);
117 std::vector<int> values;
118 using gmx::IntegerOption;
119 ASSERT_NO_THROW(options.addOption(
120 IntegerOption("p").storeVector(&values).allowMultiple()));
122 gmx::OptionsAssigner assigner(&options);
123 EXPECT_NO_THROW(assigner.start());
124 ASSERT_NO_THROW(assigner.startOption("p"));
125 ASSERT_NO_THROW(assigner.appendValue("1"));
126 EXPECT_NO_THROW(assigner.finishOption());
127 ASSERT_NO_THROW(assigner.startOption("p"));
128 ASSERT_NO_THROW(assigner.appendValue("2"));
129 EXPECT_NO_THROW(assigner.finishOption());
130 EXPECT_NO_THROW(assigner.finish());
131 EXPECT_NO_THROW(options.finish());
133 EXPECT_TRUE(options.isSet("p"));
134 ASSERT_EQ(2U, values.size());
135 EXPECT_EQ(1, values[0]);
136 EXPECT_EQ(2, values[1]);
139 TEST(OptionsAssignerTest, HandlesMissingValue)
141 gmx::Options options(NULL, NULL);
142 int value1 = 0, value2 = 0;
143 using gmx::IntegerOption;
144 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
145 ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
147 gmx::OptionsAssigner assigner(&options);
148 EXPECT_NO_THROW(assigner.start());
149 ASSERT_NO_THROW(assigner.startOption("p"));
150 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
151 ASSERT_NO_THROW(assigner.startOption("q"));
152 ASSERT_NO_THROW(assigner.appendValue("2"));
153 EXPECT_NO_THROW(assigner.finishOption());
154 EXPECT_NO_THROW(assigner.finish());
155 EXPECT_NO_THROW(options.finish());
157 EXPECT_EQ(2, value2);
160 TEST(OptionsAssignerTest, HandlesExtraValue)
162 gmx::Options options(NULL, NULL);
164 using gmx::IntegerOption;
165 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
167 gmx::OptionsAssigner assigner(&options);
168 EXPECT_NO_THROW(assigner.start());
169 ASSERT_NO_THROW(assigner.startOption("p"));
170 ASSERT_NO_THROW(assigner.appendValue("2"));
171 EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
172 EXPECT_NO_THROW(assigner.finishOption());
173 EXPECT_NO_THROW(assigner.finish());
174 EXPECT_NO_THROW(options.finish());
176 EXPECT_EQ(0, value1);
179 TEST(OptionsAssignerTest, HandlesSubSections)
181 gmx::Options options(NULL, NULL);
182 gmx::Options sub1("section1", NULL);
183 gmx::Options sub2("section2", NULL);
187 using gmx::IntegerOption;
188 ASSERT_NO_THROW(options.addSubSection(&sub1));
189 ASSERT_NO_THROW(options.addSubSection(&sub2));
190 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
191 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
192 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
194 gmx::OptionsAssigner assigner(&options);
195 EXPECT_NO_THROW(assigner.start());
196 ASSERT_NO_THROW(assigner.startSubSection("section1"));
197 ASSERT_NO_THROW(assigner.startOption("p"));
198 EXPECT_NO_THROW(assigner.appendValue("5"));
199 EXPECT_NO_THROW(assigner.finishOption());
200 EXPECT_NO_THROW(assigner.finishSubSection());
201 ASSERT_NO_THROW(assigner.startOption("p"));
202 EXPECT_NO_THROW(assigner.appendValue("4"));
203 EXPECT_NO_THROW(assigner.finishOption());
204 ASSERT_NO_THROW(assigner.startSubSection("section2"));
205 ASSERT_NO_THROW(assigner.startOption("p"));
206 EXPECT_NO_THROW(assigner.appendValue("6"));
207 EXPECT_NO_THROW(assigner.finishOption());
208 EXPECT_NO_THROW(assigner.finishSubSection());
209 EXPECT_NO_THROW(assigner.finish());
210 EXPECT_NO_THROW(options.finish());
213 EXPECT_EQ(5, value1);
214 EXPECT_EQ(6, value2);
217 TEST(OptionsAssignerTest, HandlesNoStrictSubSections)
219 gmx::Options options(NULL, NULL);
220 gmx::Options sub1("section1", NULL);
221 gmx::Options sub2("section2", NULL);
227 using gmx::IntegerOption;
228 ASSERT_NO_THROW(options.addSubSection(&sub1));
229 ASSERT_NO_THROW(options.addSubSection(&sub2));
230 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
231 ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
232 ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
233 ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
234 ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
236 gmx::OptionsAssigner assigner(&options);
237 assigner.setNoStrictSectioning(true);
238 EXPECT_NO_THROW(assigner.start());
239 ASSERT_NO_THROW(assigner.startOption("q"));
240 EXPECT_NO_THROW(assigner.appendValue("6"));
241 EXPECT_NO_THROW(assigner.finishOption());
242 ASSERT_NO_THROW(assigner.startOption("p"));
243 EXPECT_NO_THROW(assigner.appendValue("7"));
244 EXPECT_NO_THROW(assigner.finishOption());
245 ASSERT_NO_THROW(assigner.startOption("r"));
246 EXPECT_NO_THROW(assigner.appendValue("8"));
247 EXPECT_NO_THROW(assigner.finishOption());
248 ASSERT_NO_THROW(assigner.startOption("p"));
249 EXPECT_NO_THROW(assigner.appendValue("9"));
250 EXPECT_NO_THROW(assigner.finishOption());
251 EXPECT_NO_THROW(assigner.finishSubSection());
252 ASSERT_NO_THROW(assigner.startOption("p"));
253 EXPECT_NO_THROW(assigner.appendValue("10"));
254 EXPECT_NO_THROW(assigner.finishOption());
255 EXPECT_NO_THROW(assigner.finish());
256 EXPECT_NO_THROW(options.finish());
258 EXPECT_EQ(6, qvalue);
259 EXPECT_EQ(7, pvalue1);
260 EXPECT_EQ(8, rvalue);
261 EXPECT_EQ(9, pvalue2);
262 EXPECT_EQ(10, pvalue);
265 TEST(OptionsAssignerTest, HandlesMultipleSources)
267 gmx::Options options(NULL, NULL);
269 using gmx::IntegerOption;
270 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
273 gmx::OptionsAssigner assigner(&options);
274 EXPECT_NO_THROW(assigner.start());
275 ASSERT_NO_THROW(assigner.startOption("p"));
276 EXPECT_NO_THROW(assigner.appendValue("1"));
277 EXPECT_NO_THROW(assigner.finishOption());
278 EXPECT_NO_THROW(assigner.finish());
281 gmx::OptionsAssigner assigner2(&options);
282 EXPECT_NO_THROW(assigner2.start());
283 ASSERT_NO_THROW(assigner2.startOption("p"));
284 EXPECT_NO_THROW(assigner2.appendValue("2"));
285 EXPECT_NO_THROW(assigner2.finishOption());
286 EXPECT_NO_THROW(assigner2.finish());
288 EXPECT_NO_THROW(options.finish());
294 /********************************************************************
295 * Tests for boolean assignment
298 TEST(OptionsAssignerBooleanTest, StoresYesValue)
300 gmx::Options options(NULL, NULL);
302 using gmx::BooleanOption;
303 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
305 gmx::OptionsAssigner assigner(&options);
306 EXPECT_NO_THROW(assigner.start());
307 ASSERT_NO_THROW(assigner.startOption("p"));
308 EXPECT_NO_THROW(assigner.appendValue("yes"));
309 EXPECT_NO_THROW(assigner.finishOption());
310 EXPECT_NO_THROW(assigner.finish());
311 EXPECT_NO_THROW(options.finish());
316 TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
318 gmx::Options options(NULL, NULL);
320 using gmx::BooleanOption;
321 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
323 gmx::OptionsAssigner assigner(&options);
324 EXPECT_NO_THROW(assigner.start());
325 ASSERT_NO_THROW(assigner.startOption("p"));
326 EXPECT_NO_THROW(assigner.finishOption());
327 EXPECT_NO_THROW(assigner.finish());
328 EXPECT_NO_THROW(options.finish());
333 TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
335 gmx::Options options(NULL, NULL);
337 using gmx::BooleanOption;
338 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
340 gmx::OptionsAssigner assigner(&options);
341 assigner.setAcceptBooleanNoPrefix(true);
342 EXPECT_NO_THROW(assigner.start());
343 ASSERT_NO_THROW(assigner.startOption("nop"));
344 EXPECT_NO_THROW(assigner.finishOption());
345 EXPECT_NO_THROW(assigner.finish());
346 EXPECT_NO_THROW(options.finish());
351 TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
353 gmx::Options options(NULL, NULL);
355 using gmx::BooleanOption;
356 ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
358 gmx::OptionsAssigner assigner(&options);
359 assigner.setAcceptBooleanNoPrefix(true);
360 EXPECT_NO_THROW(assigner.start());
361 ASSERT_NO_THROW(assigner.startOption("nop"));
362 // It's OK to fail, but if it doesn't, it should work.
365 assigner.appendValue("no");
366 assigner.finishOption();
367 EXPECT_NO_THROW(assigner.finish());
370 catch (const gmx::InvalidInputError &)
376 /********************************************************************
377 * Tests for integer assignment
379 * These tests also contain tests for general default value handling.
382 TEST(OptionsAssignerIntegerTest, StoresSingleValue)
384 gmx::Options options(NULL, NULL);
386 using gmx::IntegerOption;
387 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
389 gmx::OptionsAssigner assigner(&options);
390 EXPECT_NO_THROW(assigner.start());
391 ASSERT_NO_THROW(assigner.startOption("p"));
392 ASSERT_NO_THROW(assigner.appendValue("3"));
393 EXPECT_NO_THROW(assigner.finishOption());
394 EXPECT_NO_THROW(assigner.finish());
395 EXPECT_NO_THROW(options.finish());
400 TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
402 gmx::Options options(NULL, NULL);
404 using gmx::IntegerOption;
405 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
407 gmx::OptionsAssigner assigner(&options);
408 EXPECT_NO_THROW(assigner.start());
409 ASSERT_NO_THROW(assigner.startOption("p"));
410 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
411 EXPECT_NO_THROW(assigner.finishOption());
412 EXPECT_NO_THROW(assigner.finish());
413 EXPECT_NO_THROW(options.finish());
418 TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
420 gmx::Options options(NULL, NULL);
422 using gmx::IntegerOption;
423 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
425 gmx::OptionsAssigner assigner(&options);
426 EXPECT_NO_THROW(assigner.start());
427 ASSERT_NO_THROW(assigner.startOption("p"));
428 EXPECT_THROW(assigner.appendValue("2abc"), gmx::InvalidInputError);
429 EXPECT_NO_THROW(assigner.finishOption());
430 EXPECT_NO_THROW(assigner.finish());
431 EXPECT_NO_THROW(options.finish());
436 TEST(OptionsAssignerIntegerTest, HandlesOverflow)
438 gmx::Options options(NULL, NULL);
440 using gmx::IntegerOption;
441 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
443 gmx::OptionsAssigner assigner(&options);
444 EXPECT_NO_THROW(assigner.start());
445 ASSERT_NO_THROW(assigner.startOption("p"));
446 std::string overflowValue(
447 gmx::formatString("%d0000", std::numeric_limits<int>::max()));
448 EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError);
449 EXPECT_NO_THROW(assigner.finishOption());
450 EXPECT_NO_THROW(assigner.finish());
451 EXPECT_NO_THROW(options.finish());
456 TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
458 gmx::Options options(NULL, NULL);
460 using gmx::IntegerOption;
461 ASSERT_NO_THROW(options.addOption(
462 IntegerOption("p").store(&value).defaultValue(2)));
465 gmx::OptionsAssigner assigner(&options);
466 EXPECT_NO_THROW(assigner.start());
467 EXPECT_NO_THROW(assigner.finish());
468 EXPECT_NO_THROW(options.finish());
473 TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
475 gmx::Options options(NULL, NULL);
477 using gmx::IntegerOption;
478 ASSERT_NO_THROW(options.addOption(
479 IntegerOption("p").store(&value).defaultValueIfSet(2)));
480 EXPECT_EQ(-1, value);
482 gmx::OptionsAssigner assigner(&options);
483 EXPECT_NO_THROW(assigner.start());
484 ASSERT_NO_THROW(assigner.startOption("p"));
485 EXPECT_NO_THROW(assigner.finishOption());
486 EXPECT_NO_THROW(assigner.finish());
487 EXPECT_NO_THROW(options.finish());
492 TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
494 gmx::Options options(NULL, NULL);
496 using gmx::IntegerOption;
497 ASSERT_NO_THROW(options.addOption(
498 IntegerOption("p").store(&value).defaultValueIfSet(2)));
499 EXPECT_EQ(-1, value);
501 gmx::OptionsAssigner assigner(&options);
502 EXPECT_NO_THROW(assigner.start());
503 EXPECT_NO_THROW(assigner.finish());
504 EXPECT_NO_THROW(options.finish());
506 EXPECT_EQ(-1, value);
509 TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
511 gmx::Options options(NULL, NULL);
513 using gmx::IntegerOption;
514 ASSERT_NO_THROW(options.addOption(
515 IntegerOption("p").store(&value)
516 .defaultValue(1).defaultValueIfSet(2)));
519 gmx::OptionsAssigner assigner(&options);
520 EXPECT_NO_THROW(assigner.start());
521 ASSERT_NO_THROW(assigner.startOption("p"));
522 EXPECT_NO_THROW(assigner.finishOption());
523 EXPECT_NO_THROW(assigner.finish());
524 EXPECT_NO_THROW(options.finish());
529 TEST(OptionsAssignerIntegerTest, StoresToVector)
531 gmx::Options options(NULL, NULL);
532 std::vector<int> values;
533 using gmx::IntegerOption;
534 ASSERT_NO_THROW(options.addOption(
535 IntegerOption("p").storeVector(&values).multiValue()));
537 gmx::OptionsAssigner assigner(&options);
538 EXPECT_NO_THROW(assigner.start());
539 ASSERT_NO_THROW(assigner.startOption("p"));
540 ASSERT_NO_THROW(assigner.appendValue("-2"));
541 ASSERT_NO_THROW(assigner.appendValue("1"));
542 ASSERT_NO_THROW(assigner.appendValue("4"));
543 EXPECT_NO_THROW(assigner.finishOption());
544 EXPECT_NO_THROW(assigner.finish());
545 EXPECT_NO_THROW(options.finish());
547 EXPECT_EQ(3U, values.size());
548 EXPECT_EQ(-2, values[0]);
549 EXPECT_EQ(1, values[1]);
550 EXPECT_EQ(4, values[2]);
553 TEST(OptionsAssignerIntegerTest, HandlesVectors)
555 gmx::Options options(NULL, NULL);
556 int vec[3] = {0, 0, 0};
557 using gmx::IntegerOption;
558 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
560 gmx::OptionsAssigner assigner(&options);
561 EXPECT_NO_THROW(assigner.start());
562 ASSERT_NO_THROW(assigner.startOption("p"));
563 ASSERT_NO_THROW(assigner.appendValue("-2"));
564 ASSERT_NO_THROW(assigner.appendValue("1"));
565 ASSERT_NO_THROW(assigner.appendValue("4"));
566 EXPECT_NO_THROW(assigner.finishOption());
567 EXPECT_NO_THROW(assigner.finish());
568 EXPECT_NO_THROW(options.finish());
570 EXPECT_EQ(-2, vec[0]);
571 EXPECT_EQ(1, vec[1]);
572 EXPECT_EQ(4, vec[2]);
575 TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
577 gmx::Options options(NULL, NULL);
578 int vec[3] = {0, 0, 0};
579 using gmx::IntegerOption;
580 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
582 gmx::OptionsAssigner assigner(&options);
583 EXPECT_NO_THROW(assigner.start());
584 ASSERT_NO_THROW(assigner.startOption("p"));
585 ASSERT_NO_THROW(assigner.appendValue("2"));
586 EXPECT_NO_THROW(assigner.finishOption());
587 EXPECT_NO_THROW(assigner.finish());
588 EXPECT_NO_THROW(options.finish());
590 EXPECT_EQ(2, vec[0]);
591 EXPECT_EQ(2, vec[1]);
592 EXPECT_EQ(2, vec[2]);
595 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
597 gmx::Options options(NULL, NULL);
598 int vec[3] = {3, 2, 1};
599 using gmx::IntegerOption;
600 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
602 EXPECT_NO_THROW(options.finish());
604 EXPECT_EQ(3, vec[0]);
605 EXPECT_EQ(2, vec[1]);
606 EXPECT_EQ(1, vec[2]);
609 TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
611 gmx::Options options(NULL, NULL);
612 int vec[3] = {3, 2, 1};
613 std::vector<int> vec2(vec, vec+3);
614 using gmx::IntegerOption;
615 ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec)
616 .storeVector(&vec2).vector()));
618 gmx::OptionsAssigner assigner(&options);
619 EXPECT_NO_THROW(assigner.start());
620 ASSERT_NO_THROW(assigner.startOption("p"));
621 EXPECT_NO_THROW(assigner.appendValue("1"));
622 EXPECT_NO_THROW(assigner.appendValue("3"));
623 EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
624 EXPECT_NO_THROW(assigner.finish());
625 EXPECT_NO_THROW(options.finish());
627 EXPECT_EQ(3, vec[0]);
628 EXPECT_EQ(2, vec[1]);
629 EXPECT_EQ(1, vec[2]);
630 ASSERT_EQ(3U, vec2.size());
631 EXPECT_EQ(3, vec2[0]);
632 EXPECT_EQ(2, vec2[1]);
633 EXPECT_EQ(1, vec2[2]);
637 /********************************************************************
638 * Tests for double assignment
641 TEST(OptionsAssignerDoubleTest, StoresSingleValue)
643 gmx::Options options(NULL, NULL);
645 using gmx::DoubleOption;
646 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
648 gmx::OptionsAssigner assigner(&options);
649 EXPECT_NO_THROW(assigner.start());
650 ASSERT_NO_THROW(assigner.startOption("p"));
651 ASSERT_NO_THROW(assigner.appendValue("2.7"));
652 EXPECT_NO_THROW(assigner.finishOption());
653 EXPECT_NO_THROW(assigner.finish());
654 EXPECT_NO_THROW(options.finish());
656 EXPECT_DOUBLE_EQ(2.7, value);
659 TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
661 gmx::Options options(NULL, NULL);
663 using gmx::DoubleOption;
664 ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
666 gmx::OptionsAssigner assigner(&options);
667 EXPECT_NO_THROW(assigner.start());
668 ASSERT_NO_THROW(assigner.startOption("p"));
669 EXPECT_THROW(assigner.appendValue(""), gmx::InvalidInputError);
670 EXPECT_NO_THROW(assigner.finishOption());
671 EXPECT_NO_THROW(assigner.finish());
672 EXPECT_NO_THROW(options.finish());
674 EXPECT_DOUBLE_EQ(1.0, value);
678 /********************************************************************
679 * Tests for string assignment
682 TEST(OptionsAssignerStringTest, StoresSingleValue)
684 gmx::Options options(NULL, NULL);
686 using gmx::StringOption;
687 ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
689 gmx::OptionsAssigner assigner(&options);
690 EXPECT_NO_THROW(assigner.start());
691 ASSERT_NO_THROW(assigner.startOption("p"));
692 ASSERT_NO_THROW(assigner.appendValue("value"));
693 EXPECT_NO_THROW(assigner.finishOption());
694 EXPECT_NO_THROW(assigner.finish());
695 EXPECT_NO_THROW(options.finish());
697 EXPECT_EQ("value", value);
700 TEST(OptionsAssignerStringTest, HandlesEnumValue)
702 gmx::Options options(NULL, NULL);
704 const char * const allowed[] = { "none", "test", "value" };
706 using gmx::StringOption;
707 ASSERT_NO_THROW(options.addOption(
708 StringOption("p").store(&value)
709 .enumValue(allowed).storeEnumIndex(&index)));
711 gmx::OptionsAssigner assigner(&options);
712 EXPECT_NO_THROW(assigner.start());
713 ASSERT_NO_THROW(assigner.startOption("p"));
714 ASSERT_NO_THROW(assigner.appendValue("test"));
715 EXPECT_NO_THROW(assigner.finishOption());
716 EXPECT_NO_THROW(assigner.finish());
717 EXPECT_NO_THROW(options.finish());
719 EXPECT_EQ("test", value);
723 TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
725 gmx::Options options(NULL, NULL);
727 const char * const allowed[] = { "none", "test", "value", NULL };
729 using gmx::StringOption;
730 ASSERT_NO_THROW(options.addOption(
731 StringOption("p").store(&value)
732 .enumValueFromNullTerminatedArray(allowed)
733 .storeEnumIndex(&index)));
735 gmx::OptionsAssigner assigner(&options);
736 EXPECT_NO_THROW(assigner.start());
737 ASSERT_NO_THROW(assigner.startOption("p"));
738 ASSERT_NO_THROW(assigner.appendValue("value"));
739 EXPECT_NO_THROW(assigner.finishOption());
740 EXPECT_NO_THROW(assigner.finish());
741 EXPECT_NO_THROW(options.finish());
743 EXPECT_EQ("value", value);
747 TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
749 gmx::Options options(NULL, NULL);
751 const char * const allowed[] = { "none", "test", "value" };
753 using gmx::StringOption;
754 ASSERT_NO_THROW(options.addOption(
755 StringOption("p").store(&value)
756 .enumValue(allowed).storeEnumIndex(&index)));
758 gmx::OptionsAssigner assigner(&options);
759 EXPECT_NO_THROW(assigner.start());
760 ASSERT_NO_THROW(assigner.startOption("p"));
761 ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
764 TEST(OptionsAssignerStringTest, CompletesEnumValue)
766 gmx::Options options(NULL, NULL);
768 const char * const allowed[] = { "none", "test", "value" };
770 using gmx::StringOption;
771 ASSERT_NO_THROW(options.addOption(
772 StringOption("p").store(&value)
773 .enumValue(allowed).storeEnumIndex(&index)));
775 gmx::OptionsAssigner assigner(&options);
776 EXPECT_NO_THROW(assigner.start());
777 ASSERT_NO_THROW(assigner.startOption("p"));
778 ASSERT_NO_THROW(assigner.appendValue("te"));
779 EXPECT_NO_THROW(assigner.finishOption());
780 EXPECT_NO_THROW(assigner.finish());
781 EXPECT_NO_THROW(options.finish());
783 EXPECT_EQ("test", value);
787 TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
789 gmx::Options options(NULL, NULL);
791 const char * const allowed[] = { "none", "test", "value" };
793 using gmx::StringOption;
794 ASSERT_NO_THROW(options.addOption(
795 StringOption("p").store(&value)
796 .enumValue(allowed).storeEnumIndex(&index)));
797 EXPECT_TRUE(value.empty());
798 EXPECT_EQ(-1, index);
800 ASSERT_NO_THROW(options.finish());
802 EXPECT_TRUE(value.empty());
803 EXPECT_EQ(-1, index);
806 TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
808 gmx::Options options(NULL, NULL);
810 const char * const allowed[] = { "none", "test", "value" };
812 using gmx::StringOption;
813 ASSERT_NO_THROW(options.addOption(
814 StringOption("p").store(&value)
815 .enumValue(allowed).defaultValue("test")
816 .storeEnumIndex(&index)));
817 EXPECT_EQ("test", value);
820 gmx::OptionsAssigner assigner(&options);
821 EXPECT_NO_THROW(assigner.start());
822 EXPECT_NO_THROW(assigner.finish());
823 EXPECT_NO_THROW(options.finish());
825 EXPECT_EQ("test", value);
829 TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
831 gmx::Options options(NULL, NULL);
833 const char * const allowed[] = { "none", "test", "value" };
835 using gmx::StringOption;
836 ASSERT_NO_THROW(options.addOption(
837 StringOption("p").store(&value)
838 .enumValue(allowed).defaultEnumIndex(1)
839 .storeEnumIndex(&index)));
840 EXPECT_EQ("test", value);
843 gmx::OptionsAssigner assigner(&options);
844 EXPECT_NO_THROW(assigner.start());
845 EXPECT_NO_THROW(assigner.finish());
846 EXPECT_NO_THROW(options.finish());
848 EXPECT_EQ("test", value);