Merge branch release-4-6
[alexxy/gromacs.git] / src / gromacs / selection / tests / selectionoption.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
5  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6  * others, as listed in the AUTHORS file in the top-level source
7  * directory and at http://www.gromacs.org.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \internal \file
36  * \brief
37  * Tests handling of selection options.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \ingroup module_selection
41  */
42 #include <gtest/gtest.h>
43
44 #include "gromacs/options/options.h"
45 #include "gromacs/options/optionsassigner.h"
46 #include "gromacs/selection/selection.h"
47 #include "gromacs/selection/selectioncollection.h"
48 #include "gromacs/selection/selectionfileoption.h"
49 #include "gromacs/selection/selectionoption.h"
50 #include "gromacs/selection/selectionoptionmanager.h"
51 #include "gromacs/utility/exceptions.h"
52
53 #include "testutils/testasserts.h"
54 #include "testutils/testfilemanager.h"
55
56 #include "toputils.h"
57
58 using gmx::test::TestFileManager;
59
60 namespace
61 {
62
63 /********************************************************************
64  * Base fixture for tests in this file.
65  */
66
67 class SelectionOptionTestBase : public ::testing::Test
68 {
69     public:
70         SelectionOptionTestBase();
71
72         void setManager();
73         void loadTopology(const char *filename);
74
75         gmx::SelectionCollection    sc_;
76         gmx::SelectionOptionManager manager_;
77         gmx::Options                options_;
78
79     private:
80         gmx::test::TopologyManager  topManager_;
81 };
82
83 SelectionOptionTestBase::SelectionOptionTestBase()
84     : manager_(&sc_), options_(NULL, NULL)
85 {
86     sc_.setReferencePosType("atom");
87     sc_.setOutputPosType("atom");
88 }
89
90 void SelectionOptionTestBase::setManager()
91 {
92     setManagerForSelectionOptions(&options_, &manager_);
93 }
94
95 void SelectionOptionTestBase::loadTopology(const char *filename)
96 {
97     topManager_.loadTopology(filename);
98
99     ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1));
100 }
101
102
103 /********************************************************************
104  * Tests for SelectionOption
105  */
106
107 //! Test fixture for gmx::SelectionOption.
108 typedef SelectionOptionTestBase SelectionOptionTest;
109
110 TEST_F(SelectionOptionTest, ParsesSimpleSelection)
111 {
112     gmx::Selection sel;
113     using gmx::SelectionOption;
114     ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
115     setManager();
116
117     gmx::OptionsAssigner assigner(&options_);
118     EXPECT_NO_THROW_GMX(assigner.start());
119     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
120     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
121     EXPECT_NO_THROW_GMX(assigner.finishOption());
122     EXPECT_NO_THROW_GMX(assigner.finish());
123     EXPECT_NO_THROW_GMX(options_.finish());
124 }
125
126
127 TEST_F(SelectionOptionTest, HandlesDynamicSelectionWhenStaticRequired)
128 {
129     gmx::Selection sel;
130     using gmx::SelectionOption;
131     ASSERT_NO_THROW_GMX(options_.addOption(
132                                 SelectionOption("sel").store(&sel).onlyStatic()));
133     setManager();
134
135     gmx::OptionsAssigner assigner(&options_);
136     EXPECT_NO_THROW_GMX(assigner.start());
137     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
138     EXPECT_THROW_GMX(assigner.appendValue("resname RA RB and x < 5"), gmx::InvalidInputError);
139     EXPECT_NO_THROW_GMX(assigner.finishOption());
140     EXPECT_NO_THROW_GMX(assigner.finish());
141     EXPECT_NO_THROW_GMX(options_.finish());
142 }
143
144
145 TEST_F(SelectionOptionTest, HandlesNonAtomicSelectionWhenAtomsRequired)
146 {
147     gmx::Selection sel;
148     using gmx::SelectionOption;
149     ASSERT_NO_THROW_GMX(options_.addOption(
150                                 SelectionOption("sel").store(&sel).onlyAtoms()));
151     setManager();
152
153     gmx::OptionsAssigner assigner(&options_);
154     EXPECT_NO_THROW_GMX(assigner.start());
155     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
156     EXPECT_NO_THROW_GMX(assigner.appendValue("res_cog of resname RA RB"));
157     EXPECT_NO_THROW_GMX(assigner.finishOption());
158     EXPECT_NO_THROW_GMX(assigner.finish());
159     EXPECT_NO_THROW_GMX(options_.finish());
160
161     ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
162     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
163 }
164
165
166 TEST_F(SelectionOptionTest, ChecksEmptySelections)
167 {
168     gmx::Selection sel;
169     using gmx::SelectionOption;
170     ASSERT_NO_THROW_GMX(options_.addOption(
171                                 SelectionOption("sel").store(&sel)));
172     setManager();
173
174     gmx::OptionsAssigner assigner(&options_);
175     EXPECT_NO_THROW_GMX(assigner.start());
176     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
177     EXPECT_NO_THROW_GMX(assigner.appendValue("none"));
178     EXPECT_NO_THROW_GMX(assigner.finishOption());
179     EXPECT_NO_THROW_GMX(assigner.finish());
180     EXPECT_NO_THROW_GMX(options_.finish());
181
182     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
183 }
184
185
186 TEST_F(SelectionOptionTest, ChecksEmptyDelayedSelections)
187 {
188     gmx::Selection sel;
189     using gmx::SelectionOption;
190     ASSERT_NO_THROW_GMX(options_.addOption(
191                                 SelectionOption("sel").store(&sel)));
192     setManager();
193
194     gmx::OptionsAssigner assigner(&options_);
195     EXPECT_NO_THROW_GMX(assigner.start());
196     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
197     EXPECT_NO_THROW_GMX(assigner.finishOption());
198     EXPECT_NO_THROW_GMX(assigner.finish());
199     EXPECT_NO_THROW_GMX(options_.finish());
200     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("none"));
201
202     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
203 }
204
205
206 TEST_F(SelectionOptionTest, HandlesTooManySelections)
207 {
208     gmx::Selection sel;
209     using gmx::SelectionOption;
210     ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
211     setManager();
212
213     gmx::OptionsAssigner assigner(&options_);
214     EXPECT_NO_THROW_GMX(assigner.start());
215     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
216     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
217     EXPECT_THROW_GMX(assigner.appendValue("resname RB RC"), gmx::InvalidInputError);
218     EXPECT_NO_THROW_GMX(assigner.finishOption());
219     EXPECT_NO_THROW_GMX(assigner.finish());
220     EXPECT_NO_THROW_GMX(options_.finish());
221 }
222
223
224 TEST_F(SelectionOptionTest, HandlesTooFewSelections)
225 {
226     gmx::Selection sel[2];
227     using gmx::SelectionOption;
228     ASSERT_NO_THROW_GMX(options_.addOption(
229                                 SelectionOption("sel").store(sel).valueCount(2)));
230     setManager();
231
232     gmx::OptionsAssigner assigner(&options_);
233     EXPECT_NO_THROW_GMX(assigner.start());
234     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
235     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
236     EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
237     EXPECT_NO_THROW_GMX(assigner.finish());
238     EXPECT_NO_THROW_GMX(options_.finish());
239 }
240
241
242 TEST_F(SelectionOptionTest, HandlesAdjuster)
243 {
244     gmx::SelectionList        sel;
245     using gmx::SelectionOption;
246     gmx::SelectionOptionInfo *info = options_.addOption(
247                 SelectionOption("sel").storeVector(&sel).multiValue());
248     setManager();
249
250     gmx::OptionsAssigner assigner(&options_);
251     EXPECT_NO_THROW_GMX(assigner.start());
252     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
253     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
254     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RB RC"));
255     EXPECT_NO_THROW_GMX(assigner.finishOption());
256     EXPECT_NO_THROW_GMX(assigner.finish());
257     EXPECT_NO_THROW_GMX(options_.finish());
258     EXPECT_NO_THROW_GMX(info->setValueCount(2));
259 }
260
261
262 TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster)
263 {
264     gmx::Selection            sel;
265     using gmx::SelectionOption;
266     gmx::SelectionOptionInfo *info = options_.addOption(
267                 SelectionOption("sel").store(&sel));
268     setManager();
269
270     gmx::OptionsAssigner assigner(&options_);
271     EXPECT_NO_THROW_GMX(assigner.start());
272     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
273     EXPECT_NO_THROW_GMX(assigner.appendValue("x < 5"));
274     EXPECT_NO_THROW_GMX(assigner.finishOption());
275     EXPECT_NO_THROW_GMX(assigner.finish());
276     EXPECT_NO_THROW_GMX(options_.finish());
277     EXPECT_THROW_GMX(info->setOnlyStatic(true), gmx::InvalidInputError);
278 }
279
280
281 TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster)
282 {
283     gmx::SelectionList        sel;
284     using gmx::SelectionOption;
285     gmx::SelectionOptionInfo *info = options_.addOption(
286                 SelectionOption("sel").storeVector(&sel).multiValue());
287     setManager();
288
289     gmx::OptionsAssigner assigner(&options_);
290     EXPECT_NO_THROW_GMX(assigner.start());
291     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
292     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
293     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RB RC"));
294     EXPECT_NO_THROW_GMX(assigner.finishOption());
295     EXPECT_NO_THROW_GMX(assigner.finish());
296     EXPECT_NO_THROW_GMX(options_.finish());
297     EXPECT_THROW_GMX(info->setValueCount(1), gmx::InvalidInputError);
298 }
299
300
301 TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster)
302 {
303     gmx::SelectionList        sel;
304     using gmx::SelectionOption;
305     gmx::SelectionOptionInfo *info = options_.addOption(
306                 SelectionOption("sel").storeVector(&sel).multiValue());
307     setManager();
308
309     gmx::OptionsAssigner assigner(&options_);
310     EXPECT_NO_THROW_GMX(assigner.start());
311     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
312     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
313     EXPECT_NO_THROW_GMX(assigner.finishOption());
314     EXPECT_NO_THROW_GMX(assigner.finish());
315     EXPECT_NO_THROW_GMX(options_.finish());
316     EXPECT_THROW_GMX(info->setValueCount(2), gmx::InvalidInputError);
317 }
318
319
320 TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection)
321 {
322     gmx::Selection sel;
323     using gmx::SelectionOption;
324     ASSERT_NO_THROW_GMX(options_.addOption(
325                                 SelectionOption("sel").store(&sel).required()));
326     setManager();
327
328     gmx::OptionsAssigner assigner(&options_);
329     EXPECT_NO_THROW_GMX(assigner.start());
330     EXPECT_NO_THROW_GMX(assigner.finish());
331     EXPECT_NO_THROW_GMX(options_.finish());
332     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
333     ASSERT_STREQ("resname RA RB", sel.selectionText());
334 }
335
336
337 TEST_F(SelectionOptionTest, HandlesTooFewDelayedRequiredSelections)
338 {
339     gmx::Selection sel[2];
340     using gmx::SelectionOption;
341     ASSERT_NO_THROW_GMX(options_.addOption(
342                                 SelectionOption("sel").store(sel).required()
343                                     .valueCount(2)));
344     setManager();
345
346     gmx::OptionsAssigner assigner(&options_);
347     EXPECT_NO_THROW_GMX(assigner.start());
348     EXPECT_NO_THROW_GMX(assigner.finish());
349     EXPECT_NO_THROW_GMX(options_.finish());
350     EXPECT_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"), gmx::InvalidInputError);
351 }
352
353
354 TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection)
355 {
356     gmx::Selection sel;
357     using gmx::SelectionOption;
358     ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
359     setManager();
360
361     gmx::OptionsAssigner assigner(&options_);
362     EXPECT_NO_THROW_GMX(assigner.start());
363     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
364     EXPECT_NO_THROW_GMX(assigner.finishOption());
365     EXPECT_NO_THROW_GMX(assigner.finish());
366     EXPECT_NO_THROW_GMX(options_.finish());
367     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
368     ASSERT_STREQ("resname RA RB", sel.selectionText());
369 }
370
371
372 TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster)
373 {
374     gmx::SelectionList        sel;
375     using gmx::SelectionOption;
376     gmx::SelectionOptionInfo *info = options_.addOption(
377                 SelectionOption("sel").storeVector(&sel).valueCount(3));
378     setManager();
379
380     gmx::OptionsAssigner assigner(&options_);
381     EXPECT_NO_THROW_GMX(assigner.start());
382     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
383     EXPECT_NO_THROW_GMX(assigner.finishOption());
384     EXPECT_NO_THROW_GMX(assigner.finish());
385     EXPECT_NO_THROW_GMX(options_.finish());
386     EXPECT_NO_THROW_GMX(info->setValueCount(2));
387     EXPECT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB; resname RB RC"));
388 }
389
390
391 /********************************************************************
392  * Tests for SelectionFileOption
393  */
394
395 class SelectionFileOptionTest : public SelectionOptionTestBase
396 {
397     public:
398         SelectionFileOptionTest();
399 };
400
401 SelectionFileOptionTest::SelectionFileOptionTest()
402 {
403     options_.addOption(gmx::SelectionFileOption("sf"));
404 }
405
406
407 TEST_F(SelectionFileOptionTest, HandlesSingleSelectionOptionFromFile)
408 {
409     gmx::SelectionList sel;
410     gmx::SelectionList reqsel;
411     using gmx::SelectionOption;
412     ASSERT_NO_THROW_GMX(options_.addOption(
413                                 SelectionOption("sel").storeVector(&sel).multiValue()));
414     ASSERT_NO_THROW_GMX(options_.addOption(
415                                 SelectionOption("reqsel").storeVector(&reqsel)
416                                     .multiValue().required()));
417     setManager();
418
419     gmx::OptionsAssigner assigner(&options_);
420     EXPECT_NO_THROW_GMX(assigner.start());
421     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
422     EXPECT_NO_THROW_GMX(assigner.finishOption());
423     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
424     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
425     EXPECT_NO_THROW_GMX(assigner.finishOption());
426     EXPECT_NO_THROW_GMX(assigner.finish());
427     EXPECT_NO_THROW_GMX(options_.finish());
428
429     // These should match the contents of selfile.dat
430     ASSERT_EQ(2U, sel.size());
431     EXPECT_STREQ("resname RA RB", sel[0].selectionText());
432     EXPECT_STREQ("resname RB RC", sel[1].selectionText());
433     ASSERT_EQ(0U, reqsel.size());
434 }
435
436
437 TEST_F(SelectionFileOptionTest, HandlesTwoSeparateSelectionOptions)
438 {
439     gmx::SelectionList sel1;
440     gmx::SelectionList sel2;
441     using gmx::SelectionOption;
442     ASSERT_NO_THROW_GMX(options_.addOption(
443                                 SelectionOption("sel1").storeVector(&sel1).multiValue()));
444     ASSERT_NO_THROW_GMX(options_.addOption(
445                                 SelectionOption("sel2").storeVector(&sel2).multiValue()));
446     setManager();
447
448     gmx::OptionsAssigner assigner(&options_);
449     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
450     EXPECT_NO_THROW_GMX(assigner.start());
451     ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
452     EXPECT_NO_THROW_GMX(assigner.finishOption());
453     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
454     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
455     EXPECT_NO_THROW_GMX(assigner.finishOption());
456     ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
457     EXPECT_NO_THROW_GMX(assigner.finishOption());
458     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
459     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
460     EXPECT_NO_THROW_GMX(assigner.finishOption());
461     EXPECT_NO_THROW_GMX(assigner.finish());
462     EXPECT_NO_THROW_GMX(options_.finish());
463
464     // These should match the contents of selfile.dat
465     ASSERT_EQ(2U, sel1.size());
466     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
467     EXPECT_STREQ("resname RB RC", sel1[1].selectionText());
468     ASSERT_EQ(2U, sel2.size());
469     EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
470     EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
471 }
472
473
474 TEST_F(SelectionFileOptionTest, HandlesTwoSelectionOptionsFromSingleFile)
475 {
476     gmx::SelectionList sel1;
477     gmx::SelectionList sel2;
478     using gmx::SelectionOption;
479     ASSERT_NO_THROW_GMX(options_.addOption(
480                                 SelectionOption("sel1").storeVector(&sel1)));
481     ASSERT_NO_THROW_GMX(options_.addOption(
482                                 SelectionOption("sel2").storeVector(&sel2)));
483     setManager();
484
485     gmx::OptionsAssigner assigner(&options_);
486     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
487     EXPECT_NO_THROW_GMX(assigner.start());
488     ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
489     EXPECT_NO_THROW_GMX(assigner.finishOption());
490     ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
491     EXPECT_NO_THROW_GMX(assigner.finishOption());
492     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
493     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
494     EXPECT_NO_THROW_GMX(assigner.finishOption());
495     EXPECT_NO_THROW_GMX(assigner.finish());
496     EXPECT_NO_THROW_GMX(options_.finish());
497
498     // These should match the contents of selfile.dat
499     ASSERT_EQ(1U, sel1.size());
500     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
501     ASSERT_EQ(1U, sel2.size());
502     EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
503 }
504
505
506 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFile)
507 {
508     gmx::SelectionList sel;
509     gmx::SelectionList optsel;
510     using gmx::SelectionOption;
511     ASSERT_NO_THROW_GMX(options_.addOption(
512                                 SelectionOption("sel").storeVector(&sel)
513                                     .multiValue().required()));
514     ASSERT_NO_THROW_GMX(options_.addOption(
515                                 SelectionOption("optsel").storeVector(&optsel)
516                                     .multiValue()));
517     setManager();
518
519     gmx::OptionsAssigner assigner(&options_);
520     EXPECT_NO_THROW_GMX(assigner.start());
521     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
522     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
523     EXPECT_NO_THROW_GMX(assigner.finishOption());
524     EXPECT_NO_THROW_GMX(assigner.startOption("optsel"));
525     EXPECT_NO_THROW_GMX(assigner.finishOption());
526     EXPECT_NO_THROW_GMX(assigner.finish());
527     EXPECT_NO_THROW_GMX(options_.finish());
528     EXPECT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RC RD"));
529
530     // These should match the contents of selfile.dat
531     ASSERT_EQ(2U, sel.size());
532     EXPECT_STREQ("resname RA RB", sel[0].selectionText());
533     EXPECT_STREQ("resname RB RC", sel[1].selectionText());
534     ASSERT_EQ(1U, optsel.size());
535     EXPECT_STREQ("resname RC RD", optsel[0].selectionText());
536 }
537
538
539 // TODO: Is this the best possible behavior, or should it error out?
540 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFileWithOtherOptionSet)
541 {
542     gmx::SelectionList sel1;
543     gmx::SelectionList sel2;
544     using gmx::SelectionOption;
545     ASSERT_NO_THROW_GMX(options_.addOption(
546                                 SelectionOption("sel1").storeVector(&sel1)
547                                     .multiValue().required()));
548     ASSERT_NO_THROW_GMX(options_.addOption(
549                                 SelectionOption("sel2").storeVector(&sel2)
550                                     .multiValue().required()));
551     setManager();
552
553     gmx::OptionsAssigner assigner(&options_);
554     EXPECT_NO_THROW_GMX(assigner.start());
555     EXPECT_NO_THROW_GMX(assigner.startOption("sel1"));
556     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RC RD"));
557     EXPECT_NO_THROW_GMX(assigner.finishOption());
558     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
559     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
560     EXPECT_NO_THROW_GMX(assigner.finishOption());
561     EXPECT_NO_THROW_GMX(assigner.finish());
562     EXPECT_NO_THROW_GMX(options_.finish());
563
564     // These should match the contents of selfile.dat
565     ASSERT_EQ(2U, sel2.size());
566     EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
567     EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
568     ASSERT_EQ(1U, sel1.size());
569     EXPECT_STREQ("resname RC RD", sel1[0].selectionText());
570 }
571
572
573 TEST_F(SelectionFileOptionTest, HandlesTwoRequiredOptionsFromSingleFile)
574 {
575     gmx::SelectionList sel1;
576     gmx::SelectionList sel2;
577     using gmx::SelectionOption;
578     ASSERT_NO_THROW_GMX(options_.addOption(
579                                 SelectionOption("sel1").storeVector(&sel1).required()));
580     ASSERT_NO_THROW_GMX(options_.addOption(
581                                 SelectionOption("sel2").storeVector(&sel2).required()));
582     setManager();
583
584     gmx::OptionsAssigner assigner(&options_);
585     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
586     EXPECT_NO_THROW_GMX(assigner.start());
587     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
588     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
589     EXPECT_NO_THROW_GMX(assigner.finishOption());
590     EXPECT_NO_THROW_GMX(assigner.finish());
591     EXPECT_NO_THROW_GMX(options_.finish());
592
593     // These should match the contents of selfile.dat
594     ASSERT_EQ(1U, sel1.size());
595     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
596     ASSERT_EQ(1U, sel2.size());
597     EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
598 }
599
600
601 TEST_F(SelectionFileOptionTest, GivesErrorWithNoFile)
602 {
603     gmx::SelectionList sel;
604     using gmx::SelectionOption;
605     ASSERT_NO_THROW_GMX(options_.addOption(
606                                 SelectionOption("sel").storeVector(&sel).multiValue()));
607     setManager();
608
609     gmx::OptionsAssigner assigner(&options_);
610     EXPECT_NO_THROW_GMX(assigner.start());
611     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
612     EXPECT_NO_THROW_GMX(assigner.finishOption());
613     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
614     EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
615     EXPECT_NO_THROW_GMX(assigner.finish());
616     EXPECT_NO_THROW_GMX(options_.finish());
617 }
618
619
620 TEST_F(SelectionFileOptionTest, GivesErrorWithNonExistentFile)
621 {
622     gmx::SelectionList sel;
623     using gmx::SelectionOption;
624     ASSERT_NO_THROW_GMX(options_.addOption(
625                                 SelectionOption("sel").storeVector(&sel).multiValue()));
626     setManager();
627
628     gmx::OptionsAssigner assigner(&options_);
629     EXPECT_NO_THROW_GMX(assigner.start());
630     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
631     EXPECT_NO_THROW_GMX(assigner.finishOption());
632     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
633     // TODO: Should this be changed to an InvalidInputError?
634     EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::FileIOError);
635     EXPECT_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")),
636                      gmx::InvalidInputError);
637     EXPECT_NO_THROW_GMX(assigner.finishOption());
638     EXPECT_NO_THROW_GMX(assigner.finish());
639     EXPECT_NO_THROW_GMX(options_.finish());
640 }
641
642
643 TEST_F(SelectionFileOptionTest, GivesErrorWithMultipleFiles)
644 {
645     gmx::SelectionList sel;
646     using gmx::SelectionOption;
647     ASSERT_NO_THROW_GMX(options_.addOption(
648                                 SelectionOption("sel").storeVector(&sel).multiValue()));
649     setManager();
650
651     gmx::OptionsAssigner assigner(&options_);
652     EXPECT_NO_THROW_GMX(assigner.start());
653     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
654     EXPECT_NO_THROW_GMX(assigner.finishOption());
655     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
656     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
657     EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::InvalidInputError);
658     EXPECT_NO_THROW_GMX(assigner.finishOption());
659     EXPECT_NO_THROW_GMX(assigner.finish());
660     EXPECT_NO_THROW_GMX(options_.finish());
661 }
662
663 } // namespace