227809a728144ecee247fba00ede4252fbeecbca
[alexxy/gromacs.git] / src / testutils / textblockmatchers.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2015,2018, 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  * Declares utility classes for testing multi-line strings against reference data.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inlibraryapi
41  * \ingroup module_testutils
42  */
43 #ifndef GMX_TESTUTILS_TEXTBLOCKMATCHERS_H
44 #define GMX_TESTUTILS_TEXTBLOCKMATCHERS_H
45
46 #include <memory>
47 #include <string>
48 #include <vector>
49
50 namespace gmx
51 {
52
53 class TextInputStream;
54
55 namespace test
56 {
57
58 class TestReferenceChecker;
59
60 /*! \libinternal \brief
61  * Represents a text matcher, matching text stream contents against reference
62  * data.
63  *
64  * Typical pattern of declaring such matchers is to
65  *  - Create a factory that implements ITextBlockMatcherSettings,
66  *  - Make that factory provide any necessary parameters that the matcher needs,
67  *    using a "named parameter" idiom (see XvgMatch for an example), and
68  *  - Make the factory create and return an instance of an internal
69  *    implementation class that implements ITextBlockMatcher and provides
70  *    the actual matching logic.
71  *
72  * Any method that then wants to accept a matcher can accept a
73  * ITextBlockMatcherSettings.
74  *
75  * \inlibraryapi
76  * \ingroup module_testutils
77  */
78 class ITextBlockMatcher
79 {
80     public:
81         virtual ~ITextBlockMatcher();
82
83         /*! \brief
84          * Matches contents of a stream against reference data.
85          *
86          * \param  stream   Stream to match.
87          * \param  checker  Checker to use for matching.
88          *
89          * The method can change the state of the provided checker (e.g., by
90          * changing the default tolerance).
91          * The caller is responsible of providing a checker where such state
92          * changes do not matter.
93          */
94         virtual void checkStream(TextInputStream      *stream,
95                                  TestReferenceChecker *checker) = 0;
96 };
97
98 //! Smart pointer for managing a ITextBlockMatcher.
99 typedef std::unique_ptr<ITextBlockMatcher> TextBlockMatcherPointer;
100
101 /*! \libinternal \brief
102  * Represents a factory for creating a text matcher.
103  *
104  * See derived classes for available matchers.  Each derived class represents
105  * one type of matcher (see ITextBlockMatcher), and provides any methods
106  * necessary to pass parameters to such a matcher.  Methods that accept a
107  * matcher can then take in this interface, and call createMatcher() to use the
108  * matcher that the caller of the method specifies.
109  *
110  * \inlibraryapi
111  * \ingroup module_testutils
112  */
113 class ITextBlockMatcherSettings
114 {
115     public:
116         //! Factory method that constructs the matcher after parameters are set.
117         virtual TextBlockMatcherPointer createMatcher() const = 0;
118
119     protected:
120         virtual ~ITextBlockMatcherSettings();
121 };
122
123 /*! \libinternal \brief
124  * Use an exact text match (the contents should be exactly equal).
125  *
126  * \inlibraryapi
127  * \ingroup module_testutils
128  */
129 class ExactTextMatch : public ITextBlockMatcherSettings
130 {
131     public:
132         virtual TextBlockMatcherPointer createMatcher() const;
133 };
134
135 /*! \libinternal \brief
136  * Do not match the text (the contents are ignored).
137  *
138  * \inlibraryapi
139  * \ingroup module_testutils
140  */
141 class NoTextMatch : public ITextBlockMatcherSettings
142 {
143     public:
144         virtual TextBlockMatcherPointer createMatcher() const;
145 };
146
147 /*! \libinternal \brief
148  * Use an exact text match after scrubbing lines of the text
149  * that match the supplied regular expressions.
150  *
151  * This suits comparing files in tests that are intended to be
152  * localized by reporting usage, time, date, user, or file-system
153  * stamps. The latter won't be reproducible in tests until
154  * the tools that emit them can be mocked suitably.
155  *
156  * \inlibraryapi
157  * \ingroup module_testutils
158  */
159 class FilteringExactTextMatch : public ITextBlockMatcherSettings
160 {
161     public:
162         //! Factory method.
163         virtual TextBlockMatcherPointer createMatcher() const;
164         //! Add a regular expression for which a matching line should be skipped.
165         void addRegexToSkip(const std::string &lineToSkip);
166     private:
167         //! The regular expressions for lines that should be skipped.
168         std::vector<std::string> linesToSkip_;
169
170 };
171
172 } // namespace test
173 } // namespace gmx
174
175 #endif