2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 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 * Implements classes and functions from refdata.h.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_testutils
53 #include <gtest/gtest.h>
55 #include "gromacs/options/basicoptions.h"
56 #include "gromacs/options/ioptionscontainer.h"
57 #include "gromacs/utility/exceptions.h"
58 #include "gromacs/utility/gmxassert.h"
59 #include "gromacs/utility/path.h"
60 #include "gromacs/utility/real.h"
61 #include "gromacs/utility/stringutil.h"
63 #include "testutils/refdata-checkers.h"
64 #include "testutils/refdata-impl.h"
65 #include "testutils/refdata-xml.h"
66 #include "testutils/testasserts.h"
67 #include "testutils/testexceptions.h"
68 #include "testutils/testfilemanager.h"
75 /********************************************************************
76 * TestReferenceData::Impl declaration
83 * Private implementation class for TestReferenceData.
85 * \ingroup module_testutils
87 class TestReferenceDataImpl
90 //! Initializes a checker in the given mode.
91 TestReferenceDataImpl(ReferenceDataMode mode
, bool bSelfTestMode
);
93 //! Performs final reference data processing when test ends.
94 void onTestEnd(bool testPassed
);
96 //! Full path of the reference data file.
97 std::string fullFilename_
;
99 * Root entry for comparing the reference data.
101 * Null after construction iff in compare mode and reference data was
102 * not loaded successfully.
103 * In all write modes, copies are present for nodes added to
104 * \a outputRootEntry_, and ReferenceDataEntry::correspondingOutputEntry()
105 * points to the copy in the output tree.
107 ReferenceDataEntry::EntryPointer compareRootEntry_
;
109 * Root entry for writing new reference data.
111 * Null if only comparing against existing data. Otherwise, starts
113 * When creating new reference data, this is maintained as a copy of
114 * \a compareRootEntry_.
115 * When updating existing data, entries are added either by copying
116 * from \a compareRootEntry_ (if they exist and comparison passes), or
117 * by creating new ones.
119 ReferenceDataEntry::EntryPointer outputRootEntry_
;
121 * Whether updating existing reference data.
123 bool updateMismatchingEntries_
;
124 //! `true` if self-testing (enables extra failure messages).
127 * Whether any reference checkers have been created for this data.
132 } // namespace internal
134 /********************************************************************
141 //! Convenience typedef for a smart pointer to TestReferenceDataImpl.
142 typedef std::shared_ptr
<internal::TestReferenceDataImpl
>
143 TestReferenceDataImplPointer
;
146 * Global reference data instance.
148 * The object is created when the test creates a TestReferenceData, and the
149 * object is destructed (and other post-processing is done) at the end of each
150 * test by ReferenceDataTestEventListener (which is installed as a Google Test
153 TestReferenceDataImplPointer g_referenceData
;
154 //! Global reference data mode set with setReferenceDataMode().
155 ReferenceDataMode g_referenceDataMode
= erefdataCompare
;
157 //! Returns the global reference data mode.
158 ReferenceDataMode
getReferenceDataMode()
160 return g_referenceDataMode
;
163 //! Returns a reference to the global reference data object.
164 TestReferenceDataImplPointer
initReferenceDataInstance()
166 GMX_RELEASE_ASSERT(!g_referenceData
,
167 "Test cannot create multiple TestReferenceData instances");
168 g_referenceData
.reset(new internal::TestReferenceDataImpl(getReferenceDataMode(), false));
169 return g_referenceData
;
172 //! Handles reference data creation for self-tests.
173 TestReferenceDataImplPointer
initReferenceDataInstanceForSelfTest(ReferenceDataMode mode
)
177 GMX_RELEASE_ASSERT(g_referenceData
.unique(),
178 "Test cannot create multiple TestReferenceData instances");
179 g_referenceData
->onTestEnd(true);
180 g_referenceData
.reset();
182 g_referenceData
.reset(new internal::TestReferenceDataImpl(mode
, true));
183 return g_referenceData
;
186 class ReferenceDataTestEventListener
: public ::testing::EmptyTestEventListener
189 virtual void OnTestEnd(const ::testing::TestInfo
&test_info
)
193 GMX_RELEASE_ASSERT(g_referenceData
.unique(),
194 "Test leaked TestRefeferenceData objects");
195 g_referenceData
->onTestEnd(test_info
.result()->Passed());
196 g_referenceData
.reset();
200 virtual void OnTestProgramEnd(const ::testing::UnitTest
&)
202 // Could be used e.g. to free internal buffers allocated by an XML parsing library
208 void initReferenceData(IOptionsContainer
*options
)
210 // Needs to correspond to the enum order in refdata.h.
211 const char *const refDataEnum
[] =
212 { "check", "create", "update-changed", "update-all" };
214 EnumOption
<ReferenceDataMode
>("ref-data")
215 .enumValue(refDataEnum
).store(&g_referenceDataMode
)
216 .description("Operation mode for tests that use reference data"));
217 ::testing::UnitTest::GetInstance()->listeners().Append(
218 new ReferenceDataTestEventListener
);
221 /********************************************************************
222 * TestReferenceDataImpl definition
228 TestReferenceDataImpl::TestReferenceDataImpl(
229 ReferenceDataMode mode
, bool bSelfTestMode
)
230 : updateMismatchingEntries_(false), bSelfTestMode_(bSelfTestMode
), bInUse_(false)
232 const std::string dirname
=
234 ? TestFileManager::getGlobalOutputTempDirectory()
235 : TestFileManager::getInputDataDirectory();
236 const std::string filename
= TestFileManager::getTestSpecificFileName(".xml");
237 fullFilename_
= Path::join(dirname
, "refdata", filename
);
241 case erefdataCompare
:
242 if (File::exists(fullFilename_
, File::throwOnError
))
244 compareRootEntry_
= readReferenceDataFile(fullFilename_
);
247 case erefdataCreateMissing
:
248 if (File::exists(fullFilename_
, File::throwOnError
))
250 compareRootEntry_
= readReferenceDataFile(fullFilename_
);
254 compareRootEntry_
= ReferenceDataEntry::createRoot();
255 outputRootEntry_
= ReferenceDataEntry::createRoot();
258 case erefdataUpdateChanged
:
259 if (File::exists(fullFilename_
, File::throwOnError
))
261 compareRootEntry_
= readReferenceDataFile(fullFilename_
);
265 compareRootEntry_
= ReferenceDataEntry::createRoot();
267 outputRootEntry_
= ReferenceDataEntry::createRoot();
268 updateMismatchingEntries_
= true;
270 case erefdataUpdateAll
:
271 compareRootEntry_
= ReferenceDataEntry::createRoot();
272 outputRootEntry_
= ReferenceDataEntry::createRoot();
277 void TestReferenceDataImpl::onTestEnd(bool testPassed
)
279 // TODO: Only write the file with update-changed if there were actual changes.
280 if (testPassed
&& bInUse_
&& outputRootEntry_
)
282 std::string dirname
= Path::getParentPath(fullFilename_
);
283 if (!Directory::exists(dirname
))
285 if (Directory::create(dirname
) != 0)
287 GMX_THROW(TestException("Creation of reference data directory failed: " + dirname
));
290 writeReferenceDataFile(fullFilename_
, *outputRootEntry_
);
294 } // namespace internal
297 /********************************************************************
298 * TestReferenceChecker::Impl
302 * Private implementation class for TestReferenceChecker.
304 * \ingroup module_testutils
306 class TestReferenceChecker::Impl
309 //! String constant for naming XML elements for boolean values.
310 static const char * const cBooleanNodeName
;
311 //! String constant for naming XML elements for string values.
312 static const char * const cStringNodeName
;
313 //! String constant for naming XML elements for integer values.
314 static const char * const cIntegerNodeName
;
315 //! String constant for naming XML elements for int64 values.
316 static const char * const cInt64NodeName
;
317 //! String constant for naming XML elements for unsigned int64 values.
318 static const char * const cUInt64NodeName
;
319 //! String constant for naming XML elements for floating-point values.
320 static const char * const cRealNodeName
;
321 //! String constant for naming XML attribute for value identifiers.
322 static const char * const cIdAttrName
;
323 //! String constant for naming compounds for vectors.
324 static const char * const cVectorType
;
325 //! String constant for naming compounds for sequences.
326 static const char * const cSequenceType
;
327 //! String constant for value identifier for sequence length.
328 static const char * const cSequenceLengthName
;
330 //! Creates a checker that does nothing.
331 explicit Impl(bool initialized
);
332 //! Creates a checker with a given root entry.
333 Impl(const std::string
&path
, ReferenceDataEntry
*compareRootEntry
,
334 ReferenceDataEntry
*outputRootEntry
, bool updateMismatchingEntries
,
335 bool bSelfTestMode
, const FloatingPointTolerance
&defaultTolerance
);
337 //! Returns the path of this checker with \p id appended.
338 std::string
appendPath(const char *id
) const;
340 //! Creates an entry with given parameters and fills it with \p checker.
341 ReferenceDataEntry::EntryPointer
342 createEntry(const char *type
, const char *id
,
343 const IReferenceDataEntryChecker
&checker
) const
345 ReferenceDataEntry::EntryPointer
entry(new ReferenceDataEntry(type
, id
));
346 checker
.fillEntry(entry
.get());
349 //! Checks an entry for correct type and using \p checker.
350 ::testing::AssertionResult
351 checkEntry(const ReferenceDataEntry
&entry
, const std::string
&fullId
,
352 const char *type
, const IReferenceDataEntryChecker
&checker
) const
354 if (entry
.type() != type
)
356 return ::testing::AssertionFailure()
357 << "Mismatching reference data item type" << std::endl
358 << " In item: " << fullId
<< std::endl
359 << " Actual: " << type
<< std::endl
360 << "Reference: " << entry
.type();
362 return checker
.checkEntry(entry
, fullId
);
364 //! Finds an entry by id and updates the last found entry pointer.
365 ReferenceDataEntry
*findEntry(const char *id
);
367 * Finds/creates a reference data entry to match against.
369 * \param[in] type Type of entry to create.
370 * \param[in] id Unique identifier of the entry (can be NULL, in
371 * which case the next entry without an id is matched).
372 * \param[out] checker Checker to use for filling out created entries.
373 * \returns Matching entry, or NULL if no matching entry found
374 * (NULL is never returned in write mode; new entries are created
378 findOrCreateEntry(const char *type
, const char *id
,
379 const IReferenceDataEntryChecker
&checker
);
381 * Helper method for checking a reference data value.
383 * \param[in] name Type of entry to find.
384 * \param[in] id Unique identifier of the entry (can be NULL, in
385 * which case the next entry without an id is matched).
386 * \param[in] checker Checker that provides logic specific to the
388 * \returns Whether the reference data matched, including details
389 * of the mismatch if the comparison failed.
390 * \throws TestException if there is a problem parsing the
393 * Performs common tasks in checking a reference value, such as
394 * finding or creating the correct entry.
395 * Caller needs to provide a checker object that provides the string
396 * value for a newly created entry and performs the actual comparison
397 * against a found entry.
399 ::testing::AssertionResult
400 processItem(const char *name
, const char *id
,
401 const IReferenceDataEntryChecker
&checker
);
403 * Whether the checker is initialized.
405 bool initialized() const { return initialized_
; }
407 * Whether the checker should ignore all validation calls.
409 * This is used to ignore any calls within compounds for which
410 * reference data could not be found, such that only one error is
411 * issued for the missing compound, instead of every individual value.
413 bool shouldIgnore() const
415 GMX_RELEASE_ASSERT(initialized(),
416 "Accessing uninitialized reference data checker.");
417 return compareRootEntry_
== NULL
;
420 //! Whether initialized with other means than the default constructor.
422 //! Default floating-point comparison tolerance.
423 FloatingPointTolerance defaultTolerance_
;
425 * Human-readable path to the root node of this checker.
427 * For the root checker, this will be "/", and for each compound, the
428 * id of the compound is added. Used for reporting comparison
433 * Current entry under which reference data is searched for comparison.
435 * Points to either the TestReferenceDataImpl::compareRootEntry_, or to
436 * a compound entry in the tree rooted at that entry.
438 * Can be NULL, in which case this checker does nothing (doesn't even
439 * report errors, see shouldIgnore()).
441 ReferenceDataEntry
*compareRootEntry_
;
443 * Current entry under which entries for writing are created.
445 * Points to either the TestReferenceDataImpl::outputRootEntry_, or to
446 * a compound entry in the tree rooted at that entry. NULL if only
447 * comparing, or if shouldIgnore() returns `false`.
449 ReferenceDataEntry
*outputRootEntry_
;
451 * Iterator to a child of \a compareRootEntry_ that was last found.
453 * If `compareRootEntry_->isValidChild()` returns false, no entry has
455 * After every check, is updated to point to the entry that was used
457 * Subsequent checks start the search for the matching node on this
460 ReferenceDataEntry::ChildIterator lastFoundEntry_
;
462 * Whether the reference data is being written (true) or compared
465 bool updateMismatchingEntries_
;
466 //! `true` if self-testing (enables extra failure messages).
469 * Current number of unnamed elements in a sequence.
471 * It is the index of the next added unnamed element.
476 const char *const TestReferenceChecker::Impl::cBooleanNodeName
= "Bool";
477 const char *const TestReferenceChecker::Impl::cStringNodeName
= "String";
478 const char *const TestReferenceChecker::Impl::cIntegerNodeName
= "Int";
479 const char *const TestReferenceChecker::Impl::cInt64NodeName
= "Int64";
480 const char *const TestReferenceChecker::Impl::cUInt64NodeName
= "UInt64";
481 const char *const TestReferenceChecker::Impl::cRealNodeName
= "Real";
482 const char *const TestReferenceChecker::Impl::cIdAttrName
= "Name";
483 const char *const TestReferenceChecker::Impl::cVectorType
= "Vector";
484 const char *const TestReferenceChecker::Impl::cSequenceType
= "Sequence";
485 const char *const TestReferenceChecker::Impl::cSequenceLengthName
= "Length";
488 TestReferenceChecker::Impl::Impl(bool initialized
)
489 : initialized_(initialized
), defaultTolerance_(defaultRealTolerance()),
490 compareRootEntry_(NULL
), outputRootEntry_(NULL
),
491 updateMismatchingEntries_(false), bSelfTestMode_(false), seqIndex_(0)
496 TestReferenceChecker::Impl::Impl(const std::string
&path
,
497 ReferenceDataEntry
*compareRootEntry
,
498 ReferenceDataEntry
*outputRootEntry
,
499 bool updateMismatchingEntries
, bool bSelfTestMode
,
500 const FloatingPointTolerance
&defaultTolerance
)
501 : initialized_(true), defaultTolerance_(defaultTolerance
), path_(path
+ "/"),
502 compareRootEntry_(compareRootEntry
), outputRootEntry_(outputRootEntry
),
503 lastFoundEntry_(compareRootEntry
->children().end()),
504 updateMismatchingEntries_(updateMismatchingEntries
),
505 bSelfTestMode_(bSelfTestMode
), seqIndex_(0)
511 TestReferenceChecker::Impl::appendPath(const char *id
) const
513 std::string printId
= (id
!= NULL
) ? id
: formatString("[%d]", seqIndex_
);
514 return path_
+ printId
;
518 ReferenceDataEntry
*TestReferenceChecker::Impl::findEntry(const char *id
)
520 ReferenceDataEntry::ChildIterator entry
= compareRootEntry_
->findChild(id
, lastFoundEntry_
);
521 seqIndex_
= (id
== NULL
) ? seqIndex_
+1 : 0;
522 if (compareRootEntry_
->isValidChild(entry
))
524 lastFoundEntry_
= entry
;
531 TestReferenceChecker::Impl::findOrCreateEntry(
532 const char *type
, const char *id
,
533 const IReferenceDataEntryChecker
&checker
)
535 ReferenceDataEntry
*entry
= findEntry(id
);
536 if (entry
== NULL
&& outputRootEntry_
!= NULL
)
538 lastFoundEntry_
= compareRootEntry_
->addChild(createEntry(type
, id
, checker
));
539 entry
= lastFoundEntry_
->get();
544 ::testing::AssertionResult
545 TestReferenceChecker::Impl::processItem(const char *type
, const char *id
,
546 const IReferenceDataEntryChecker
&checker
)
550 return ::testing::AssertionSuccess();
552 std::string fullId
= appendPath(id
);
553 ReferenceDataEntry
*entry
= findOrCreateEntry(type
, id
, checker
);
556 return ::testing::AssertionFailure()
557 << "Reference data item " << fullId
<< " not found";
559 ::testing::AssertionResult
result(checkEntry(*entry
, fullId
, type
, checker
));
560 if (outputRootEntry_
!= NULL
&& entry
->correspondingOutputEntry() == NULL
)
562 if (!updateMismatchingEntries_
|| result
)
564 outputRootEntry_
->addChild(entry
->cloneToOutputEntry());
568 ReferenceDataEntry::EntryPointer
outputEntry(createEntry(type
, id
, checker
));
569 entry
->setCorrespondingOutputEntry(outputEntry
.get());
570 outputRootEntry_
->addChild(move(outputEntry
));
571 return ::testing::AssertionSuccess();
574 if (bSelfTestMode_
&& !result
)
576 ReferenceDataEntry
expected(type
, id
);
577 checker
.fillEntry(&expected
);
579 << "String value: '" << expected
.value() << "'" << std::endl
580 << " Ref. string: '" << entry
->value() << "'";
586 /********************************************************************
590 TestReferenceData::TestReferenceData()
591 : impl_(initReferenceDataInstance())
596 TestReferenceData::TestReferenceData(ReferenceDataMode mode
)
597 : impl_(initReferenceDataInstanceForSelfTest(mode
))
602 TestReferenceData::~TestReferenceData()
607 TestReferenceChecker
TestReferenceData::rootChecker()
609 if (!impl_
->bInUse_
&& !impl_
->compareRootEntry_
)
611 ADD_FAILURE() << "Reference data file not found: "
612 << impl_
->fullFilename_
;
614 impl_
->bInUse_
= true;
615 if (!impl_
->compareRootEntry_
)
617 return TestReferenceChecker(new TestReferenceChecker::Impl(true));
619 return TestReferenceChecker(
620 new TestReferenceChecker::Impl("", impl_
->compareRootEntry_
.get(),
621 impl_
->outputRootEntry_
.get(),
622 impl_
->updateMismatchingEntries_
, impl_
->bSelfTestMode_
,
623 defaultRealTolerance()));
627 /********************************************************************
628 * TestReferenceChecker
631 TestReferenceChecker::TestReferenceChecker()
632 : impl_(new Impl(false))
636 TestReferenceChecker::TestReferenceChecker(Impl
*impl
)
641 TestReferenceChecker::TestReferenceChecker(const TestReferenceChecker
&other
)
642 : impl_(new Impl(*other
.impl_
))
646 TestReferenceChecker::TestReferenceChecker(TestReferenceChecker
&&other
)
647 : impl_(std::move(other
.impl_
))
651 TestReferenceChecker
&
652 TestReferenceChecker::operator=(TestReferenceChecker
&&other
)
654 impl_
= std::move(other
.impl_
);
658 TestReferenceChecker::~TestReferenceChecker()
662 bool TestReferenceChecker::isValid() const
664 return impl_
->initialized();
668 void TestReferenceChecker::setDefaultTolerance(
669 const FloatingPointTolerance
&tolerance
)
671 impl_
->defaultTolerance_
= tolerance
;
675 bool TestReferenceChecker::checkPresent(bool bPresent
, const char *id
)
677 if (impl_
->shouldIgnore() || impl_
->outputRootEntry_
!= NULL
)
681 ReferenceDataEntry::ChildIterator entry
682 = impl_
->compareRootEntry_
->findChild(id
, impl_
->lastFoundEntry_
);
684 = impl_
->compareRootEntry_
->isValidChild(entry
);
685 if (bFound
!= bPresent
)
687 ADD_FAILURE() << "Mismatch while checking reference data item '"
688 << impl_
->appendPath(id
) << "'\n"
689 << "Expected: " << (bPresent
? "it is present.\n" : "it is absent.\n")
690 << " Actual: " << (bFound
? "it is present." : "it is absent.");
692 if (bFound
&& bPresent
)
694 impl_
->lastFoundEntry_
= entry
;
701 TestReferenceChecker
TestReferenceChecker::checkCompound(const char *type
, const char *id
)
703 if (impl_
->shouldIgnore())
705 return TestReferenceChecker(new Impl(true));
707 std::string fullId
= impl_
->appendPath(id
);
709 ReferenceDataEntry
*entry
= impl_
->findOrCreateEntry(type
, id
, checker
);
712 ADD_FAILURE() << "Reference data item " << fullId
<< " not found";
713 return TestReferenceChecker(new Impl(true));
715 if (impl_
->updateMismatchingEntries_
)
717 entry
->makeCompound(type
);
721 ::testing::AssertionResult
result(impl_
->checkEntry(*entry
, fullId
, type
, checker
));
722 EXPECT_PLAIN(result
);
725 return TestReferenceChecker(new Impl(true));
728 if (impl_
->outputRootEntry_
!= NULL
&& entry
->correspondingOutputEntry() == NULL
)
730 impl_
->outputRootEntry_
->addChild(entry
->cloneToOutputEntry());
732 return TestReferenceChecker(
733 new Impl(fullId
, entry
, entry
->correspondingOutputEntry(),
734 impl_
->updateMismatchingEntries_
, impl_
->bSelfTestMode_
,
735 impl_
->defaultTolerance_
));
739 /*! \brief Throw a TestException if the caller tries to write particular refdata that can't work.
741 * If the string to write is non-empty and has only whitespace,
742 * TinyXML2 can't read it correctly, so throw an exception for this
743 * case, so that we can't accidentally use it and run into mysterious
746 * \todo Eliminate this limitation of TinyXML2. See
747 * e.g. https://github.com/leethomason/tinyxml2/issues/432
750 throwIfNonEmptyAndOnlyWhitespace(const std::string
&s
, const char *id
)
752 if (!s
.empty() && std::all_of(s
.cbegin(), s
.cend(), [](const char &c
){ return std::isspace(c
); }))
754 std::string
message("String '" + s
+ "' with ");
755 message
+= (id
!= nullptr) ? "null " : "";
757 message
+= (id
!= nullptr) ? "" : id
;
758 message
+= " cannot be handled. We must refuse to write a refdata String"
759 "field for a non-empty string that contains only whitespace, "
760 "because it will not be read correctly by TinyXML2.";
761 GMX_THROW(TestException(message
));
765 void TestReferenceChecker::checkBoolean(bool value
, const char *id
)
767 EXPECT_PLAIN(impl_
->processItem(Impl::cBooleanNodeName
, id
,
768 ExactStringChecker(value
? "true" : "false")));
772 void TestReferenceChecker::checkString(const char *value
, const char *id
)
774 throwIfNonEmptyAndOnlyWhitespace(value
, id
);
775 EXPECT_PLAIN(impl_
->processItem(Impl::cStringNodeName
, id
,
776 ExactStringChecker(value
)));
780 void TestReferenceChecker::checkString(const std::string
&value
, const char *id
)
782 throwIfNonEmptyAndOnlyWhitespace(value
, id
);
783 EXPECT_PLAIN(impl_
->processItem(Impl::cStringNodeName
, id
,
784 ExactStringChecker(value
)));
788 void TestReferenceChecker::checkTextBlock(const std::string
&value
,
791 EXPECT_PLAIN(impl_
->processItem(Impl::cStringNodeName
, id
,
792 ExactStringBlockChecker(value
)));
796 void TestReferenceChecker::checkInteger(int value
, const char *id
)
798 EXPECT_PLAIN(impl_
->processItem(Impl::cIntegerNodeName
, id
,
799 ExactStringChecker(formatString("%d", value
))));
802 void TestReferenceChecker::checkInt64(gmx_int64_t value
, const char *id
)
804 EXPECT_PLAIN(impl_
->processItem(Impl::cInt64NodeName
, id
,
805 ExactStringChecker(formatString("%" GMX_PRId64
, value
))));
808 void TestReferenceChecker::checkUInt64(gmx_uint64_t value
, const char *id
)
810 EXPECT_PLAIN(impl_
->processItem(Impl::cUInt64NodeName
, id
,
811 ExactStringChecker(formatString("%" GMX_PRIu64
, value
))));
814 void TestReferenceChecker::checkDouble(double value
, const char *id
)
816 FloatingPointChecker
<double> checker(value
, impl_
->defaultTolerance_
);
817 EXPECT_PLAIN(impl_
->processItem(Impl::cRealNodeName
, id
, checker
));
821 void TestReferenceChecker::checkFloat(float value
, const char *id
)
823 FloatingPointChecker
<float> checker(value
, impl_
->defaultTolerance_
);
824 EXPECT_PLAIN(impl_
->processItem(Impl::cRealNodeName
, id
, checker
));
828 void TestReferenceChecker::checkReal(float value
, const char *id
)
830 checkFloat(value
, id
);
834 void TestReferenceChecker::checkReal(double value
, const char *id
)
836 checkDouble(value
, id
);
840 void TestReferenceChecker::checkRealFromString(const std::string
&value
, const char *id
)
842 FloatingPointFromStringChecker
<real
> checker(value
, impl_
->defaultTolerance_
);
843 EXPECT_PLAIN(impl_
->processItem(Impl::cRealNodeName
, id
, checker
));
847 void TestReferenceChecker::checkVector(const int value
[3], const char *id
)
849 TestReferenceChecker
compound(checkCompound(Impl::cVectorType
, id
));
850 compound
.checkInteger(value
[0], "X");
851 compound
.checkInteger(value
[1], "Y");
852 compound
.checkInteger(value
[2], "Z");
856 void TestReferenceChecker::checkVector(const float value
[3], const char *id
)
858 TestReferenceChecker
compound(checkCompound(Impl::cVectorType
, id
));
859 compound
.checkReal(value
[0], "X");
860 compound
.checkReal(value
[1], "Y");
861 compound
.checkReal(value
[2], "Z");
865 void TestReferenceChecker::checkVector(const double value
[3], const char *id
)
867 TestReferenceChecker
compound(checkCompound(Impl::cVectorType
, id
));
868 compound
.checkReal(value
[0], "X");
869 compound
.checkReal(value
[1], "Y");
870 compound
.checkReal(value
[2], "Z");
875 TestReferenceChecker::checkSequenceCompound(const char *id
, size_t length
)
877 TestReferenceChecker
compound(checkCompound(Impl::cSequenceType
, id
));
878 compound
.checkInteger(static_cast<int>(length
), Impl::cSequenceLengthName
);