Reformat existing LGPL copyright notices.
[alexxy/gromacs.git] / src / testutils / refdata.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Functionality for writing tests that can produce their own reference data.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inlibraryapi
41  * \ingroup module_testutils
42  */
43 #ifndef GMX_TESTUTILS_REFDATA_H
44 #define GMX_TESTUTILS_REFDATA_H
45
46 #include <iterator>
47 #include <string>
48
49 #include "gromacs/utility/common.h"
50
51 namespace gmx
52 {
53
54 class Options;
55
56 namespace test
57 {
58
59 /*! \libinternal \brief
60  * Mode of operation for reference data handling.
61  *
62  * There should be no need to use this type outside the test utility module.
63  */
64 enum ReferenceDataMode
65 {
66     /*! \brief
67      * Compare to existing reference data.
68      *
69      * If reference data does not exist, or if the test results differ from
70      * those in the reference data, the test fails.
71      */
72     erefdataCompare,
73     /*! \brief
74      * Create missing reference data.
75      *
76      * If reference data does not exist for a test, that test behaves as if
77      * ::erefdataUpdateAll had been specified.  Tests for which reference data
78      * exists, behave like with ::erefdataCompare.
79      */
80     erefdataCreateMissing,
81     /*! \brief
82      * Update reference data, overwriting old data.
83      *
84      * Tests utilizing reference data should always pass in this mode unless
85      * there is an I/O error.
86      */
87     erefdataUpdateAll
88 };
89
90 /*! \libinternal \brief
91  * Returns the global reference data mode.
92  *
93  * There should be no need to use this function outside the test utility module.
94  */
95 ReferenceDataMode getReferenceDataMode();
96 /*! \libinternal \brief
97  * Sets the global reference data mode.
98  *
99  * There should be no need to use this function outside the test utility module.
100  */
101 void setReferenceDataMode(ReferenceDataMode mode);
102 /*! \libinternal \brief
103  * Returns the directory where reference data files are stored.
104  *
105  * There should be no need to use this function outside the test utility module.
106  */
107 std::string getReferenceDataPath();
108 /*! \libinternal \brief
109  * Initializes reference data handling.
110  *
111  * Adds command-line options to \p options to set the reference data mode.
112  * By default, ::erefdataCompare is used, but \c "--ref-data create" or
113  * \c "--ref-data update" can be used to change it.
114  *
115  * This function is automatically called by initTestUtils().
116  */
117 void initReferenceData(Options *options);
118
119
120 class TestReferenceChecker;
121
122 /*! \libinternal \brief
123  * Handles creation of and comparison to test reference data.
124  *
125  * This class provides functionality to use the same code to generate reference
126  * data and then on later runs compare the results of the code against that
127  * reference.  The mode in which the class operates (writing reference data or
128  * comparing against existing data) is set with parseReferenceDataArgs(), which
129  * is automatically called when using the testutils module to implement tests.
130  * Tests only need to create an instance of TestReferenceData, obtain a
131  * TestReferenceChecker using the rootChecker() method and use the various
132  * check*() methods in TestReferenceChecker to indicate values to check.  If
133  * the test is running in reference data creation mode, it will produce an XML
134  * file with the values recorder.  In comparison mode, it will read that same
135  * XML file and produce a Google Test non-fatal assertion for every discrepancy
136  * it detects with the reference data (including missing reference data file or
137  * individual item).  Exceptions derived from TestException are thrown for I/O
138  * errors and syntax errors in the reference data.
139  *
140  * Simple example (using Google Test):
141  * \code
142    int functionToTest(int param);
143
144    TEST(MyTest, SimpleTest)
145    {
146        gmx::test::TestReferenceData data;
147
148        gmx::test::TestReferenceChecker checker(data.rootChecker());
149        checker.checkInteger(functionToTest(3), "ValueWith3");
150        checker.checkInteger(functionToTest(5), "ValueWith5");
151        gmx::test::TestReferenceChecker compound(
152                checker.checkCompound("CustomCompound", "Item"));
153        compound.checkInteger(function2ToTest(3), "ValueWith3");
154        compound.checkInteger(function2ToTest(5), "ValueWith5");
155        checker.checkInteger(functionToTest(4), "ValueWith4");
156    }
157  * \endcode
158  *
159  * If rootChecker() is never called, no comparison is done (i.e., missing
160  * reference data file is not reported as an error, nor is empty reference data
161  * file created in write mode).
162  *
163  * \inlibraryapi
164  * \ingroup module_testutils
165  */
166 class TestReferenceData
167 {
168     public:
169         /*! \brief
170          * Initializes the reference data in the global mode.
171          */
172         TestReferenceData();
173         /*! \brief
174          * Initializes the reference data in a specific mode.
175          *
176          * This function is mainly useful for self-testing the reference data
177          * framework.
178          * The default constructor should be used in tests utilizing this class.
179          */
180         explicit TestReferenceData(ReferenceDataMode mode);
181         /*! \brief
182          * Frees reference data structures.
183          *
184          * In the current implementation, this function writes the reference
185          * data out if necessary.
186          */
187         ~TestReferenceData();
188
189         //! Returns true if reference data is currently being written.
190         bool isWriteMode() const;
191
192         /*! \brief
193          * Returns a root-level checker object for comparisons.
194          *
195          * Each call returns an independent instance.
196          */
197         TestReferenceChecker rootChecker();
198
199     private:
200         class Impl;
201
202         PrivateImplPointer<Impl> impl_;
203 };
204
205 /*! \libinternal \brief
206  * Handles comparison to test reference data.
207  *
208  * Every check*() method takes an id string as the last parameter.  This id is
209  * used to uniquely identify the value in the reference data, and it makes the
210  * output XML more human-friendly and more robust to errors.  The id can be
211  * NULL; in this case, multiple elements with no id are created, and they will
212  * be matched in the same order as in which they are created.  The
213  * checkCompound() method can be used to create a set of reference values
214  * grouped together.  In this case, all check*() calls using the returned child
215  * TestReferenceChecker object will create the reference data within this
216  * group, and the ids only need to be unique within the compound.  Compounds
217  * can be nested.
218  *
219  * For usage example, see TestReferenceData.
220  *
221  * Copies of this class behave have independent internal state.
222  *
223  * \inlibraryapi
224  * \ingroup module_testutils
225  */
226 class TestReferenceChecker
227 {
228     public:
229         /*! \brief
230          * Creates a deep copy of the other checker.
231          */
232         TestReferenceChecker(const TestReferenceChecker &other);
233         ~TestReferenceChecker();
234
235         //! Assigns a test reference checker.
236         TestReferenceChecker &operator=(const TestReferenceChecker &other);
237
238         //! Returns true if reference data is currently being written.
239         bool isWriteMode() const;
240
241         /*! \brief
242          * Checks whether a data item is present.
243          *
244          * \param[in] bPresent  Whether to check for presence or absence.
245          * \param[in] id        Unique identifier of the item to check.
246          * \returns   true if bPresent was true and the data item was found.
247          *
248          * If \p bPresent is true, checks that a data item with \p id is
249          * present, otherwise checks that the data item is absent.
250          * If the check fails, a non-fatal Google Test assertion is generated.
251          *
252          * If isWriteMode() returns true, the check always succeeds and the
253          * return value is \p bPresent.
254          *
255          * The main use of this method is to assign meaning for missing
256          * reference data.  Example use:
257          * \code
258            if (checker.checkPresent(bHaveVelocities, "Velocities"))
259            {
260                // <check the velocities>
261            }
262          * \endcode
263          */
264         bool checkPresent(bool bPresent, const char *id);
265
266         /*! \brief
267          * Initializes comparison of a group of related data items.
268          *
269          * \param[in] type Informational type for the compound.
270          * \param[in] id   Unique identifier for the compound among its
271          *                 siblings.
272          * \returns   Checker to use for comparison within the compound.
273          *
274          * All checks performed with the returned checker only
275          * need to have unique ids within the compound, not globally.
276          *
277          * Compound structures can be nested.
278          */
279         TestReferenceChecker checkCompound(const char *type, const char *id);
280
281         //! Check a single boolean value.
282         void checkBoolean(bool value, const char *id);
283         //! Check a single string value.
284         void checkString(const char *value, const char *id);
285         //! Check a single string value.
286         void checkString(const std::string &value, const char *id);
287         /*! \brief
288          * Check a multi-line string value.
289          *
290          * This method works as checkString(), but should be used for long
291          * strings that may contain, e.g., newlines.  Typically used to check
292          * formatted output, and attempts to make the output XML such that it
293          * is easier to edit by hand to set the desired output formatting.
294          */
295         void checkStringBlock(const std::string &value, const char *id);
296         //! Check a single integer value.
297         void checkInteger(int value, const char *id);
298         //! Check a single single-precision floating point value.
299         void checkFloat(float value, const char *id);
300         //! Check a single double-precision floating point value.
301         void checkDouble(double value, const char *id);
302         //! Check a single floating point value.
303         void checkReal(float value, const char *id);
304         //! Check a single floating point value.
305         void checkReal(double value, const char *id);
306         //! Check a vector of three integer values.
307         void checkVector(const int value[3], const char *id);
308         //! Check a vector of three single-precision floating point values.
309         void checkVector(const float value[3], const char *id);
310         //! Check a vector of three double-precision floating point values.
311         void checkVector(const double value[3], const char *id);
312
313         /*! \name Overloaded versions of simple checker methods
314          *
315          * These methods provide overloads under a single name for all the
316          * methods checkBoolean(), checkString(), checkReal() and checkVector().
317          * They are provided mainly to allow template implementations (such as
318          * checkSequence()).  Typically callers should use the individually
319          * named versions for greater clarity.
320          * \{
321          */
322         //! Check a single boolean value.
323         void checkValue(bool value, const char *id)
324         {
325             checkBoolean(value, id);
326         }
327         //! Check a single string value.
328         void checkValue(const char *value, const char *id)
329         {
330             checkString(value, id);
331         }
332         //! Check a single string value.
333         void checkValue(const std::string &value, const char *id)
334         {
335             checkString(value, id);
336         }
337         //! Check a single integer value.
338         void checkValue(int value, const char *id)
339         {
340             checkInteger(value, id);
341         }
342         //! Check a single single-precision floating point value.
343         void checkValue(float value, const char *id)
344         {
345             checkFloat(value, id);
346         }
347         //! Check a single double-precision floating point value.
348         void checkValue(double value, const char *id)
349         {
350             checkDouble(value, id);
351         }
352         //! Check a vector of three integer values.
353         void checkValue(const int value[3], const char *id)
354         {
355             checkVector(value, id);
356         }
357         //! Check a vector of three single-precision floating point values.
358         void checkValue(const float value[3], const char *id)
359         {
360             checkVector(value, id);
361         }
362         //! Check a vector of three double-precision floating point values.
363         void checkValue(const double value[3], const char *id)
364         {
365             checkVector(value, id);
366         }
367         /*!\}*/
368
369         /*! \brief
370          * Generic method to check a sequence of simple values.
371          *
372          * \tparam Iterator  Input iterator that allows multiple (two) passes.
373          *      Value type must be one of those accepted by checkValue(), or
374          *      implicitly convertible to one.
375          * \param[in] begin  Iterator to the start of the range to check.
376          * \param[in] end    Iterator to the end of the range to check.
377          * \param[in] id     Unique identifier for the sequence among its
378          *                   siblings.
379          */
380         template <class Iterator>
381         void checkSequence(Iterator begin, Iterator end, const char *id)
382         {
383             typename std::iterator_traits<Iterator>::difference_type length
384                 = std::distance(begin, end);
385             TestReferenceChecker compound(checkSequenceCompound(id, length));
386             for (Iterator i = begin; i != end; ++i)
387             {
388                 compound.checkValue(*i, NULL);
389             }
390         }
391         /*! \brief
392          * Generic method to check a sequence of custom values.
393          *
394          * \tparam Iterator    Input iterator that allows multiple (two) passes.
395          * \tparam ItemChecker Functor to check an individual value. Signature
396          *      void(TestReferenceChecker *, const T &), where T is the value
397          *      type of \p Iterator.
398          * \param[in] begin  Iterator to the start of the range to check.
399          * \param[in] end    Iterator to the end of the range to check.
400          * \param[in] id     Unique identifier for the sequence among its
401          *                   siblings.
402          * \param[in] checkItem  Functor to check an individual item.
403          *
404          * This method creates a compound checker \c compound within which all
405          * values of the sequence are checked.  Calls \c checkItem(&compound, *i)
406          * with that compound for each iterator \c i in the range [begin, end).
407          * \p checkItem should use the various check methods in the passed
408          * checker to check each value.
409          *
410          * This method can be used to check a sequence made of compound types.
411          * Typically \p checkItem will create a compound within the passed
412          * checker to check different aspects of the passed in value.
413          */
414         template <class Iterator, class ItemChecker>
415         void checkSequence(Iterator begin, Iterator end, const char *id,
416                            ItemChecker checkItem)
417         {
418             typename std::iterator_traits<Iterator>::difference_type length
419                 = std::distance(begin, end);
420             TestReferenceChecker compound(checkSequenceCompound(id, length));
421             for (Iterator i = begin; i != end; ++i)
422             {
423                 checkItem(&compound, *i);
424             }
425         }
426         /*! \brief
427          * Check an array of values.
428          *
429          * \tparam T  Type of values to check. Should be one of those accepted
430          *      by checkValue(), or implicitly convertible to one.
431          *
432          * \param[in] length  Number of values to check.
433          * \param[in] values  Pointer to the first value to check.
434          * \param[in] id     Unique identifier for the sequence among its
435          *                   siblings.
436          *
437          * This is a convenience method that delegates all work to
438          * checkSequence().
439          */
440         template <typename T>
441         void checkSequenceArray(size_t length, const T *values, const char *id)
442         {
443             checkSequence(values, values + length, id);
444         }
445         /*! \brief
446          * Convenience method for checking that a sequence is empty.
447          *
448          * \param[in] id     Unique identifier for the sequence among its
449          *                   siblings.
450          *
451          * This method provides a convenient solution for a case where there is
452          * implicitly a sequence to be checked, but there is no pointer
453          * available to the values since the sequence is empty.
454          * Since this method does not require the type of the values, it can be
455          * used in such cases easily.
456          */
457         void checkEmptySequence(const char *id);
458         /*! \brief
459          * Initializes a compound for a sequence of items.
460          *
461          * \param[in] id     Unique identifier for the sequence among its
462          *                   siblings.
463          * \param[in] length Number of items that will be in the sequence.
464          * \returns   Checker to use for comparison within the sequence.
465          *
466          * This method can be used to check custom sequences where
467          * checkSequence() is not appropriate.
468          */
469         TestReferenceChecker checkSequenceCompound(const char *id, size_t length);
470
471     private:
472         class Impl;
473
474         /*! \brief
475          * Constructs a checker with a specific internal state.
476          *
477          * Is private to only allow users of this class to create instances
478          * using TestReferenceData::rootChecker() or checkCompound()
479          * (or by copying).
480          */
481         explicit TestReferenceChecker(Impl *impl);
482
483         PrivateImplPointer<Impl> impl_;
484
485         /*! \brief
486          * Needed to expose the constructor only to TestReferenceData.
487          */
488         friend class TestReferenceData;
489 };
490
491 } // namespace test
492 } // namespace gmx
493
494 #endif