Don't use check_library for libm
[gromacs.git] / src / testutils / cmdlinetest.h
blob519911f16e75b342f3a0444a0bf1335c3c8777ec
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014, 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.
35 /*! \libinternal \file
36 * \brief
37 * Declares utilities testing command-line programs.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \inlibraryapi
41 * \ingroup module_testutils
43 #ifndef GMX_TESTUTILS_CMDLINETEST_H
44 #define GMX_TESTUTILS_CMDLINETEST_H
46 #include <string>
48 #include <gtest/gtest.h>
50 // arrayref.h is not strictly necessary for this header, but nearly all
51 // callers will need it to use the constructor that takes ConstArrayRef.
52 #include "gromacs/utility/arrayref.h"
53 #include "gromacs/utility/classhelpers.h"
55 namespace gmx
58 class CommandLineModuleInterface;
59 class CommandLineOptionsModuleInterface;
61 namespace test
64 class TestFileManager;
65 class TestReferenceChecker;
67 /*! \libinternal \brief
68 * Helper class for tests that need to construct command lines.
70 * This class helps in writing tests for command-line handling.
71 * The constructor method takes an array of const char pointers, specifying the
72 * command-line arguments, each as one array element. It is also possible to
73 * construct the command line by adding individual arguments with append() and
74 * addOption().
75 * The argc() and argv() methods can then be used to obtain `argc` and `argv`
76 * (non-const char pointers) arrays for passing into methods that expect these.
78 * Note that although the interface allows passing the argc and argv pointers
79 * to methods that modify them (typically as \p f(&argc(), argv())), currently
80 * the CommandLine object is not in a consistent state internally if the
81 * parameters are actually modified. Reading the command line is possible
82 * afterwards, but modification is not.
84 * If you need to construct command lines that refer to files on the file
85 * system, see CommandLineTestHelper and CommandLineTestBase for additional
86 * convenience utilities.
88 * All constructors and methods that modify this class may throw an
89 * std::bad_alloc. Const methods and accessors do not throw.
91 * \inlibraryapi
92 * \ingroup module_testutils
94 class CommandLine
96 public:
97 //! Initializes an empty command-line object.
98 CommandLine();
99 /*! \brief
100 * Initializes a command-line object from an array.
102 * \param[in] cmdline Array of command-line arguments.
104 * \p cmdline should include the binary name as the first element if
105 * that is desired in the output.
107 * This constructor is not explicit to make it possible to create a
108 * CommandLine object directly from a C array.
110 CommandLine(const ConstArrayRef<const char *> &cmdline);
111 //! Creates a deep copy of a command-line object.
112 CommandLine(const CommandLine &other);
113 ~CommandLine();
115 /*! \brief
116 * Initializes a command-line object in-place from an array.
118 * \param[in] cmdline Array of command-line arguments.
120 * \p cmdline should include the binary name as the first element if
121 * that is desired in the output.
123 * This function does the same as the constructor that takes a
124 * ConstArrayRef. Any earlier contents of the object are discarded.
126 * Strong exception safety.
128 void initFromArray(const ConstArrayRef<const char *> &cmdline);
130 /*! \brief
131 * Appends an argument to the command line.
133 * \param[in] arg Argument to append.
135 * Strong exception safety.
137 void append(const char *arg);
138 //! Convenience overload taking a std::string.
139 void append(const std::string &arg) { append(arg.c_str()); }
140 /*! \brief
141 * Adds an option-value pair to the command line.
143 * \param[in] name Name of the option to append, which
144 * should start with "-".
145 * \param[in] value Value of the argument to append.
147 void addOption(const char *name, const char *value);
148 //! Convenience overload taking a std::string.
149 void addOption(const char *name, const std::string &value);
150 //! Overload taking an int.
151 void addOption(const char *name, int value);
152 //! Overload taking a double.
153 void addOption(const char *name, double value);
154 /*! \brief
155 * Appends all arguments from \p args to the command line.
157 * If the first argument of \p args does not start with a `-`, it is
158 * skipped.
160 void merge(const CommandLine &args);
162 //! Returns argc for passing into C-style command-line handling.
163 int &argc();
164 //! Returns argv for passing into C-style command-line handling.
165 char **argv();
166 //! Returns argc for passing into C-style command-line handling.
167 int argc() const;
168 //! Returns argv for passing into C-style command-line handling.
169 const char *const *argv() const;
170 //! Returns a single argument.
171 const char *arg(int i) const;
173 //! Returns the command line formatted as a single string.
174 std::string toString() const;
176 private:
177 class Impl;
179 PrivateImplPointer<Impl> impl_;
182 /*! \libinternal \brief
183 * Helper class for tests that construct command lines that need to reference
184 * existing files.
186 * This class provides helper methods for:
188 * 1. Adding input files to a CommandLine instance by generating them from a
189 * string provided in the test (setInputFileContents()).
190 * 2. Adding output files to a CommandLine instance (setOutputFile() and
191 * setOutputFileNoTest()).
192 * 3. Checking the contents of some of the output files using
193 * TestReferenceData (setOutputFile() and checkOutputFiles()).
194 * 4. Static methods for easily executing command-line modules
195 * (various overloads of runModule()).
197 * All files created during the test are cleaned up at the end of the test.
199 * All methods can throw std::bad_alloc.
201 * \see TestFileManager
202 * \inlibraryapi
203 * \ingroup module_testutils
205 class CommandLineTestHelper
207 public:
208 /*! \brief
209 * Runs a command-line program that implements CommandLineModuleInterface.
211 * \param[in,out] module Module to run.
212 * The function does not take ownership.
213 * \param[in,out] commandLine Command line parameters to pass.
214 * This is only modified if \p module modifies it.
215 * \returns The return value of the module.
216 * \throws unspecified Any exception thrown by the module.
218 static int
219 runModule(CommandLineModuleInterface *module, CommandLine *commandLine);
220 /*! \brief
221 * Runs a command-line program that implements
222 * CommandLineOptionsModuleInterface.
224 * \param[in] factory Factory method for the module to run.
225 * \param[in,out] commandLine Command line parameters to pass.
226 * This is only modified if the module modifies it.
227 * \returns The return value of the module.
228 * \throws unspecified Any exception thrown by the factory or the
229 * module.
231 static int
232 runModule(CommandLineOptionsModuleInterface *(*factory)(),
233 CommandLine *commandLine);
235 /*! \brief
236 * Initializes an instance.
238 * \param fileManager File manager to use for generating temporary
239 * file names and to track temporary files.
241 explicit CommandLineTestHelper(TestFileManager *fileManager);
242 ~CommandLineTestHelper();
244 /*! \brief
245 * Generates and sets an input file.
247 * \param[in,out] args CommandLine to which to add the option.
248 * \param[in] option Option to set.
249 * \param[in] extension Extension for the file to create.
250 * \param[in] contents Text to write to the input file.
252 * Creates a temporary file with contents from \p contents, and adds
253 * \p option to \p args with a value that points to the generated file.
255 void setInputFileContents(CommandLine *args, const char *option,
256 const char *extension,
257 const std::string &contents);
258 /*! \brief
259 * Generates and sets an input file.
261 * \param[in,out] args CommandLine to which to add the option.
262 * \param[in] option Option to set.
263 * \param[in] extension Extension for the file to create.
264 * \param[in] contents Text to write to the input file.
266 * Creates a temporary file with contents from \p contents (each array
267 * entry on its own line), and adds \p option to \p args with a value
268 * that points to the generated file.
270 void setInputFileContents(CommandLine *args, const char *option,
271 const char *extension,
272 const ConstArrayRef<const char *> &contents);
273 /*! \brief
274 * Sets an output file parameter and adds it to the set of tested files.
276 * \param[in,out] args CommandLine to which to add the option.
277 * \param[in] option Option to set.
278 * \param[in] filename Name of the output file.
280 * This method:
281 * - Adds \p option to \p args to point a temporary file name
282 * constructed from \p filename.
283 * - Makes checkOutputFiles() to check the contents of the file
284 * against reference data.
285 * - Marks the temporary file for removal at test teardown.
287 * \p filename is given to TestTemporaryFileManager to make a unique
288 * filename for the temporary file, but is not otherwise used.
290 * Currently, this method should not be called for an XVG file, because
291 * the comments in the beginning of the file contain timestamps and
292 * other variable information, causing the test to fail. Best used
293 * only for custom data formats.
295 void setOutputFile(CommandLine *args, const char *option,
296 const char *filename);
297 /*! \brief
298 * Sets an output file parameter.
300 * \param[in,out] args CommandLine to which to add the option.
301 * \param[in] option Option to set.
302 * \param[in] extension Extension for the file to create.
304 * This method:
305 * - Adds \p option to \p args to point to a temporary file name with
306 * extension \p extension.
307 * - Marks the temporary file for removal at test teardown.
309 * This method provides the mechanism to set output files that are
310 * required to trigger computation of values that are required for
311 * the test. The contents of the output file are not tested.
313 * Another use case is to mark files that are unconditionally produced
314 * by the code under test, but do not need to be tested. This method
315 * makes the test code aware of those files such that it can remove
316 * them at the end of the test.
318 void setOutputFileNoTest(CommandLine *args, const char *option,
319 const char *extension);
321 /*! \brief
322 * Checks output files added with setOutputFile() against reference
323 * data.
325 * \param checker Reference data root location where the reference
326 * data is stored.
328 * The file contents are tested verbatim, using direct string
329 * comparison. The text can be found verbatim in the reference data
330 * XML files for manual inspection.
332 * Generates non-fatal test failures if some output file contents do
333 * not match the reference data.
335 void checkOutputFiles(TestReferenceChecker checker) const;
337 private:
338 class Impl;
340 PrivateImplPointer<Impl> impl_;
343 /*! \libinternal \brief
344 * Test fixture for tests that call a single command-line program with
345 * input/output files.
347 * This class provides a convenient package for using CommandLineTestHelper in
348 * a test that do not need special customization. It takes care of creating
349 * the other necessary objects (like TestFileManager, TestReferenceData, and
350 * CommandLine) and wrapping the methods from CommandLineTestHelper such that
351 * extra parameters are not needed. Additionally, it provides setInputFile()
352 * as a convenience function for adding a fixed input file, pointing to a file
353 * that resides in the source tree.
355 * \see CommandLineTestHelper
356 * \inlibraryapi
357 * \ingroup module_testutils
359 class CommandLineTestBase : public ::testing::Test
361 public:
362 CommandLineTestBase();
363 ~CommandLineTestBase();
365 /*! \brief
366 * Sets an input file.
368 * \param[in] option Option to set.
369 * \param[in] filename Name of the input file.
371 * \see TestFileManager::getInputFilePath()
373 void setInputFile(const char *option, const char *filename);
374 /*! \brief
375 * Generates and sets an input file.
377 * \see CommandLineTestHelper::setInputFileContents()
379 void setInputFileContents(const char *option,
380 const char *extension,
381 const std::string &contents);
382 /*! \brief
383 * Generates and sets an input file.
385 * \see CommandLineTestHelper::setInputFileContents()
387 void setInputFileContents(const char *option,
388 const char *extension,
389 const ConstArrayRef<const char *> &contents);
390 /*! \brief
391 * Sets an output file parameter and adds it to the set of tested files.
393 * \see CommandLineTestHelper::setOutputFile()
395 void setOutputFile(const char *option, const char *filename);
396 /*! \brief
397 * Sets an output file parameter.
399 * \see CommandLineTestHelper::setOutputFileNoTest()
401 void setOutputFileNoTest(const char *option, const char *extension);
403 /*! \brief
404 * Returns the internal CommandLine object used to construct the
405 * command line for the test.
407 * Derived test fixtures can use this to add additional options, and
408 * to access the final command line to do the actual call that is being
409 * tested.
411 * Does not throw.
413 CommandLine &commandLine();
414 /*! \brief
415 * Returns the internal TestFileManager object used to manage the
416 * files.
418 * Derived test fixtures can use this to manage files in cases the
419 * canned methods are not sufficient.
421 * Does not throw.
423 TestFileManager &fileManager();
424 /*! \brief
425 * Returns the root reference data checker.
427 * Derived test fixtures can use this to check other things than output
428 * file contents.
430 TestReferenceChecker rootChecker();
432 /*! \brief
433 * Checks output files added with setOutputFile() against reference
434 * data.
436 * \see CommandLineTestHelper::checkOutputFiles()
438 void checkOutputFiles();
440 private:
441 class Impl;
443 PrivateImplPointer<Impl> impl_;
446 } // namespace test
447 } // namespace gmx
449 #endif