Merge branch release-4-6 into release-5-0
[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 <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     ASSERT_TRUE(sel.isValid());
126 }
127
128
129 TEST_F(SelectionOptionTest, HandlesDynamicSelectionWhenStaticRequired)
130 {
131     gmx::Selection sel;
132     using gmx::SelectionOption;
133     ASSERT_NO_THROW_GMX(options_.addOption(
134                                 SelectionOption("sel").store(&sel).onlyStatic()));
135     setManager();
136
137     gmx::OptionsAssigner assigner(&options_);
138     EXPECT_NO_THROW_GMX(assigner.start());
139     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
140     EXPECT_THROW_GMX(assigner.appendValue("resname RA RB and x < 5"), gmx::InvalidInputError);
141     EXPECT_NO_THROW_GMX(assigner.finishOption());
142     EXPECT_NO_THROW_GMX(assigner.finish());
143     EXPECT_NO_THROW_GMX(options_.finish());
144 }
145
146
147 TEST_F(SelectionOptionTest, HandlesNonAtomicSelectionWhenAtomsRequired)
148 {
149     gmx::Selection sel;
150     using gmx::SelectionOption;
151     ASSERT_NO_THROW_GMX(options_.addOption(
152                                 SelectionOption("sel").store(&sel).onlyAtoms()));
153     setManager();
154
155     gmx::OptionsAssigner assigner(&options_);
156     EXPECT_NO_THROW_GMX(assigner.start());
157     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
158     EXPECT_NO_THROW_GMX(assigner.appendValue("res_cog of resname RA RB"));
159     EXPECT_NO_THROW_GMX(assigner.finishOption());
160     EXPECT_NO_THROW_GMX(assigner.finish());
161     EXPECT_NO_THROW_GMX(options_.finish());
162
163     ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
164     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
165 }
166
167
168 TEST_F(SelectionOptionTest, ChecksEmptySelections)
169 {
170     gmx::Selection sel;
171     using gmx::SelectionOption;
172     ASSERT_NO_THROW_GMX(options_.addOption(
173                                 SelectionOption("sel").store(&sel)));
174     setManager();
175
176     gmx::OptionsAssigner assigner(&options_);
177     EXPECT_NO_THROW_GMX(assigner.start());
178     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
179     EXPECT_NO_THROW_GMX(assigner.appendValue("none"));
180     EXPECT_NO_THROW_GMX(assigner.finishOption());
181     EXPECT_NO_THROW_GMX(assigner.finish());
182     EXPECT_NO_THROW_GMX(options_.finish());
183
184     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
185 }
186
187
188 TEST_F(SelectionOptionTest, ChecksEmptyDelayedSelections)
189 {
190     gmx::Selection sel;
191     using gmx::SelectionOption;
192     ASSERT_NO_THROW_GMX(options_.addOption(
193                                 SelectionOption("sel").store(&sel)));
194     setManager();
195
196     gmx::OptionsAssigner assigner(&options_);
197     EXPECT_NO_THROW_GMX(assigner.start());
198     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
199     EXPECT_NO_THROW_GMX(assigner.finishOption());
200     EXPECT_NO_THROW_GMX(assigner.finish());
201     EXPECT_NO_THROW_GMX(options_.finish());
202     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("none"));
203
204     EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
205 }
206
207
208 TEST_F(SelectionOptionTest, HandlesTooManySelections)
209 {
210     gmx::Selection sel;
211     using gmx::SelectionOption;
212     ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
213     setManager();
214
215     gmx::OptionsAssigner assigner(&options_);
216     EXPECT_NO_THROW_GMX(assigner.start());
217     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
218     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
219     EXPECT_THROW_GMX(assigner.appendValue("resname RB RC"), gmx::InvalidInputError);
220     EXPECT_NO_THROW_GMX(assigner.finishOption());
221     EXPECT_NO_THROW_GMX(assigner.finish());
222     EXPECT_NO_THROW_GMX(options_.finish());
223 }
224
225
226 TEST_F(SelectionOptionTest, HandlesTooFewSelections)
227 {
228     gmx::Selection sel[2];
229     using gmx::SelectionOption;
230     ASSERT_NO_THROW_GMX(options_.addOption(
231                                 SelectionOption("sel").store(sel).valueCount(2)));
232     setManager();
233
234     gmx::OptionsAssigner assigner(&options_);
235     EXPECT_NO_THROW_GMX(assigner.start());
236     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
237     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
238     EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
239     EXPECT_NO_THROW_GMX(assigner.finish());
240     EXPECT_NO_THROW_GMX(options_.finish());
241 }
242
243
244 TEST_F(SelectionOptionTest, HandlesDefaultSelectionText)
245 {
246     gmx::Selection sel;
247     using gmx::SelectionOption;
248     options_.addOption(SelectionOption("sel").store(&sel)
249                            .defaultSelectionText("all"));
250     setManager();
251
252     EXPECT_NO_THROW_GMX(options_.finish());
253
254     ASSERT_TRUE(sel.isValid());
255
256     EXPECT_NO_THROW_GMX(sc_.setTopology(NULL, 10));
257     EXPECT_NO_THROW_GMX(sc_.compile());
258
259     EXPECT_STREQ("all", sel.selectionText());
260 }
261
262
263 TEST_F(SelectionOptionTest, HandlesAdjuster)
264 {
265     gmx::SelectionList        sel;
266     using gmx::SelectionOption;
267     gmx::SelectionOptionInfo *info = options_.addOption(
268                 SelectionOption("sel").storeVector(&sel).multiValue());
269     setManager();
270
271     gmx::OptionsAssigner assigner(&options_);
272     EXPECT_NO_THROW_GMX(assigner.start());
273     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
274     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
275     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RB RC"));
276     EXPECT_NO_THROW_GMX(assigner.finishOption());
277     EXPECT_NO_THROW_GMX(assigner.finish());
278     EXPECT_NO_THROW_GMX(options_.finish());
279     EXPECT_NO_THROW_GMX(info->setValueCount(2));
280 }
281
282
283 TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster)
284 {
285     gmx::Selection            sel;
286     using gmx::SelectionOption;
287     gmx::SelectionOptionInfo *info = options_.addOption(
288                 SelectionOption("sel").store(&sel));
289     setManager();
290
291     gmx::OptionsAssigner assigner(&options_);
292     EXPECT_NO_THROW_GMX(assigner.start());
293     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
294     EXPECT_NO_THROW_GMX(assigner.appendValue("x < 5"));
295     EXPECT_NO_THROW_GMX(assigner.finishOption());
296     EXPECT_NO_THROW_GMX(assigner.finish());
297     EXPECT_NO_THROW_GMX(options_.finish());
298     EXPECT_THROW_GMX(info->setOnlyStatic(true), gmx::InvalidInputError);
299 }
300
301
302 TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster)
303 {
304     gmx::SelectionList        sel;
305     using gmx::SelectionOption;
306     gmx::SelectionOptionInfo *info = options_.addOption(
307                 SelectionOption("sel").storeVector(&sel).multiValue());
308     setManager();
309
310     gmx::OptionsAssigner assigner(&options_);
311     EXPECT_NO_THROW_GMX(assigner.start());
312     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
313     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
314     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RB RC"));
315     EXPECT_NO_THROW_GMX(assigner.finishOption());
316     EXPECT_NO_THROW_GMX(assigner.finish());
317     EXPECT_NO_THROW_GMX(options_.finish());
318     EXPECT_THROW_GMX(info->setValueCount(1), gmx::InvalidInputError);
319 }
320
321
322 TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster)
323 {
324     gmx::SelectionList        sel;
325     using gmx::SelectionOption;
326     gmx::SelectionOptionInfo *info = options_.addOption(
327                 SelectionOption("sel").storeVector(&sel).multiValue());
328     setManager();
329
330     gmx::OptionsAssigner assigner(&options_);
331     EXPECT_NO_THROW_GMX(assigner.start());
332     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
333     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
334     EXPECT_NO_THROW_GMX(assigner.finishOption());
335     EXPECT_NO_THROW_GMX(assigner.finish());
336     EXPECT_NO_THROW_GMX(options_.finish());
337     EXPECT_THROW_GMX(info->setValueCount(2), gmx::InvalidInputError);
338 }
339
340
341 TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection)
342 {
343     gmx::Selection sel;
344     using gmx::SelectionOption;
345     ASSERT_NO_THROW_GMX(options_.addOption(
346                                 SelectionOption("sel").store(&sel).required()));
347     setManager();
348
349     gmx::OptionsAssigner assigner(&options_);
350     EXPECT_NO_THROW_GMX(assigner.start());
351     EXPECT_NO_THROW_GMX(assigner.finish());
352     EXPECT_NO_THROW_GMX(options_.finish());
353     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
354     ASSERT_STREQ("resname RA RB", sel.selectionText());
355 }
356
357
358 TEST_F(SelectionOptionTest, HandlesTooFewDelayedRequiredSelections)
359 {
360     gmx::Selection sel[2];
361     using gmx::SelectionOption;
362     ASSERT_NO_THROW_GMX(options_.addOption(
363                                 SelectionOption("sel").store(sel).required()
364                                     .valueCount(2)));
365     setManager();
366
367     gmx::OptionsAssigner assigner(&options_);
368     EXPECT_NO_THROW_GMX(assigner.start());
369     EXPECT_NO_THROW_GMX(assigner.finish());
370     EXPECT_NO_THROW_GMX(options_.finish());
371     EXPECT_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"), gmx::InvalidInputError);
372 }
373
374
375 TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection)
376 {
377     gmx::Selection sel;
378     using gmx::SelectionOption;
379     ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
380     setManager();
381
382     gmx::OptionsAssigner assigner(&options_);
383     EXPECT_NO_THROW_GMX(assigner.start());
384     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
385     EXPECT_NO_THROW_GMX(assigner.finishOption());
386     EXPECT_NO_THROW_GMX(assigner.finish());
387     EXPECT_NO_THROW_GMX(options_.finish());
388     ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
389     ASSERT_STREQ("resname RA RB", sel.selectionText());
390 }
391
392
393 TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster)
394 {
395     gmx::SelectionList        sel;
396     using gmx::SelectionOption;
397     gmx::SelectionOptionInfo *info = options_.addOption(
398                 SelectionOption("sel").storeVector(&sel).valueCount(3));
399     setManager();
400
401     gmx::OptionsAssigner assigner(&options_);
402     EXPECT_NO_THROW_GMX(assigner.start());
403     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
404     EXPECT_NO_THROW_GMX(assigner.finishOption());
405     EXPECT_NO_THROW_GMX(assigner.finish());
406     EXPECT_NO_THROW_GMX(options_.finish());
407     EXPECT_NO_THROW_GMX(info->setValueCount(2));
408     EXPECT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB; resname RB RC"));
409 }
410
411
412 /********************************************************************
413  * Tests for SelectionFileOption
414  */
415
416 class SelectionFileOptionTest : public SelectionOptionTestBase
417 {
418     public:
419         SelectionFileOptionTest();
420 };
421
422 SelectionFileOptionTest::SelectionFileOptionTest()
423 {
424     options_.addOption(gmx::SelectionFileOption("sf"));
425 }
426
427
428 TEST_F(SelectionFileOptionTest, HandlesSingleSelectionOptionFromFile)
429 {
430     gmx::SelectionList sel;
431     gmx::SelectionList reqsel;
432     using gmx::SelectionOption;
433     ASSERT_NO_THROW_GMX(options_.addOption(
434                                 SelectionOption("sel").storeVector(&sel).multiValue()));
435     ASSERT_NO_THROW_GMX(options_.addOption(
436                                 SelectionOption("reqsel").storeVector(&reqsel)
437                                     .multiValue().required()));
438     setManager();
439
440     gmx::OptionsAssigner assigner(&options_);
441     EXPECT_NO_THROW_GMX(assigner.start());
442     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
443     EXPECT_NO_THROW_GMX(assigner.finishOption());
444     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
445     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
446     EXPECT_NO_THROW_GMX(assigner.finishOption());
447     EXPECT_NO_THROW_GMX(assigner.finish());
448     EXPECT_NO_THROW_GMX(options_.finish());
449
450     // These should match the contents of selfile.dat
451     ASSERT_EQ(2U, sel.size());
452     EXPECT_STREQ("resname RA RB", sel[0].selectionText());
453     EXPECT_STREQ("resname RB RC", sel[1].selectionText());
454     ASSERT_EQ(0U, reqsel.size());
455 }
456
457
458 TEST_F(SelectionFileOptionTest, HandlesTwoSeparateSelectionOptions)
459 {
460     gmx::SelectionList sel1;
461     gmx::SelectionList sel2;
462     using gmx::SelectionOption;
463     ASSERT_NO_THROW_GMX(options_.addOption(
464                                 SelectionOption("sel1").storeVector(&sel1).multiValue()));
465     ASSERT_NO_THROW_GMX(options_.addOption(
466                                 SelectionOption("sel2").storeVector(&sel2).multiValue()));
467     setManager();
468
469     gmx::OptionsAssigner assigner(&options_);
470     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
471     EXPECT_NO_THROW_GMX(assigner.start());
472     ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
473     EXPECT_NO_THROW_GMX(assigner.finishOption());
474     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
475     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
476     EXPECT_NO_THROW_GMX(assigner.finishOption());
477     ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
478     EXPECT_NO_THROW_GMX(assigner.finishOption());
479     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
480     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
481     EXPECT_NO_THROW_GMX(assigner.finishOption());
482     EXPECT_NO_THROW_GMX(assigner.finish());
483     EXPECT_NO_THROW_GMX(options_.finish());
484
485     // These should match the contents of selfile.dat
486     ASSERT_EQ(2U, sel1.size());
487     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
488     EXPECT_STREQ("resname RB RC", sel1[1].selectionText());
489     ASSERT_EQ(2U, sel2.size());
490     EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
491     EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
492 }
493
494
495 TEST_F(SelectionFileOptionTest, HandlesTwoSelectionOptionsFromSingleFile)
496 {
497     gmx::SelectionList sel1;
498     gmx::SelectionList sel2;
499     using gmx::SelectionOption;
500     ASSERT_NO_THROW_GMX(options_.addOption(
501                                 SelectionOption("sel1").storeVector(&sel1)));
502     ASSERT_NO_THROW_GMX(options_.addOption(
503                                 SelectionOption("sel2").storeVector(&sel2)));
504     setManager();
505
506     gmx::OptionsAssigner assigner(&options_);
507     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
508     EXPECT_NO_THROW_GMX(assigner.start());
509     ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
510     EXPECT_NO_THROW_GMX(assigner.finishOption());
511     ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
512     EXPECT_NO_THROW_GMX(assigner.finishOption());
513     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
514     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
515     EXPECT_NO_THROW_GMX(assigner.finishOption());
516     EXPECT_NO_THROW_GMX(assigner.finish());
517     EXPECT_NO_THROW_GMX(options_.finish());
518
519     // These should match the contents of selfile.dat
520     ASSERT_EQ(1U, sel1.size());
521     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
522     ASSERT_EQ(1U, sel2.size());
523     EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
524 }
525
526
527 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFile)
528 {
529     gmx::SelectionList sel;
530     gmx::SelectionList optsel;
531     using gmx::SelectionOption;
532     ASSERT_NO_THROW_GMX(options_.addOption(
533                                 SelectionOption("sel").storeVector(&sel)
534                                     .multiValue().required()));
535     ASSERT_NO_THROW_GMX(options_.addOption(
536                                 SelectionOption("optsel").storeVector(&optsel)
537                                     .multiValue()));
538     setManager();
539
540     gmx::OptionsAssigner assigner(&options_);
541     EXPECT_NO_THROW_GMX(assigner.start());
542     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
543     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
544     EXPECT_NO_THROW_GMX(assigner.finishOption());
545     EXPECT_NO_THROW_GMX(assigner.startOption("optsel"));
546     EXPECT_NO_THROW_GMX(assigner.finishOption());
547     EXPECT_NO_THROW_GMX(assigner.finish());
548     EXPECT_NO_THROW_GMX(options_.finish());
549     EXPECT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RC RD"));
550
551     // These should match the contents of selfile.dat
552     ASSERT_EQ(2U, sel.size());
553     EXPECT_STREQ("resname RA RB", sel[0].selectionText());
554     EXPECT_STREQ("resname RB RC", sel[1].selectionText());
555     ASSERT_EQ(1U, optsel.size());
556     EXPECT_STREQ("resname RC RD", optsel[0].selectionText());
557 }
558
559
560 // TODO: Is this the best possible behavior, or should it error out?
561 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFileWithOtherOptionSet)
562 {
563     gmx::SelectionList sel1;
564     gmx::SelectionList sel2;
565     using gmx::SelectionOption;
566     ASSERT_NO_THROW_GMX(options_.addOption(
567                                 SelectionOption("sel1").storeVector(&sel1)
568                                     .multiValue().required()));
569     ASSERT_NO_THROW_GMX(options_.addOption(
570                                 SelectionOption("sel2").storeVector(&sel2)
571                                     .multiValue().required()));
572     setManager();
573
574     gmx::OptionsAssigner assigner(&options_);
575     EXPECT_NO_THROW_GMX(assigner.start());
576     EXPECT_NO_THROW_GMX(assigner.startOption("sel1"));
577     EXPECT_NO_THROW_GMX(assigner.appendValue("resname RC RD"));
578     EXPECT_NO_THROW_GMX(assigner.finishOption());
579     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
580     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
581     EXPECT_NO_THROW_GMX(assigner.finishOption());
582     EXPECT_NO_THROW_GMX(assigner.finish());
583     EXPECT_NO_THROW_GMX(options_.finish());
584
585     // These should match the contents of selfile.dat
586     ASSERT_EQ(2U, sel2.size());
587     EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
588     EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
589     ASSERT_EQ(1U, sel1.size());
590     EXPECT_STREQ("resname RC RD", sel1[0].selectionText());
591 }
592
593
594 TEST_F(SelectionFileOptionTest, HandlesTwoRequiredOptionsFromSingleFile)
595 {
596     gmx::SelectionList sel1;
597     gmx::SelectionList sel2;
598     using gmx::SelectionOption;
599     ASSERT_NO_THROW_GMX(options_.addOption(
600                                 SelectionOption("sel1").storeVector(&sel1).required()));
601     ASSERT_NO_THROW_GMX(options_.addOption(
602                                 SelectionOption("sel2").storeVector(&sel2).required()));
603     setManager();
604
605     gmx::OptionsAssigner assigner(&options_);
606     std::string          value(TestFileManager::getInputFilePath("selfile.dat"));
607     EXPECT_NO_THROW_GMX(assigner.start());
608     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
609     EXPECT_NO_THROW_GMX(assigner.appendValue(value));
610     EXPECT_NO_THROW_GMX(assigner.finishOption());
611     EXPECT_NO_THROW_GMX(assigner.finish());
612     EXPECT_NO_THROW_GMX(options_.finish());
613
614     // These should match the contents of selfile.dat
615     ASSERT_EQ(1U, sel1.size());
616     EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
617     ASSERT_EQ(1U, sel2.size());
618     EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
619 }
620
621
622 TEST_F(SelectionFileOptionTest, GivesErrorWithNoFile)
623 {
624     gmx::SelectionList sel;
625     using gmx::SelectionOption;
626     ASSERT_NO_THROW_GMX(options_.addOption(
627                                 SelectionOption("sel").storeVector(&sel).multiValue()));
628     setManager();
629
630     gmx::OptionsAssigner assigner(&options_);
631     EXPECT_NO_THROW_GMX(assigner.start());
632     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
633     EXPECT_NO_THROW_GMX(assigner.finishOption());
634     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
635     EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
636     EXPECT_NO_THROW_GMX(assigner.finish());
637     EXPECT_NO_THROW_GMX(options_.finish());
638 }
639
640
641 TEST_F(SelectionFileOptionTest, GivesErrorWithNonExistentFile)
642 {
643     gmx::SelectionList sel;
644     using gmx::SelectionOption;
645     ASSERT_NO_THROW_GMX(options_.addOption(
646                                 SelectionOption("sel").storeVector(&sel).multiValue()));
647     setManager();
648
649     gmx::OptionsAssigner assigner(&options_);
650     EXPECT_NO_THROW_GMX(assigner.start());
651     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
652     EXPECT_NO_THROW_GMX(assigner.finishOption());
653     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
654     // TODO: Should this be changed to an InvalidInputError?
655     EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::FileIOError);
656     EXPECT_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")),
657                      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
664 TEST_F(SelectionFileOptionTest, GivesErrorWithMultipleFiles)
665 {
666     gmx::SelectionList sel;
667     using gmx::SelectionOption;
668     ASSERT_NO_THROW_GMX(options_.addOption(
669                                 SelectionOption("sel").storeVector(&sel).multiValue()));
670     setManager();
671
672     gmx::OptionsAssigner assigner(&options_);
673     EXPECT_NO_THROW_GMX(assigner.start());
674     ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
675     EXPECT_NO_THROW_GMX(assigner.finishOption());
676     ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
677     EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
678     EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::InvalidInputError);
679     EXPECT_NO_THROW_GMX(assigner.finishOption());
680     EXPECT_NO_THROW_GMX(assigner.finish());
681     EXPECT_NO_THROW_GMX(options_.finish());
682 }
683
684 } // namespace