1 /*
2 * This file is part of the GROMACS molecular simulation package.
3 *
4 * Copyright (c) 2010-2017, The GROMACS development team.
5 * Copyright (c) 2019, by the GROMACS development team, led by
6 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 * and including many others, as listed in the AUTHORS file in the
8 * top-level source directory and at http://www.gromacs.org.
9 *
10 * GROMACS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
14 *
15 * GROMACS is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with GROMACS; if not, see
22 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 * If you want to redistribute modifications to GROMACS, please
26 * consider that scientific software is very special. Version
27 * control is crucial - bugs must be traceable. We will be happy to
28 * consider code for inclusion in the official distribution, but
29 * derived work must not be called official GROMACS. Details are found
30 * in the README & COPYING files - if they are missing, get the
31 * official version at http://www.gromacs.org.
32 *
33 * To help us fund GROMACS development, we humbly ask that you cite
34 * the research papers on the package. Check out http://www.gromacs.org.
35 */
36 /*! \internal \file
37 * \brief
38 * Tests handling of selection options.
39 *
40 * \author Teemu Murtola <teemu.murtola@gmail.com>
41 * \ingroup module_selection
42 */
43 #include "gmxpre.h"
44
45 #include "gromacs/selection/selectionoption.h"
46
47 #include <gtest/gtest.h>
48
49 #include "gromacs/options/options.h"
50 #include "gromacs/options/optionsassigner.h"
51 #include "gromacs/selection/selection.h"
52 #include "gromacs/selection/selectioncollection.h"
53 #include "gromacs/selection/selectionfileoption.h"
54 #include "gromacs/selection/selectionoptionmanager.h"
55 #include "gromacs/utility/exceptions.h"
56
57 #include "testutils/testasserts.h"
58 #include "testutils/testfilemanager.h"
59
60 #include "toputils.h"
61
62 using gmx::test::TestFileManager;
63
64 namespace
65 {
66
67 /********************************************************************
68 * Base fixture for tests in this file.
69 */
70
71 class SelectionOptionTestBase : public ::testing::Test
72 {
73 public:
74 SelectionOptionTestBase();
75
76 void loadTopology(const char* filename);
77
78 gmx::SelectionCollection sc_;
79 gmx::SelectionOptionManager manager_;
80 gmx::Options options_;
81
82 private:
83 gmx::test::TopologyManager topManager_;
84 };
85
SelectionOptionTestBase()86 SelectionOptionTestBase::SelectionOptionTestBase() : manager_(&sc_)
87 {
88 options_.addManager(&manager_);
89 sc_.setReferencePosType("atom");
90 sc_.setOutputPosType("atom");
91 }
92
loadTopology(const char * filename)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
TEST_F(SelectionOptionTest,ParsesSimpleSelection)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
TEST_F(SelectionOptionTest,HandlesDynamicSelectionWhenStaticRequired)126 TEST_F(SelectionOptionTest, HandlesDynamicSelectionWhenStaticRequired)
127 {
128 gmx::Selection sel;
129 using gmx::SelectionOption;
130 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlyStatic()));
131
132 gmx::OptionsAssigner assigner(&options_);
133 EXPECT_NO_THROW_GMX(assigner.start());
134 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
135 EXPECT_THROW_GMX(assigner.appendValue("resname RA RB and x < 5"), gmx::InvalidInputError);
136 EXPECT_NO_THROW_GMX(assigner.finishOption());
137 EXPECT_NO_THROW_GMX(assigner.finish());
138 EXPECT_NO_THROW_GMX(options_.finish());
139 }
140
141
TEST_F(SelectionOptionTest,HandlesNonAtomicSelectionWhenAtomsRequired)142 TEST_F(SelectionOptionTest, HandlesNonAtomicSelectionWhenAtomsRequired)
143 {
144 gmx::Selection sel;
145 using gmx::SelectionOption;
146 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlyAtoms()));
147
148 gmx::OptionsAssigner assigner(&options_);
149 EXPECT_NO_THROW_GMX(assigner.start());
150 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
151 EXPECT_NO_THROW_GMX(assigner.appendValue("res_cog of resname RA RB"));
152 EXPECT_NO_THROW_GMX(assigner.finishOption());
153 EXPECT_NO_THROW_GMX(assigner.finish());
154 EXPECT_NO_THROW_GMX(options_.finish());
155
156 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
157 EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
158 }
159
160
TEST_F(SelectionOptionTest,ChecksForSortedAtomsWhenRequired)161 TEST_F(SelectionOptionTest, ChecksForSortedAtomsWhenRequired)
162 {
163 gmx::Selection sel;
164 using gmx::SelectionOption;
165 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlySortedAtoms()));
166
167 gmx::OptionsAssigner assigner(&options_);
168 EXPECT_NO_THROW_GMX(assigner.start());
169 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
170 EXPECT_NO_THROW_GMX(assigner.appendValue("resnr 1 2 permute 2 1"));
171 EXPECT_NO_THROW_GMX(assigner.finishOption());
172 EXPECT_NO_THROW_GMX(assigner.finish());
173 EXPECT_NO_THROW_GMX(options_.finish());
174
175 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
176 EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
177 }
178
179
TEST_F(SelectionOptionTest,ChecksEmptySelections)180 TEST_F(SelectionOptionTest, ChecksEmptySelections)
181 {
182 gmx::Selection sel;
183 using gmx::SelectionOption;
184 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
185
186 gmx::OptionsAssigner assigner(&options_);
187 EXPECT_NO_THROW_GMX(assigner.start());
188 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
189 EXPECT_NO_THROW_GMX(assigner.appendValue("none"));
190 EXPECT_NO_THROW_GMX(assigner.finishOption());
191 EXPECT_NO_THROW_GMX(assigner.finish());
192 EXPECT_NO_THROW_GMX(options_.finish());
193
194 EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
195 }
196
197
TEST_F(SelectionOptionTest,ChecksEmptyDelayedSelections)198 TEST_F(SelectionOptionTest, ChecksEmptyDelayedSelections)
199 {
200 gmx::Selection sel;
201 using gmx::SelectionOption;
202 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
203
204 gmx::OptionsAssigner assigner(&options_);
205 EXPECT_NO_THROW_GMX(assigner.start());
206 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
207 EXPECT_NO_THROW_GMX(assigner.finishOption());
208 EXPECT_NO_THROW_GMX(assigner.finish());
209 EXPECT_NO_THROW_GMX(options_.finish());
210 ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("none"));
211
212 EXPECT_THROW_GMX(sc_.compile(), gmx::InvalidInputError);
213 }
214
215
TEST_F(SelectionOptionTest,HandlesTooManySelections)216 TEST_F(SelectionOptionTest, HandlesTooManySelections)
217 {
218 gmx::Selection sel;
219 using gmx::SelectionOption;
220 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
221
222 gmx::OptionsAssigner assigner(&options_);
223 EXPECT_NO_THROW_GMX(assigner.start());
224 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
225 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
226 EXPECT_THROW_GMX(assigner.appendValue("resname RB RC"), gmx::InvalidInputError);
227 EXPECT_NO_THROW_GMX(assigner.finishOption());
228 EXPECT_NO_THROW_GMX(assigner.finish());
229 EXPECT_NO_THROW_GMX(options_.finish());
230 }
231
232
TEST_F(SelectionOptionTest,HandlesTooFewSelections)233 TEST_F(SelectionOptionTest, HandlesTooFewSelections)
234 {
235 gmx::Selection sel[2];
236 using gmx::SelectionOption;
237 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(sel).valueCount(2)));
238
239 gmx::OptionsAssigner assigner(&options_);
240 EXPECT_NO_THROW_GMX(assigner.start());
241 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
242 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
243 EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
244 EXPECT_NO_THROW_GMX(assigner.finish());
245 EXPECT_NO_THROW_GMX(options_.finish());
246 }
247
248
TEST_F(SelectionOptionTest,HandlesDefaultSelectionText)249 TEST_F(SelectionOptionTest, HandlesDefaultSelectionText)
250 {
251 gmx::Selection sel;
252 using gmx::SelectionOption;
253 options_.addOption(SelectionOption("sel").store(&sel).defaultSelectionText("all"));
254
255 EXPECT_NO_THROW_GMX(options_.finish());
256
257 ASSERT_TRUE(sel.isValid());
258
259 EXPECT_NO_THROW_GMX(sc_.setTopology(nullptr, 10));
260 EXPECT_NO_THROW_GMX(sc_.compile());
261
262 EXPECT_STREQ("all", sel.selectionText());
263 }
264
265
TEST_F(SelectionOptionTest,HandlesAdjuster)266 TEST_F(SelectionOptionTest, HandlesAdjuster)
267 {
268 gmx::SelectionList sel;
269 using gmx::SelectionOption;
270 gmx::SelectionOptionInfo* info =
271 options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue());
272
273 gmx::OptionsAssigner assigner(&options_);
274 EXPECT_NO_THROW_GMX(assigner.start());
275 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
276 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
277 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RB RC"));
278 EXPECT_NO_THROW_GMX(assigner.finishOption());
279 EXPECT_NO_THROW_GMX(assigner.finish());
280 EXPECT_NO_THROW_GMX(options_.finish());
281 EXPECT_NO_THROW_GMX(info->setValueCount(2));
282 }
283
284
TEST_F(SelectionOptionTest,HandlesDynamicWhenStaticRequiredWithAdjuster)285 TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster)
286 {
287 gmx::Selection sel;
288 using gmx::SelectionOption;
289 gmx::SelectionOptionInfo* info = options_.addOption(SelectionOption("sel").store(&sel));
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
TEST_F(SelectionOptionTest,HandlesTooManySelectionsWithAdjuster)302 TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster)
303 {
304 gmx::SelectionList sel;
305 using gmx::SelectionOption;
306 gmx::SelectionOptionInfo* info =
307 options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue());
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.appendValue("resname RB RC"));
314 EXPECT_NO_THROW_GMX(assigner.finishOption());
315 EXPECT_NO_THROW_GMX(assigner.finish());
316 EXPECT_NO_THROW_GMX(options_.finish());
317 EXPECT_THROW_GMX(info->setValueCount(1), gmx::InvalidInputError);
318 }
319
320
TEST_F(SelectionOptionTest,HandlesTooFewSelectionsWithAdjuster)321 TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster)
322 {
323 gmx::SelectionList sel;
324 using gmx::SelectionOption;
325 gmx::SelectionOptionInfo* info =
326 options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue());
327
328 gmx::OptionsAssigner assigner(&options_);
329 EXPECT_NO_THROW_GMX(assigner.start());
330 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
331 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RA RB"));
332 EXPECT_NO_THROW_GMX(assigner.finishOption());
333 EXPECT_NO_THROW_GMX(assigner.finish());
334 EXPECT_NO_THROW_GMX(options_.finish());
335 EXPECT_THROW_GMX(info->setValueCount(2), gmx::InvalidInputError);
336 }
337
338
TEST_F(SelectionOptionTest,HandlesDelayedRequiredSelection)339 TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection)
340 {
341 gmx::Selection sel;
342 using gmx::SelectionOption;
343 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).required()));
344
345 gmx::OptionsAssigner assigner(&options_);
346 EXPECT_NO_THROW_GMX(assigner.start());
347 EXPECT_NO_THROW_GMX(assigner.finish());
348 EXPECT_NO_THROW_GMX(options_.finish());
349 ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
350 ASSERT_STREQ("resname RA RB", sel.selectionText());
351 }
352
353
TEST_F(SelectionOptionTest,HandlesTooFewDelayedRequiredSelections)354 TEST_F(SelectionOptionTest, HandlesTooFewDelayedRequiredSelections)
355 {
356 gmx::Selection sel[2];
357 using gmx::SelectionOption;
358 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(sel).required().valueCount(2)));
359
360 gmx::OptionsAssigner assigner(&options_);
361 EXPECT_NO_THROW_GMX(assigner.start());
362 EXPECT_NO_THROW_GMX(assigner.finish());
363 EXPECT_NO_THROW_GMX(options_.finish());
364 EXPECT_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"), gmx::InvalidInputError);
365 }
366
367
TEST_F(SelectionOptionTest,HandlesDelayedOptionalSelection)368 TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection)
369 {
370 gmx::Selection sel;
371 using gmx::SelectionOption;
372 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
373
374 gmx::OptionsAssigner assigner(&options_);
375 EXPECT_NO_THROW_GMX(assigner.start());
376 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
377 EXPECT_NO_THROW_GMX(assigner.finishOption());
378 EXPECT_NO_THROW_GMX(assigner.finish());
379 EXPECT_NO_THROW_GMX(options_.finish());
380 ASSERT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB"));
381 ASSERT_STREQ("resname RA RB", sel.selectionText());
382 }
383
384
TEST_F(SelectionOptionTest,HandlesDelayedSelectionWithAdjuster)385 TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster)
386 {
387 gmx::SelectionList sel;
388 using gmx::SelectionOption;
389 gmx::SelectionOptionInfo* info =
390 options_.addOption(SelectionOption("sel").storeVector(&sel).valueCount(3));
391
392 gmx::OptionsAssigner assigner(&options_);
393 EXPECT_NO_THROW_GMX(assigner.start());
394 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
395 EXPECT_NO_THROW_GMX(assigner.finishOption());
396 EXPECT_NO_THROW_GMX(assigner.finish());
397 EXPECT_NO_THROW_GMX(options_.finish());
398 EXPECT_NO_THROW_GMX(info->setValueCount(2));
399 EXPECT_NO_THROW_GMX(manager_.parseRequestedFromString("resname RA RB; resname RB RC"));
400 }
401
402
403 /********************************************************************
404 * Tests for SelectionFileOption
405 */
406
407 class SelectionFileOptionTest : public SelectionOptionTestBase
408 {
409 public:
410 SelectionFileOptionTest();
411 };
412
SelectionFileOptionTest()413 SelectionFileOptionTest::SelectionFileOptionTest()
414 {
415 options_.addOption(gmx::SelectionFileOption("sf"));
416 }
417
418
TEST_F(SelectionFileOptionTest,HandlesSingleSelectionOptionFromFile)419 TEST_F(SelectionFileOptionTest, HandlesSingleSelectionOptionFromFile)
420 {
421 gmx::SelectionList sel;
422 gmx::SelectionList reqsel;
423 using gmx::SelectionOption;
424 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()));
425 ASSERT_NO_THROW_GMX(
426 options_.addOption(SelectionOption("reqsel").storeVector(&reqsel).multiValue().required()));
427
428 gmx::OptionsAssigner assigner(&options_);
429 EXPECT_NO_THROW_GMX(assigner.start());
430 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
431 EXPECT_NO_THROW_GMX(assigner.finishOption());
432 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
433 EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
434 EXPECT_NO_THROW_GMX(assigner.finishOption());
435 EXPECT_NO_THROW_GMX(assigner.finish());
436 EXPECT_NO_THROW_GMX(options_.finish());
437
438 // These should match the contents of selfile.dat
439 ASSERT_EQ(2U, sel.size());
440 EXPECT_STREQ("resname RA RB", sel[0].selectionText());
441 EXPECT_STREQ("resname RB RC", sel[1].selectionText());
442 ASSERT_EQ(0U, reqsel.size());
443 }
444
445
TEST_F(SelectionFileOptionTest,HandlesTwoSeparateSelectionOptions)446 TEST_F(SelectionFileOptionTest, HandlesTwoSeparateSelectionOptions)
447 {
448 gmx::SelectionList sel1;
449 gmx::SelectionList sel2;
450 using gmx::SelectionOption;
451 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1).multiValue()));
452 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2).multiValue()));
453
454 gmx::OptionsAssigner assigner(&options_);
455 std::string value(TestFileManager::getInputFilePath("selfile.dat"));
456 EXPECT_NO_THROW_GMX(assigner.start());
457 ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
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 ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
463 EXPECT_NO_THROW_GMX(assigner.finishOption());
464 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
465 EXPECT_NO_THROW_GMX(assigner.appendValue(value));
466 EXPECT_NO_THROW_GMX(assigner.finishOption());
467 EXPECT_NO_THROW_GMX(assigner.finish());
468 EXPECT_NO_THROW_GMX(options_.finish());
469
470 // These should match the contents of selfile.dat
471 ASSERT_EQ(2U, sel1.size());
472 EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
473 EXPECT_STREQ("resname RB RC", sel1[1].selectionText());
474 ASSERT_EQ(2U, sel2.size());
475 EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
476 EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
477 }
478
479
TEST_F(SelectionFileOptionTest,HandlesTwoSelectionOptionsFromSingleFile)480 TEST_F(SelectionFileOptionTest, HandlesTwoSelectionOptionsFromSingleFile)
481 {
482 gmx::SelectionList sel1;
483 gmx::SelectionList sel2;
484 using gmx::SelectionOption;
485 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1)));
486 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2)));
487
488 gmx::OptionsAssigner assigner(&options_);
489 std::string value(TestFileManager::getInputFilePath("selfile.dat"));
490 EXPECT_NO_THROW_GMX(assigner.start());
491 ASSERT_NO_THROW_GMX(assigner.startOption("sel1"));
492 EXPECT_NO_THROW_GMX(assigner.finishOption());
493 ASSERT_NO_THROW_GMX(assigner.startOption("sel2"));
494 EXPECT_NO_THROW_GMX(assigner.finishOption());
495 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
496 EXPECT_NO_THROW_GMX(assigner.appendValue(value));
497 EXPECT_NO_THROW_GMX(assigner.finishOption());
498 EXPECT_NO_THROW_GMX(assigner.finish());
499 EXPECT_NO_THROW_GMX(options_.finish());
500
501 // These should match the contents of selfile.dat
502 ASSERT_EQ(1U, sel1.size());
503 EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
504 ASSERT_EQ(1U, sel2.size());
505 EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
506 }
507
508
TEST_F(SelectionFileOptionTest,HandlesRequiredOptionFromFile)509 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFile)
510 {
511 gmx::SelectionList sel;
512 gmx::SelectionList optsel;
513 using gmx::SelectionOption;
514 ASSERT_NO_THROW_GMX(
515 options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue().required()));
516 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("optsel").storeVector(&optsel).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?
TEST_F(SelectionFileOptionTest,HandlesRequiredOptionFromFileWithOtherOptionSet)539 TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFileWithOtherOptionSet)
540 {
541 gmx::SelectionList sel1;
542 gmx::SelectionList sel2;
543 using gmx::SelectionOption;
544 ASSERT_NO_THROW_GMX(
545 options_.addOption(SelectionOption("sel1").storeVector(&sel1).multiValue().required()));
546 ASSERT_NO_THROW_GMX(
547 options_.addOption(SelectionOption("sel2").storeVector(&sel2).multiValue().required()));
548
549 gmx::OptionsAssigner assigner(&options_);
550 EXPECT_NO_THROW_GMX(assigner.start());
551 EXPECT_NO_THROW_GMX(assigner.startOption("sel1"));
552 EXPECT_NO_THROW_GMX(assigner.appendValue("resname RC RD"));
553 EXPECT_NO_THROW_GMX(assigner.finishOption());
554 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
555 EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
556 EXPECT_NO_THROW_GMX(assigner.finishOption());
557 EXPECT_NO_THROW_GMX(assigner.finish());
558 EXPECT_NO_THROW_GMX(options_.finish());
559
560 // These should match the contents of selfile.dat
561 ASSERT_EQ(2U, sel2.size());
562 EXPECT_STREQ("resname RA RB", sel2[0].selectionText());
563 EXPECT_STREQ("resname RB RC", sel2[1].selectionText());
564 ASSERT_EQ(1U, sel1.size());
565 EXPECT_STREQ("resname RC RD", sel1[0].selectionText());
566 }
567
568
TEST_F(SelectionFileOptionTest,HandlesTwoRequiredOptionsFromSingleFile)569 TEST_F(SelectionFileOptionTest, HandlesTwoRequiredOptionsFromSingleFile)
570 {
571 gmx::SelectionList sel1;
572 gmx::SelectionList sel2;
573 using gmx::SelectionOption;
574 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1).required()));
575 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2).required()));
576
577 gmx::OptionsAssigner assigner(&options_);
578 std::string value(TestFileManager::getInputFilePath("selfile.dat"));
579 EXPECT_NO_THROW_GMX(assigner.start());
580 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
581 EXPECT_NO_THROW_GMX(assigner.appendValue(value));
582 EXPECT_NO_THROW_GMX(assigner.finishOption());
583 EXPECT_NO_THROW_GMX(assigner.finish());
584 EXPECT_NO_THROW_GMX(options_.finish());
585
586 // These should match the contents of selfile.dat
587 ASSERT_EQ(1U, sel1.size());
588 EXPECT_STREQ("resname RA RB", sel1[0].selectionText());
589 ASSERT_EQ(1U, sel2.size());
590 EXPECT_STREQ("resname RB RC", sel2[0].selectionText());
591 }
592
593
TEST_F(SelectionFileOptionTest,GivesErrorWithNoFile)594 TEST_F(SelectionFileOptionTest, GivesErrorWithNoFile)
595 {
596 gmx::SelectionList sel;
597 using gmx::SelectionOption;
598 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()));
599
600 gmx::OptionsAssigner assigner(&options_);
601 EXPECT_NO_THROW_GMX(assigner.start());
602 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
603 EXPECT_NO_THROW_GMX(assigner.finishOption());
604 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
605 EXPECT_THROW_GMX(assigner.finishOption(), gmx::InvalidInputError);
606 EXPECT_NO_THROW_GMX(assigner.finish());
607 EXPECT_NO_THROW_GMX(options_.finish());
608 }
609
610
TEST_F(SelectionFileOptionTest,GivesErrorWithNonExistentFile)611 TEST_F(SelectionFileOptionTest, GivesErrorWithNonExistentFile)
612 {
613 gmx::SelectionList sel;
614 using gmx::SelectionOption;
615 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()));
616
617 gmx::OptionsAssigner assigner(&options_);
618 EXPECT_NO_THROW_GMX(assigner.start());
619 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
620 EXPECT_NO_THROW_GMX(assigner.finishOption());
621 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
622 // TODO: Should this be changed to an InvalidInputError?
623 EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::FileIOError);
624 EXPECT_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")),
625 gmx::InvalidInputError);
626 EXPECT_NO_THROW_GMX(assigner.finishOption());
627 EXPECT_NO_THROW_GMX(assigner.finish());
628 EXPECT_NO_THROW_GMX(options_.finish());
629 }
630
631
TEST_F(SelectionFileOptionTest,GivesErrorWithMultipleFiles)632 TEST_F(SelectionFileOptionTest, GivesErrorWithMultipleFiles)
633 {
634 gmx::SelectionList sel;
635 using gmx::SelectionOption;
636 ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()));
637
638 gmx::OptionsAssigner assigner(&options_);
639 EXPECT_NO_THROW_GMX(assigner.start());
640 ASSERT_NO_THROW_GMX(assigner.startOption("sel"));
641 EXPECT_NO_THROW_GMX(assigner.finishOption());
642 ASSERT_NO_THROW_GMX(assigner.startOption("sf"));
643 EXPECT_NO_THROW_GMX(assigner.appendValue(TestFileManager::getInputFilePath("selfile.dat")));
644 EXPECT_THROW_GMX(assigner.appendValue("nonexistentfile"), gmx::InvalidInputError);
645 EXPECT_NO_THROW_GMX(assigner.finishOption());
646 EXPECT_NO_THROW_GMX(assigner.finish());
647 EXPECT_NO_THROW_GMX(options_.finish());
648 }
649
650 } // namespace
651