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