2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Tests selection parsing and compilation.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_selection
44 #include "gromacs/selection/selectioncollection.h"
46 #include <gtest/gtest.h>
48 #include "gromacs/options/basicoptions.h"
49 #include "gromacs/options/ioptionscontainer.h"
50 #include "gromacs/selection/indexutil.h"
51 #include "gromacs/selection/selection.h"
52 #include "gromacs/topology/topology.h"
53 #include "gromacs/trajectory/trajectoryframe.h"
54 #include "gromacs/utility/arrayref.h"
55 #include "gromacs/utility/exceptions.h"
56 #include "gromacs/utility/flags.h"
57 #include "gromacs/utility/gmxregex.h"
58 #include "gromacs/utility/stringutil.h"
60 #include "testutils/interactivetest.h"
61 #include "testutils/refdata.h"
62 #include "testutils/testasserts.h"
63 #include "testutils/testfilemanager.h"
64 #include "testutils/testoptions.h"
71 /********************************************************************
72 * Test fixture for selection testing
75 class SelectionCollectionTest
: public ::testing::Test
78 static int s_debugLevel
;
80 SelectionCollectionTest();
81 ~SelectionCollectionTest();
83 void setAtomCount(int natoms
)
85 ASSERT_NO_THROW_GMX(sc_
.setTopology(NULL
, natoms
));
87 void loadTopology(const char *filename
);
89 void loadIndexGroups(const char *filename
);
91 gmx::test::TopologyManager topManager_
;
92 gmx::SelectionCollection sc_
;
93 gmx::SelectionList sel_
;
94 gmx_ana_indexgrps_t
*grps_
;
97 int SelectionCollectionTest::s_debugLevel
= 0;
99 // cond/endcond do not seem to work here with Doxygen 1.8.5 parser.
101 GMX_TEST_OPTIONS(SelectionCollectionTestOptions
, options
)
103 options
->addOption(gmx::IntegerOption("seldebug")
104 .store(&SelectionCollectionTest::s_debugLevel
)
105 .description("Set selection debug level"));
109 SelectionCollectionTest::SelectionCollectionTest()
112 topManager_
.requestFrame();
113 sc_
.setDebugLevel(s_debugLevel
);
114 sc_
.setReferencePosType("atom");
115 sc_
.setOutputPosType("atom");
118 SelectionCollectionTest::~SelectionCollectionTest()
122 gmx_ana_indexgrps_free(grps_
);
127 SelectionCollectionTest::loadTopology(const char *filename
)
129 topManager_
.loadTopology(filename
);
134 SelectionCollectionTest::setTopology()
136 ASSERT_NO_THROW_GMX(sc_
.setTopology(topManager_
.topology(), -1));
140 SelectionCollectionTest::loadIndexGroups(const char *filename
)
142 GMX_RELEASE_ASSERT(grps_
== NULL
,
143 "External groups can only be loaded once");
144 std::string fullpath
=
145 gmx::test::TestFileManager::getInputFilePath(filename
);
146 gmx_ana_indexgrps_init(&grps_
, NULL
, fullpath
.c_str());
147 sc_
.setIndexGroups(grps_
);
151 /********************************************************************
152 * Test fixture for interactive SelectionCollection tests
155 class SelectionCollectionInteractiveTest
: public SelectionCollectionTest
158 SelectionCollectionInteractiveTest()
159 : helper_(data_
.rootChecker())
163 void runTest(int count
, bool bInteractive
,
164 const gmx::ConstArrayRef
<const char *> &input
);
166 gmx::test::TestReferenceData data_
;
167 gmx::test::InteractiveTestHelper helper_
;
170 void SelectionCollectionInteractiveTest::runTest(
171 int count
, bool bInteractive
,
172 const gmx::ConstArrayRef
<const char *> &inputLines
)
174 helper_
.setInputLines(inputLines
);
175 // TODO: Check something about the returned selections as well.
176 ASSERT_NO_THROW_GMX(sc_
.parseInteractive(
177 count
, &helper_
.inputStream(),
178 bInteractive
? &helper_
.outputStream() : NULL
,
179 "for test context"));
180 helper_
.checkSession();
184 /********************************************************************
185 * Test fixture for selection testing with reference data
188 class SelectionCollectionDataTest
: public SelectionCollectionTest
193 efTestEvaluation
= 1<<0,
194 efTestPositionAtoms
= 1<<1,
195 efTestPositionCoordinates
= 1<<2,
196 efTestPositionMapping
= 1<<3,
197 efTestPositionMasses
= 1<<4,
198 efTestPositionCharges
= 1<<5,
199 efTestSelectionNames
= 1<<6,
200 efDontTestCompiledAtoms
= 1<<8
202 typedef gmx::FlagsTemplate
<TestFlag
> TestFlags
;
204 SelectionCollectionDataTest()
205 : checker_(data_
.rootChecker()), count_(0), framenr_(0)
209 void setFlags(TestFlags flags
) { flags_
= flags
; }
211 void runParser(const gmx::ConstArrayRef
<const char *> &selections
);
214 void runEvaluateFinal();
216 void runTest(int natoms
,
217 const gmx::ConstArrayRef
<const char *> &selections
);
218 void runTest(const char *filename
,
219 const gmx::ConstArrayRef
<const char *> &selections
);
222 static void checkSelection(gmx::test::TestReferenceChecker
*checker
,
223 const gmx::Selection
&sel
, TestFlags flags
);
225 void checkCompiled();
227 gmx::test::TestReferenceData data_
;
228 gmx::test::TestReferenceChecker checker_
;
236 SelectionCollectionDataTest::checkSelection(
237 gmx::test::TestReferenceChecker
*checker
,
238 const gmx::Selection
&sel
, TestFlags flags
)
240 using gmx::test::TestReferenceChecker
;
243 gmx::ConstArrayRef
<int> atoms
= sel
.atomIndices();
244 checker
->checkSequence(atoms
.begin(), atoms
.end(), "Atoms");
246 if (flags
.test(efTestPositionAtoms
)
247 || flags
.test(efTestPositionCoordinates
)
248 || flags
.test(efTestPositionMapping
)
249 || flags
.test(efTestPositionMasses
)
250 || flags
.test(efTestPositionCharges
))
252 TestReferenceChecker
compound(
253 checker
->checkSequenceCompound("Positions", sel
.posCount()));
254 for (int i
= 0; i
< sel
.posCount(); ++i
)
256 TestReferenceChecker
poscompound(compound
.checkCompound("Position", NULL
));
257 const gmx::SelectionPosition
&p
= sel
.position(i
);
258 if (flags
.test(efTestPositionAtoms
))
260 gmx::ConstArrayRef
<int> atoms
= p
.atomIndices();
261 poscompound
.checkSequence(atoms
.begin(), atoms
.end(), "Atoms");
263 if (flags
.test(efTestPositionCoordinates
))
265 poscompound
.checkVector(p
.x(), "Coordinates");
267 if (flags
.test(efTestPositionMapping
))
269 poscompound
.checkInteger(p
.refId(), "RefId");
270 poscompound
.checkInteger(p
.mappedId(), "MappedId");
272 if (flags
.test(efTestPositionMasses
))
274 poscompound
.checkReal(p
.mass(), "Mass");
276 if (flags
.test(efTestPositionCharges
))
278 poscompound
.checkReal(p
.charge(), "Charge");
286 SelectionCollectionDataTest::runParser(
287 const gmx::ConstArrayRef
<const char *> &selections
)
289 using gmx::test::TestReferenceChecker
;
291 TestReferenceChecker
compound(checker_
.checkCompound("ParsedSelections", "Parsed"));
294 for (size_t i
= 0; i
< selections
.size(); ++i
)
296 SCOPED_TRACE(std::string("Parsing selection \"")
297 + selections
[i
] + "\"");
298 gmx::SelectionList result
;
299 ASSERT_NO_THROW_GMX(result
= sc_
.parseFromString(selections
[i
]));
300 sel_
.insert(sel_
.end(), result
.begin(), result
.end());
301 if (sel_
.size() == count_
)
303 std::string id
= gmx::formatString("Variable%d", static_cast<int>(varcount
+ 1));
304 TestReferenceChecker
varcompound(
305 compound
.checkCompound("ParsedVariable", id
.c_str()));
306 varcompound
.checkString(selections
[i
], "Input");
311 std::string id
= gmx::formatString("Selection%d", static_cast<int>(count_
+ 1));
312 TestReferenceChecker
selcompound(
313 compound
.checkCompound("ParsedSelection", id
.c_str()));
314 selcompound
.checkString(selections
[i
], "Input");
315 if (flags_
.test(efTestSelectionNames
))
317 selcompound
.checkString(sel_
[count_
].name(), "Name");
319 selcompound
.checkString(sel_
[count_
].selectionText(), "Text");
320 selcompound
.checkBoolean(sel_
[count_
].isDynamic(), "Dynamic");
328 SelectionCollectionDataTest::runCompiler()
330 ASSERT_NO_THROW_GMX(sc_
.compile());
331 ASSERT_EQ(count_
, sel_
.size());
337 SelectionCollectionDataTest::checkCompiled()
339 using gmx::test::TestReferenceChecker
;
340 const TestFlags mask
= ~TestFlags(efTestPositionCoordinates
);
342 TestReferenceChecker
compound(checker_
.checkCompound("CompiledSelections", "Compiled"));
343 for (size_t i
= 0; i
< count_
; ++i
)
345 SCOPED_TRACE(std::string("Checking selection \"") +
346 sel_
[i
].selectionText() + "\"");
347 std::string id
= gmx::formatString("Selection%d", static_cast<int>(i
+ 1));
348 TestReferenceChecker
selcompound(
349 compound
.checkCompound("Selection", id
.c_str()));
350 if (flags_
.test(efTestSelectionNames
))
352 selcompound
.checkString(sel_
[i
].name(), "Name");
354 if (!flags_
.test(efDontTestCompiledAtoms
))
356 checkSelection(&selcompound
, sel_
[i
], flags_
& mask
);
363 SelectionCollectionDataTest::runEvaluate()
365 using gmx::test::TestReferenceChecker
;
368 ASSERT_NO_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
));
369 std::string frame
= gmx::formatString("Frame%d", framenr_
);
370 TestReferenceChecker
compound(
371 checker_
.checkCompound("EvaluatedSelections", frame
.c_str()));
372 for (size_t i
= 0; i
< count_
; ++i
)
374 SCOPED_TRACE(std::string("Checking selection \"") +
375 sel_
[i
].selectionText() + "\"");
376 std::string id
= gmx::formatString("Selection%d", static_cast<int>(i
+ 1));
377 TestReferenceChecker
selcompound(
378 compound
.checkCompound("Selection", id
.c_str()));
379 checkSelection(&selcompound
, sel_
[i
], flags_
);
385 SelectionCollectionDataTest::runEvaluateFinal()
387 ASSERT_NO_THROW_GMX(sc_
.evaluateFinal(framenr_
));
393 SelectionCollectionDataTest::runTest(
394 int natoms
, const gmx::ConstArrayRef
<const char *> &selections
)
396 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
397 ASSERT_NO_FATAL_FAILURE(setAtomCount(natoms
));
398 ASSERT_NO_FATAL_FAILURE(runCompiler());
403 SelectionCollectionDataTest::runTest(
404 const char *filename
, const gmx::ConstArrayRef
<const char *> &selections
)
406 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
407 ASSERT_NO_FATAL_FAILURE(loadTopology(filename
));
408 ASSERT_NO_FATAL_FAILURE(runCompiler());
409 if (flags_
.test(efTestEvaluation
))
411 ASSERT_NO_FATAL_FAILURE(runEvaluate());
412 ASSERT_NO_FATAL_FAILURE(runEvaluateFinal());
417 /********************************************************************
418 * Tests for SelectionCollection functionality without reference data
421 TEST_F(SelectionCollectionTest
, HandlesNoSelections
)
423 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
424 EXPECT_NO_THROW_GMX(sc_
.compile());
425 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
428 TEST_F(SelectionCollectionTest
, HandlesNoSelectionsWithDefaultPositionType
)
430 EXPECT_NO_THROW_GMX(sc_
.setOutputPosType("res_com"));
431 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsTopology
);
432 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsMasses
);
433 EXPECT_NO_THROW_GMX(sc_
.setOutputPosType("res_cog"));
434 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsTopology
);
435 EXPECT_FALSE(sc_
.requiredTopologyProperties().needsMasses
);
436 ASSERT_NO_THROW_GMX(sc_
.parseFromString("atom of atomnr 1 to 10"));
437 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
438 ASSERT_NO_THROW_GMX(sc_
.compile());
439 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
442 TEST_F(SelectionCollectionTest
, HandlesVelocityAndForceRequests
)
444 ASSERT_NO_THROW_GMX(sel_
= sc_
.parseFromString("atomnr 1 to 10; none"));
445 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
446 ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
447 ASSERT_EQ(2U, sel_
.size());
448 ASSERT_NO_THROW_GMX(sel_
[0].setEvaluateVelocities(true));
449 ASSERT_NO_THROW_GMX(sel_
[1].setEvaluateVelocities(true));
450 ASSERT_NO_THROW_GMX(sel_
[0].setEvaluateForces(true));
451 ASSERT_NO_THROW_GMX(sel_
[1].setEvaluateForces(true));
452 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
453 ASSERT_NO_THROW_GMX(sc_
.compile());
454 EXPECT_FALSE(sc_
.requiredTopologyProperties().hasAny());
455 EXPECT_TRUE(sel_
[0].hasVelocities());
456 EXPECT_TRUE(sel_
[1].hasVelocities());
457 EXPECT_TRUE(sel_
[0].hasForces());
458 EXPECT_TRUE(sel_
[1].hasForces());
461 TEST_F(SelectionCollectionTest
, HandlesForceRequestForCenterOfGeometry
)
463 ASSERT_NO_THROW_GMX(sel_
= sc_
.parseFromString("res_cog of atomnr 1 to 10"));
464 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsTopology
);
465 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
466 ASSERT_EQ(1U, sel_
.size());
467 ASSERT_NO_THROW_GMX(sel_
[0].setEvaluateForces(true));
468 // In principle, the code could know here that the masses are required, but
469 // currently it only knows this after compilation.
470 ASSERT_NO_THROW_GMX(sc_
.compile());
471 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsMasses
);
472 EXPECT_TRUE(sel_
[0].hasForces());
475 TEST_F(SelectionCollectionTest
, ParsesSelectionsFromFile
)
477 ASSERT_NO_THROW_GMX(sel_
= sc_
.parseFromFile(
478 gmx::test::TestFileManager::getInputFilePath("selfile.dat")));
479 // These should match the contents of selfile.dat
480 ASSERT_EQ(2U, sel_
.size());
481 EXPECT_STREQ("resname RA RB", sel_
[0].selectionText());
482 EXPECT_STREQ("resname RB RC", sel_
[1].selectionText());
485 TEST_F(SelectionCollectionTest
, HandlesAtypicalWhitespace
)
487 ASSERT_NO_THROW_GMX(sel_
= sc_
.parseFromString("atomnr\n1\r\nto\t10;\vatomnr 3\f to 14\r"));
488 ASSERT_EQ(2U, sel_
.size());
489 EXPECT_STREQ("atomnr 1 to 10", sel_
[0].selectionText());
490 // TODO: Get rid of the trailing whitespace.
491 EXPECT_STREQ("atomnr 3 to 14 ", sel_
[1].selectionText());
494 TEST_F(SelectionCollectionTest
, HandlesInvalidRegularExpressions
)
496 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
498 sc_
.parseFromString("resname ~ \"R[A\"");
500 }, gmx::InvalidInputError
);
503 TEST_F(SelectionCollectionTest
, HandlesUnsupportedRegularExpressions
)
505 if (!gmx::Regex::isSupported())
507 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
509 sc_
.parseFromString("resname \"R[AD]\"");
511 }, gmx::InvalidInputError
);
515 TEST_F(SelectionCollectionTest
, HandlesMissingMethodParamValue
)
517 EXPECT_THROW_GMX(sc_
.parseFromString("mindist from atomnr 1 cutoff"),
518 gmx::InvalidInputError
);
521 TEST_F(SelectionCollectionTest
, HandlesMissingMethodParamValue2
)
523 EXPECT_THROW_GMX(sc_
.parseFromString("within 1 of"),
524 gmx::InvalidInputError
);
527 TEST_F(SelectionCollectionTest
, HandlesMissingMethodParamValue3
)
529 EXPECT_THROW_GMX(sc_
.parseFromString("within of atomnr 1"),
530 gmx::InvalidInputError
);
533 // TODO: Tests for more parser errors
535 TEST_F(SelectionCollectionTest
, HandlesUnknownGroupReferenceParser1
)
537 ASSERT_NO_THROW_GMX(sc_
.setIndexGroups(NULL
));
538 EXPECT_THROW_GMX(sc_
.parseFromString("group \"foo\""), gmx::InconsistentInputError
);
539 EXPECT_THROW_GMX(sc_
.parseFromString("4"), gmx::InconsistentInputError
);
542 TEST_F(SelectionCollectionTest
, HandlesUnknownGroupReferenceParser2
)
544 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
545 EXPECT_THROW_GMX(sc_
.parseFromString("group \"foo\""), gmx::InconsistentInputError
);
546 EXPECT_THROW_GMX(sc_
.parseFromString("4"), gmx::InconsistentInputError
);
549 TEST_F(SelectionCollectionTest
, HandlesUnknownGroupReferenceDelayed1
)
551 ASSERT_NO_THROW_GMX(sc_
.parseFromString("group \"foo\""));
552 ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
553 EXPECT_THROW_GMX(sc_
.setIndexGroups(NULL
), gmx::InconsistentInputError
);
554 EXPECT_THROW_GMX(sc_
.compile(), gmx::APIError
);
557 TEST_F(SelectionCollectionTest
, HandlesUnknownGroupReferenceDelayed2
)
559 ASSERT_NO_THROW_GMX(sc_
.parseFromString("group 4; group \"foo\""));
560 ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
561 EXPECT_THROW_GMX(loadIndexGroups("simple.ndx"), gmx::InconsistentInputError
);
562 EXPECT_THROW_GMX(sc_
.compile(), gmx::APIError
);
565 TEST_F(SelectionCollectionTest
, HandlesUnsortedGroupReference
)
567 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
568 EXPECT_THROW_GMX(sc_
.parseFromString("atomnr 1 to 3 and group \"GrpUnsorted\""),
569 gmx::InconsistentInputError
);
570 EXPECT_THROW_GMX(sc_
.parseFromString("group 2 or atomnr 2 to 5"),
571 gmx::InconsistentInputError
);
572 EXPECT_THROW_GMX(sc_
.parseFromString("within 1 of group 2"),
573 gmx::InconsistentInputError
);
576 TEST_F(SelectionCollectionTest
, HandlesUnsortedGroupReferenceDelayed
)
578 ASSERT_NO_THROW_GMX(sc_
.parseFromString("atomnr 1 to 3 and group \"GrpUnsorted\""));
579 ASSERT_NO_THROW_GMX(sc_
.parseFromString("atomnr 1 to 3 and group 2"));
580 EXPECT_THROW_GMX(loadIndexGroups("simple.ndx"), gmx::InconsistentInputError
);
581 // TODO: Add a separate check in the selection compiler for a safer API
582 // (makes sense in the future if the compiler needs the information for
583 // other purposes as well).
584 // EXPECT_THROW_GMX(sc_.compile(), gmx::APIError);
587 TEST_F(SelectionCollectionTest
, HandlesOutOfRangeAtomIndexInGroup
)
589 ASSERT_NO_THROW_GMX(sc_
.setTopology(NULL
, 5));
590 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
591 EXPECT_THROW_GMX(sc_
.parseFromString("group \"GrpB\""), gmx::InconsistentInputError
);
594 TEST_F(SelectionCollectionTest
, HandlesOutOfRangeAtomIndexInGroupDelayed
)
596 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
597 ASSERT_NO_THROW_GMX(sc_
.parseFromString("group \"GrpB\""));
598 EXPECT_THROW_GMX(sc_
.setTopology(NULL
, 5), gmx::InconsistentInputError
);
601 TEST_F(SelectionCollectionTest
, HandlesOutOfRangeAtomIndexInGroupDelayed2
)
603 ASSERT_NO_THROW_GMX(sc_
.setTopology(NULL
, 5));
604 ASSERT_NO_THROW_GMX(sc_
.parseFromString("group \"GrpB\""));
605 EXPECT_THROW_GMX(loadIndexGroups("simple.ndx"), gmx::InconsistentInputError
);
608 TEST_F(SelectionCollectionTest
, RecoversFromMissingMoleculeInfo
)
610 ASSERT_NO_THROW_GMX(sc_
.parseFromString("molindex 1 to 5"));
611 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
612 EXPECT_THROW_GMX(sc_
.compile(), gmx::InconsistentInputError
);
615 TEST_F(SelectionCollectionTest
, RecoversFromMissingAtomTypes
)
617 ASSERT_NO_THROW_GMX(sc_
.parseFromString("type CA"));
618 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
619 EXPECT_THROW_GMX(sc_
.compile(), gmx::InconsistentInputError
);
622 TEST_F(SelectionCollectionTest
, RecoversFromMissingPDBInfo
)
624 ASSERT_NO_THROW_GMX(sc_
.parseFromString("altloc A"));
625 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
626 EXPECT_THROW_GMX(sc_
.compile(), gmx::InconsistentInputError
);
629 TEST_F(SelectionCollectionTest
, RecoversFromInvalidPermutation
)
631 ASSERT_NO_THROW_GMX(sc_
.parseFromString("all permute 1 1"));
632 ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
633 EXPECT_THROW_GMX(sc_
.compile(), gmx::InvalidInputError
);
636 TEST_F(SelectionCollectionTest
, RecoversFromInvalidPermutation2
)
638 ASSERT_NO_THROW_GMX(sc_
.parseFromString("all permute 3 2 1"));
639 ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
640 EXPECT_THROW_GMX(sc_
.compile(), gmx::InconsistentInputError
);
643 TEST_F(SelectionCollectionTest
, RecoversFromInvalidPermutation3
)
645 ASSERT_NO_THROW_GMX(sc_
.parseFromString("x < 1.5 permute 3 2 1"));
646 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
647 ASSERT_NO_THROW_GMX(sc_
.compile());
648 EXPECT_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
), gmx::InconsistentInputError
);
651 TEST_F(SelectionCollectionTest
, HandlesFramesWithTooSmallAtomSubsets
)
653 ASSERT_NO_THROW_GMX(sc_
.parseFromString("atomnr 3 to 10"));
654 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
655 ASSERT_NO_THROW_GMX(sc_
.compile());
656 topManager_
.frame()->natoms
= 8;
657 EXPECT_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
), gmx::InconsistentInputError
);
660 TEST_F(SelectionCollectionTest
, HandlesFramesWithTooSmallAtomSubsets2
)
662 const int index
[] = { 1, 2, 3, 9 };
663 ASSERT_NO_THROW_GMX(sc_
.parseFromString("atomnr 3 4 7 10"));
664 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
665 ASSERT_NO_THROW_GMX(sc_
.compile());
666 topManager_
.initFrameIndices(index
);
667 EXPECT_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
), gmx::InconsistentInputError
);
670 TEST_F(SelectionCollectionTest
, HandlesFramesWithTooSmallAtomSubsets3
)
672 const int index
[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11 };
673 // Evaluating the positions will require atoms 1-3, 7-12.
674 ASSERT_NO_THROW_GMX(sc_
.parseFromString("whole_res_cog of atomnr 2 7 11"));
675 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
676 ASSERT_NO_THROW_GMX(sc_
.compile());
677 topManager_
.initFrameIndices(index
);
678 EXPECT_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
), gmx::InconsistentInputError
);
681 TEST_F(SelectionCollectionTest
, HandlesFramesWithTooSmallAtomSubsets4
)
683 ASSERT_NO_THROW_GMX(sc_
.parseFromString("mindistance from atomnr 1 to 5 < 2"));
684 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
685 ASSERT_NO_THROW_GMX(sc_
.compile());
686 topManager_
.frame()->natoms
= 10;
687 EXPECT_THROW_GMX(sc_
.evaluate(topManager_
.frame(), NULL
), gmx::InconsistentInputError
);
690 // TODO: Tests for more evaluation errors
692 /********************************************************************
693 * Tests for interactive selection input
696 TEST_F(SelectionCollectionInteractiveTest
, HandlesBasicInput
)
698 const char *const input
[] = {
701 "\"Name\" resname RC"
703 runTest(-1, true, input
);
706 TEST_F(SelectionCollectionInteractiveTest
, HandlesContinuation
)
708 const char *const input
[] = {
712 runTest(-1, true, input
);
715 TEST_F(SelectionCollectionInteractiveTest
, HandlesSingleSelectionInput
)
717 const char *const input
[] = {
721 runTest(1, true, input
);
724 TEST_F(SelectionCollectionInteractiveTest
, HandlesTwoSelectionInput
)
726 const char *const input
[] = {
730 runTest(2, true, input
);
733 TEST_F(SelectionCollectionInteractiveTest
, HandlesStatusWithGroups
)
735 const char *const input
[] = {
739 loadIndexGroups("simple.ndx");
740 runTest(-1, true, input
);
743 TEST_F(SelectionCollectionInteractiveTest
, HandlesStatusWithExistingSelections
)
745 const char *const input
[] = {
751 ASSERT_NO_THROW_GMX(sc_
.parseFromString("foo = resname RA"));
752 ASSERT_NO_THROW_GMX(sc_
.parseFromString("resname RB"));
753 runTest(-1, true, input
);
756 TEST_F(SelectionCollectionInteractiveTest
, HandlesSingleSelectionInputStatus
)
758 const char *const input
[] = {
763 runTest(1, true, input
);
766 TEST_F(SelectionCollectionInteractiveTest
, HandlesTwoSelectionInputStatus
)
768 const char *const input
[] = {
769 "\"Sel\" resname RA",
773 runTest(2, true, input
);
776 TEST_F(SelectionCollectionInteractiveTest
, HandlesMultiSelectionInputStatus
)
778 const char *const input
[] = {
779 "\"Sel\" resname RA",
780 "\"Sel2\" resname RB",
783 runTest(-1, true, input
);
786 TEST_F(SelectionCollectionInteractiveTest
, HandlesNoFinalNewline
)
788 // TODO: There is an extra prompt printed after the input is finished; it
789 // would be cleaner not to have it, but it's only a cosmetic issue.
790 const char *const input
[] = {
793 helper_
.setLastNewline(false);
794 runTest(-1, true, input
);
797 TEST_F(SelectionCollectionInteractiveTest
, HandlesEmptySelections
)
799 const char *const input
[] = {
805 runTest(-1, true, input
);
808 TEST_F(SelectionCollectionInteractiveTest
, HandlesMultipleSelectionsOnLine
)
810 const char *const input
[] = {
811 "resname RA; resname RB and \\",
814 runTest(2, true, input
);
817 TEST_F(SelectionCollectionInteractiveTest
, HandlesNoninteractiveInput
)
819 const char *const input
[] = {
822 "\"Name\" resname RC"
824 runTest(-1, false, input
);
827 TEST_F(SelectionCollectionInteractiveTest
, HandlesSingleSelectionInputNoninteractively
)
829 const char *const input
[] = {
833 runTest(1, false, input
);
837 /********************************************************************
838 * Tests for selection keywords
841 TEST_F(SelectionCollectionDataTest
, HandlesAllNone
)
843 static const char * const selections
[] = {
847 runTest(10, selections
);
850 TEST_F(SelectionCollectionDataTest
, HandlesAtomnr
)
852 static const char * const selections
[] = {
853 "atomnr 1 to 3 6 to 8",
857 runTest(10, selections
);
860 TEST_F(SelectionCollectionDataTest
, HandlesResnr
)
862 static const char * const selections
[] = {
866 runTest("simple.gro", selections
);
869 TEST_F(SelectionCollectionDataTest
, HandlesResIndex
)
871 static const char * const selections
[] = {
875 runTest("simple.pdb", selections
);
878 TEST_F(SelectionCollectionDataTest
, HandlesMolIndex
)
880 static const char * const selections
[] = {
884 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
885 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
886 topManager_
.initUniformMolecules(3);
887 ASSERT_NO_FATAL_FAILURE(setTopology());
888 ASSERT_NO_FATAL_FAILURE(runCompiler());
891 TEST_F(SelectionCollectionDataTest
, HandlesAtomname
)
893 static const char * const selections
[] = {
897 runTest("simple.gro", selections
);
900 TEST_F(SelectionCollectionDataTest
, HandlesPdbAtomname
)
902 static const char * const selections
[] = {
908 runTest("simple.pdb", selections
);
912 TEST_F(SelectionCollectionDataTest
, HandlesAtomtype
)
914 static const char * const selections
[] = {
917 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
918 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
919 const char *const types
[] = { "CA", "SA", "SB" };
920 topManager_
.initAtomTypes(types
);
921 ASSERT_NO_FATAL_FAILURE(setTopology());
922 ASSERT_NO_FATAL_FAILURE(runCompiler());
925 TEST_F(SelectionCollectionDataTest
, HandlesChain
)
927 static const char * const selections
[] = {
931 runTest("simple.pdb", selections
);
934 TEST_F(SelectionCollectionDataTest
, HandlesMass
)
936 static const char * const selections
[] = {
939 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
940 EXPECT_TRUE(sc_
.requiredTopologyProperties().needsMasses
);
941 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
942 t_atoms
&atoms
= topManager_
.atoms();
943 for (int i
= 0; i
< atoms
.nr
; ++i
)
945 atoms
.atom
[i
].m
= 1.0 + i
;
947 atoms
.haveMass
= TRUE
;
948 ASSERT_NO_FATAL_FAILURE(setTopology());
949 ASSERT_NO_FATAL_FAILURE(runCompiler());
952 TEST_F(SelectionCollectionDataTest
, HandlesCharge
)
954 static const char * const selections
[] = {
957 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
958 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
959 t_atoms
&atoms
= topManager_
.atoms();
960 for (int i
= 0; i
< atoms
.nr
; ++i
)
962 atoms
.atom
[i
].q
= i
/ 10.0;
964 // Ensure exact representation of 0.5 is used, so that the test is
966 atoms
.atom
[5].q
= 0.5;
967 atoms
.haveCharge
= TRUE
;
968 ASSERT_NO_FATAL_FAILURE(setTopology());
969 ASSERT_NO_FATAL_FAILURE(runCompiler());
972 TEST_F(SelectionCollectionDataTest
, HandlesAltLoc
)
974 static const char * const selections
[] = {
978 runTest("simple.pdb", selections
);
981 TEST_F(SelectionCollectionDataTest
, HandlesInsertCode
)
983 static const char * const selections
[] = {
987 runTest("simple.pdb", selections
);
990 TEST_F(SelectionCollectionDataTest
, HandlesOccupancy
)
992 static const char * const selections
[] = {
996 runTest("simple.pdb", selections
);
999 TEST_F(SelectionCollectionDataTest
, HandlesBeta
)
1001 static const char * const selections
[] = {
1005 runTest("simple.pdb", selections
);
1008 TEST_F(SelectionCollectionDataTest
, HandlesResname
)
1010 static const char * const selections
[] = {
1014 runTest("simple.gro", selections
);
1017 TEST_F(SelectionCollectionDataTest
, HandlesCoordinateKeywords
)
1019 static const char * const selections
[] = {
1024 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1025 runTest("simple.gro", selections
);
1029 TEST_F(SelectionCollectionDataTest
, HandlesSameResidue
)
1031 static const char * const selections
[] = {
1032 "same residue as atomnr 1 4 12"
1034 runTest("simple.gro", selections
);
1038 TEST_F(SelectionCollectionDataTest
, HandlesSameResidueName
)
1040 static const char * const selections
[] = {
1041 "same resname as atomnr 1 14"
1043 runTest("simple.gro", selections
);
1047 TEST_F(SelectionCollectionDataTest
, HandlesPositionKeywords
)
1049 static const char * const selections
[] = {
1051 "res_cog of name CB and resnr 1 3",
1052 "whole_res_cog of name CB and resnr 1 3",
1053 "part_res_cog of x < 3",
1054 "dyn_res_cog of x < 3"
1056 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1057 | efTestPositionAtoms
);
1058 runTest("simple.gro", selections
);
1062 TEST_F(SelectionCollectionDataTest
, HandlesDistanceKeyword
)
1064 static const char * const selections
[] = {
1065 "distance from cog of resnr 1 < 2"
1067 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1068 runTest("simple.gro", selections
);
1072 TEST_F(SelectionCollectionDataTest
, HandlesMinDistanceKeyword
)
1074 static const char * const selections
[] = {
1075 "mindistance from resnr 1 < 2"
1077 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1078 runTest("simple.gro", selections
);
1082 TEST_F(SelectionCollectionDataTest
, HandlesWithinKeyword
)
1084 static const char * const selections
[] = {
1085 "within 1 of resnr 2"
1087 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1088 runTest("simple.gro", selections
);
1092 TEST_F(SelectionCollectionDataTest
, HandlesInSolidAngleKeyword
)
1094 // Both of these should evaluate to empty on a correct implementation.
1095 static const char * const selections
[] = {
1096 "resname TP and not insolidangle center cog of resname C span resname R cutoff 20",
1097 "resname TN and insolidangle center cog of resname C span resname R cutoff 20"
1099 setFlags(TestFlags() | efDontTestCompiledAtoms
| efTestEvaluation
);
1100 runTest("sphere.gro", selections
);
1104 TEST_F(SelectionCollectionDataTest
, HandlesPermuteModifier
)
1106 static const char * const selections
[] = {
1107 "all permute 3 1 2",
1108 "res_cog of resnr 1 to 4 permute 2 1",
1109 "name CB S1 and res_cog x < 3 permute 2 1"
1111 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1112 | efTestPositionAtoms
| efTestPositionMapping
);
1113 runTest("simple.gro", selections
);
1117 TEST_F(SelectionCollectionDataTest
, HandlesPlusModifier
)
1119 static const char * const selections
[] = {
1120 "name S2 plus name S1",
1121 "res_cog of resnr 2 plus res_cog of resnr 1 plus res_cog of resnr 3",
1122 "name S1 and y < 3 plus res_cog of x < 2.5"
1124 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1125 | efTestPositionAtoms
| efTestPositionMapping
);
1126 runTest("simple.gro", selections
);
1130 TEST_F(SelectionCollectionDataTest
, HandlesMergeModifier
)
1132 static const char * const selections
[] = {
1133 "name S2 merge name S1",
1134 "resnr 1 2 and name S2 merge resnr 1 2 and name S1 merge res_cog of resnr 1 2",
1135 "name S1 and x < 2.5 merge res_cog of x < 2.5"
1137 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1138 | efTestPositionAtoms
| efTestPositionMapping
);
1139 runTest("simple.gro", selections
);
1143 /********************************************************************
1144 * Tests for generic selection evaluation
1147 TEST_F(SelectionCollectionDataTest
, ComputesMassesAndCharges
)
1149 static const char * const selections
[] = {
1154 setFlags(TestFlags() | efTestEvaluation
| efTestPositionAtoms
1155 | efTestPositionMasses
| efTestPositionCharges
);
1156 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
1157 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
1158 t_atoms
&atoms
= topManager_
.atoms();
1159 for (int i
= 0; i
< atoms
.nr
; ++i
)
1161 atoms
.atom
[i
].m
= 1.0 + i
/ 100.0;
1162 atoms
.atom
[i
].q
= -(1.0 + i
/ 100.0);
1164 atoms
.haveMass
= TRUE
;
1165 atoms
.haveCharge
= TRUE
;
1166 ASSERT_NO_FATAL_FAILURE(setTopology());
1167 ASSERT_NO_FATAL_FAILURE(runCompiler());
1168 ASSERT_NO_FATAL_FAILURE(runEvaluate());
1169 ASSERT_NO_FATAL_FAILURE(runEvaluateFinal());
1172 TEST_F(SelectionCollectionDataTest
, ComputesMassesAndChargesWithoutTopology
)
1174 static const char * const selections
[] = {
1175 "atomnr 1 to 3 8 to 9",
1179 setFlags(TestFlags() | efTestPositionAtoms
1180 | efTestPositionMasses
| efTestPositionCharges
);
1181 runTest(10, selections
);
1184 TEST_F(SelectionCollectionDataTest
, HandlesFramesWithAtomSubsets
)
1186 const int index
[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11 };
1187 const char * const selections
[] = {
1189 "atomnr 1 2 5 11 and y > 2",
1190 "res_cog of atomnr 2 5 11"
1192 setFlags(TestFlags() | efTestEvaluation
| efTestPositionAtoms
);
1193 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
1194 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
1195 ASSERT_NO_FATAL_FAILURE(runCompiler());
1196 topManager_
.initFrameIndices(index
);
1197 ASSERT_NO_FATAL_FAILURE(runEvaluate());
1198 ASSERT_NO_FATAL_FAILURE(runEvaluateFinal());
1202 /********************************************************************
1203 * Tests for selection syntactic constructs
1206 TEST_F(SelectionCollectionDataTest
, HandlesSelectionNames
)
1208 static const char * const selections
[] = {
1209 "\"GroupSelection\" group \"GrpA\"",
1210 "\"DynamicSelection\" x < 5",
1213 setFlags(TestFlags() | efTestSelectionNames
);
1214 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
1215 runTest(10, selections
);
1218 TEST_F(SelectionCollectionDataTest
, HandlesIndexGroupsInSelections
)
1220 static const char * const selections
[] = {
1224 // These test that the name of the group is not too eagerly promoted to
1225 // the name of the selection.
1226 "group \"GrpB\" and resname RB",
1227 "group \"GrpA\" permute 5 3 2 1 4",
1228 "group \"GrpA\" plus group \"GrpB\"",
1229 "res_cog of group \"GrpA\""
1231 setFlags(TestFlags() | efTestSelectionNames
);
1232 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
1233 runTest("simple.gro", selections
);
1236 TEST_F(SelectionCollectionDataTest
, HandlesIndexGroupsInSelectionsDelayed
)
1238 static const char * const selections
[] = {
1242 "group \"GrpB\" and resname RB"
1244 setFlags(TestFlags() | efTestSelectionNames
);
1245 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
1246 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
1247 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
1248 ASSERT_NO_FATAL_FAILURE(runCompiler());
1251 TEST_F(SelectionCollectionDataTest
, HandlesUnsortedIndexGroupsInSelections
)
1253 static const char * const selections
[] = {
1254 "foo = group \"GrpUnsorted\"",
1255 "group \"GrpUnsorted\"",
1258 "res_cog of group \"GrpUnsorted\"",
1259 "group \"GrpUnsorted\" permute 2 1",
1262 setFlags(TestFlags() | efTestPositionAtoms
| efTestPositionMapping
1263 | efTestSelectionNames
);
1264 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
1265 runTest("simple.gro", selections
);
1268 TEST_F(SelectionCollectionDataTest
, HandlesUnsortedIndexGroupsInSelectionsDelayed
)
1270 static const char * const selections
[] = {
1271 "foo = group \"GrpUnsorted\"",
1272 "group \"GrpUnsorted\"",
1275 "res_cog of group \"GrpUnsorted\"",
1276 "group \"GrpUnsorted\" permute 2 1",
1279 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
1280 ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
1281 ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx"));
1282 ASSERT_NO_FATAL_FAILURE(runCompiler());
1286 TEST_F(SelectionCollectionDataTest
, HandlesConstantPositions
)
1288 static const char * const selections
[] = {
1291 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1292 | efTestPositionMapping
);
1293 runTest("simple.gro", selections
);
1297 TEST_F(SelectionCollectionDataTest
, HandlesConstantPositionsWithModifiers
)
1299 static const char * const selections
[] = {
1300 "[0, 0, 0] plus [0, 1, 0]"
1302 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1303 | efTestPositionMapping
);
1304 runTest("simple.gro", selections
);
1308 TEST_F(SelectionCollectionDataTest
, HandlesWithinConstantPositions
)
1310 static const char * const selections
[] = {
1311 "within 1 of [2, 1, 0]"
1313 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1314 runTest("simple.gro", selections
);
1318 TEST_F(SelectionCollectionDataTest
, HandlesOverlappingIntegerRanges
)
1320 static const char * const selections
[] = {
1321 "atomnr 2 to 4 5 to 8",
1322 "atomnr 2 to 5 4 to 7"
1324 ASSERT_NO_FATAL_FAILURE(runTest(10, selections
));
1328 TEST_F(SelectionCollectionDataTest
, HandlesOverlappingRealRanges
)
1330 static const char * const selections
[] = {
1331 "charge {-0.35 to -0.05 0.25 to 0.75}",
1332 "charge {0.05 to -0.3 -0.05 to 0.55}"
1334 ASSERT_NO_FATAL_FAILURE(runParser(selections
));
1335 ASSERT_NO_FATAL_FAILURE(topManager_
.loadTopology("simple.gro"));
1336 t_atoms
&atoms
= topManager_
.atoms();
1337 for (int i
= 0; i
< atoms
.nr
; ++i
)
1339 atoms
.atom
[i
].q
= i
/ 10.0 - 0.5;
1341 atoms
.haveCharge
= TRUE
;
1342 ASSERT_NO_FATAL_FAILURE(setTopology());
1343 ASSERT_NO_FATAL_FAILURE(runCompiler());
1347 TEST_F(SelectionCollectionDataTest
, HandlesForcedStringMatchingMode
)
1349 static const char * const selections
[] = {
1353 runTest("simple.gro", selections
);
1357 TEST_F(SelectionCollectionDataTest
, HandlesWildcardMatching
)
1359 static const char * const selections
[] = {
1363 runTest("simple.gro", selections
);
1367 TEST_F(SelectionCollectionDataTest
, HandlesRegexMatching
)
1369 static const char * const selections
[] = {
1370 "resname \"R[BD]\"",
1371 "resname ~ \"R[BD]\""
1373 if (gmx::Regex::isSupported())
1375 runTest("simple.gro", selections
);
1380 TEST_F(SelectionCollectionDataTest
, HandlesBasicBoolean
)
1382 static const char * const selections
[] = {
1383 "atomnr 1 to 5 and atomnr 2 to 7",
1384 "atomnr 1 to 5 or not atomnr 3 to 8",
1385 "not not atomnr 1 to 5 and atomnr 2 to 6 and not not atomnr 3 to 7",
1386 "atomnr 1 to 5 and (atomnr 2 to 7 and atomnr 3 to 6)",
1387 "x < 5 and atomnr 1 to 5 and y < 3 and atomnr 2 to 4"
1389 runTest(10, selections
);
1393 TEST_F(SelectionCollectionDataTest
, HandlesDynamicAtomValuedParameters
)
1395 static const char * const selections
[] = {
1396 "same residue as (atomnr 3 5 13 or y > 5)",
1397 "(resnr 1 3 5 or x > 10) and same residue as (atomnr 3 5 13 or z > 5)"
1399 setFlags(TestFlags() | efTestEvaluation
);
1400 runTest("simple.gro", selections
);
1404 TEST_F(SelectionCollectionDataTest
, HandlesEmptySelectionWithUnevaluatedExpressions
)
1406 static const char * const selections
[] = {
1408 "none and same resname as resnr 2"
1410 runTest("simple.gro", selections
);
1414 TEST_F(SelectionCollectionDataTest
, HandlesEmptyReferenceForSame
)
1416 static const char * const selections
[] = {
1417 "same residue as none",
1418 "same resname as none"
1420 runTest("simple.gro", selections
);
1424 TEST_F(SelectionCollectionDataTest
, HandlesPositionModifiersForKeywords
)
1426 static const char * const selections
[] = {
1428 "name CB and res_cog y > 2.5"
1430 setFlags(TestFlags() | efTestEvaluation
);
1431 runTest("simple.gro", selections
);
1435 TEST_F(SelectionCollectionDataTest
, HandlesPositionModifiersForMethods
)
1437 static const char * const selections
[] = {
1438 "res_cog distance from cog of resnr 1 < 2",
1439 "res_cog within 2 of cog of resnr 1"
1441 setFlags(TestFlags() | efTestEvaluation
);
1442 runTest("simple.gro", selections
);
1446 TEST_F(SelectionCollectionDataTest
, HandlesKeywordOfPositions
)
1448 static const char * const selections
[] = {
1449 "x < y of cog of resnr 2"
1451 setFlags(TestFlags() | efTestEvaluation
);
1452 runTest("simple.gro", selections
);
1455 TEST_F(SelectionCollectionDataTest
, HandlesKeywordOfPositionsInArithmetic
)
1457 static const char * const selections
[] = {
1458 "x - y of cog of resnr 2 < 0"
1460 setFlags(TestFlags() | efTestEvaluation
);
1461 runTest("simple.gro", selections
);
1465 TEST_F(SelectionCollectionDataTest
, HandlesNumericComparisons
)
1467 static const char * const selections
[] = {
1474 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1475 runTest("simple.gro", selections
);
1479 TEST_F(SelectionCollectionDataTest
, HandlesArithmeticExpressions
)
1481 static const char * const selections
[] = {
1487 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1488 runTest("simple.gro", selections
);
1492 TEST_F(SelectionCollectionDataTest
, HandlesNumericVariables
)
1494 static const char * const selections
[] = {
1500 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1501 runTest("simple.gro", selections
);
1505 TEST_F(SelectionCollectionDataTest
, HandlesComplexNumericVariables
)
1507 static const char * const selections
[] = {
1509 "resname RA and value <= 4",
1510 "resname RA RB and x < 3 and value <= 4",
1512 "resname RA and index < 3",
1513 "resname RB and y < 3 and index < 6"
1515 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1516 runTest("simple.gro", selections
);
1520 TEST_F(SelectionCollectionDataTest
, HandlesPositionVariables
)
1522 static const char * const selections
[] = {
1523 "foo = res_cog of resname RA",
1526 "bar = cog of resname RA",
1530 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1531 runTest("simple.gro", selections
);
1535 TEST_F(SelectionCollectionDataTest
, HandlesConstantPositionInVariable
)
1537 static const char * const selections
[] = {
1538 "constpos = [1.0, 2.5, 0.5]",
1540 "within 2 of constpos"
1542 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
1543 | efTestPositionAtoms
);
1544 runTest("simple.gro", selections
);
1548 TEST_F(SelectionCollectionDataTest
, HandlesNumericConstantsInVariables
)
1550 static const char * const selections
[] = {
1555 "x + constreal1 < constreal2"
1557 setFlags(TestFlags() | efTestEvaluation
| efTestPositionCoordinates
);
1558 runTest("simple.gro", selections
);
1562 /********************************************************************
1563 * Tests for complex boolean syntax
1566 TEST_F(SelectionCollectionDataTest
, HandlesBooleanStaticAnalysis
)
1568 static const char * const selections
[] = {
1569 "atomnr 1 to 5 and atomnr 2 to 7 and x < 2",
1570 "atomnr 1 to 5 and (atomnr 4 to 7 or x < 2)",
1571 "atomnr 1 to 5 and y < 3 and (atomnr 4 to 7 or x < 2)",
1572 "atomnr 1 to 5 and not (atomnr 4 to 7 or x < 2)",
1573 "atomnr 1 to 5 or (atomnr 4 to 6 and (atomnr 5 to 7 or x < 2))"
1575 runTest(10, selections
);
1579 TEST_F(SelectionCollectionDataTest
, HandlesBooleanStaticAnalysisWithVariables
)
1581 static const char * const selections
[] = {
1582 "foo = atomnr 4 to 7 or x < 2",
1583 "atomnr 1 to 4 and foo",
1584 "atomnr 2 to 6 and y < 3 and foo",
1585 "atomnr 6 to 10 and not foo"
1587 runTest(10, selections
);
1591 TEST_F(SelectionCollectionDataTest
, HandlesBooleanStaticAnalysisWithMoreVariables
)
1593 static const char * const selections
[] = {
1594 "foo = atomnr 4 to 7",
1595 "bar = foo and x < 2",
1596 "bar2 = foo and y < 2",
1597 "atomnr 1 to 4 and bar",
1598 "atomnr 2 to 6 and y < 3 and bar2",
1599 "atomnr 6 to 10 and not foo"
1601 runTest(10, selections
);
1605 /********************************************************************
1606 * Tests for complex subexpression cases
1608 * These tests use some knowledge of the implementation to trigger different
1609 * paths in the code.
1612 TEST_F(SelectionCollectionDataTest
, HandlesUnusedVariables
)
1614 static const char * const selections
[] = {
1615 "unused1 = atomnr 1 to 3",
1616 "foo = atomnr 4 to 7",
1617 "atomnr 1 to 6 and foo",
1618 "unused2 = atomnr 3 to 5"
1620 runTest(10, selections
);
1624 TEST_F(SelectionCollectionDataTest
, HandlesVariablesWithStaticEvaluationGroups
)
1626 static const char * const selections
[] = {
1627 "foo = atomnr 4 to 7 and x < 2",
1628 "atomnr 1 to 5 and foo",
1629 "atomnr 3 to 7 and foo"
1631 runTest(10, selections
);
1635 TEST_F(SelectionCollectionDataTest
, HandlesVariablesWithMixedEvaluationGroups
)
1637 static const char * const selections
[] = {
1638 "foo = atomnr 4 to 7 and x < 2",
1639 "atomnr 1 to 6 and foo",
1643 runTest(10, selections
);
1647 TEST_F(SelectionCollectionDataTest
, HandlesVariablesWithMixedEvaluationGroups2
)
1649 static const char * const selections
[] = {
1650 "foo = atomnr 1 to 8 and x < 10",
1651 "atomnr 1 to 5 and y < 10 and foo",
1654 setFlags(TestFlags() | efTestEvaluation
);
1655 runTest("simple.gro", selections
);