Introduce SimulatorBuilder
[gromacs.git] / src / gromacs / commandline / tests / cmdlinehelpwriter.cpp
blob0fc925d28582fdafdf23a62128d1da31f837d587
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014,2015,2016,2017,2019, 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 /*! \internal \file
36 * \brief
37 * Tests gmx::CommandLineHelpWriter.
39 * These tests fail for any change in the output, and it should be reviewed
40 * whether the change was intentional.
41 * For development, the tests can be run with a '-stdout' command-line option
42 * to print out the help to stdout instead of using the XML reference
43 * framework.
45 * \author Teemu Murtola <teemu.murtola@gmail.com>
46 * \ingroup module_commandline
48 #include "gmxpre.h"
50 #include "gromacs/commandline/cmdlinehelpwriter.h"
52 #include <gtest/gtest.h>
54 #include "gromacs/commandline/cmdlinehelpcontext.h"
55 #include "gromacs/math/vectypes.h"
56 #include "gromacs/options/basicoptions.h"
57 #include "gromacs/options/filenameoption.h"
58 #include "gromacs/options/options.h"
59 #include "gromacs/utility/arrayref.h"
60 #include "gromacs/utility/stringstream.h"
61 #include "gromacs/utility/textwriter.h"
63 #include "testutils/stringtest.h"
65 namespace
68 class CommandLineHelpWriterTest : public ::gmx::test::StringTestBase
70 public:
71 CommandLineHelpWriterTest() : bHidden_(false) {}
73 void checkHelp(gmx::CommandLineHelpWriter *writer);
75 bool bHidden_;
78 void CommandLineHelpWriterTest::checkHelp(gmx::CommandLineHelpWriter *writer)
80 gmx::StringOutputStream stream;
81 gmx::TextWriter streamWriter(&stream);
82 gmx::CommandLineHelpContext context(&streamWriter, gmx::eHelpOutputFormat_Console,
83 nullptr, "test");
84 context.setShowHidden(bHidden_);
85 writer->writeHelp(context);
86 stream.close();
88 checkText(stream.toString(), "HelpText");
92 /********************************************************************
93 * Tests start here
97 * Tests help printing for each option type, but doesn't contain much
98 * variablity in the options.
100 TEST_F(CommandLineHelpWriterTest, HandlesOptionTypes)
102 using namespace gmx;
104 Options options;
105 options.addOption(BooleanOption("bool").description("Boolean option")
106 .defaultValue(true));
107 options.addOption(BooleanOption("hidden").description("Hidden option")
108 .hidden().defaultValue(true));
109 options.addOption(IntegerOption("int").description("Integer option")
110 .defaultValue(2));
111 ivec intvec = {1, 2, 3};
112 options.addOption(IntegerOption("ivec").description("Integer vector option")
113 .vector().store(intvec));
114 options.addOption(DoubleOption("double").description("Double option")
115 .defaultValue(2.5));
116 dvec dblvec = {1.1, 2.3, 3.2};
117 options.addOption(DoubleOption("dvec").description("Double vector option")
118 .vector().store(dblvec));
119 options.addOption(DoubleOption("time").description("Time option (%t)")
120 .timeValue().defaultValue(10.0));
121 options.addOption(StringOption("string").description("String option")
122 .defaultValue("test"));
123 const char * const enumValues[] = { "no", "opt1", "opt2" };
124 options.addOption(StringOption("enum").description("Enum option")
125 .enumValue(enumValues).defaultEnumIndex(0));
126 options.addOption(EnumIntOption("ienum").description("Enum option")
127 .enumValue(enumValues).defaultValue(1));
129 std::string filename;
130 options.addOption(FileNameOption("f")
131 .description("Input file description")
132 .filetype(eftTrajectory).inputFile().required()
133 .defaultBasename("traj"));
134 options.addOption(FileNameOption("mult")
135 .description("Multiple file description")
136 .filetype(eftTrajectory).inputFile().multiValue()
137 .defaultBasename("traj"));
138 options.addOption(FileNameOption("lib")
139 .description("Library file description")
140 .filetype(eftGenericData).inputFile().libraryFile()
141 .defaultBasename("libdata"));
142 options.addOption(FileNameOption("io")
143 .store(&filename)
144 .description("Input/Output file description")
145 .filetype(eftGenericData).inputOutputFile()
146 .defaultBasename("inout"));
147 options.addOption(FileNameOption("o")
148 .description("Output file description")
149 .filetype(eftPlot).outputFile());
151 CommandLineHelpWriter writer(options);
152 bHidden_ = true;
153 checkHelp(&writer);
156 //! Enum value for testing.
157 enum TestEnum {
158 eFoo, eBar
162 * Tests that default values taken from variables are properly visible in the
163 * help output.
165 TEST_F(CommandLineHelpWriterTest, HandlesDefaultValuesFromVariables)
167 using namespace gmx;
169 Options options;
171 bool bValue = true;
172 options.addOption(BooleanOption("bool").description("Boolean option")
173 .store(&bValue));
175 int ivalue = 3;
176 options.addOption(IntegerOption("int").description("Integer option")
177 .store(&ivalue));
179 int iavalue[] = {2, 3};
180 options.addOption(IntegerOption("int2").description("Integer 2-value option")
181 .store(iavalue).valueCount(2));
183 std::vector<std::string> svalues;
184 svalues.emplace_back("foo");
185 options.addOption(StringOption("str").description("String option")
186 .storeVector(&svalues).multiValue());
188 TestEnum evalue = eBar;
189 const char *const allowed[] = { "foo", "bar" };
190 options.addOption(EnumOption<TestEnum>("enum").description("Enum option")
191 .enumValue(allowed).store(&evalue));
193 CommandLineHelpWriter writer(options);
194 checkHelp(&writer);
198 * Tests help printing with file name options with various values that don't
199 * fit into the allocated columns.
201 TEST_F(CommandLineHelpWriterTest, HandlesLongFileOptions)
203 using gmx::FileNameOption;
204 using gmx::eftGenericData;
205 using gmx::eftTrajectory;
207 gmx::Options options;
208 options.addOption(FileNameOption("f")
209 .description("File name option with a long value")
210 .filetype(eftTrajectory).inputFile().required()
211 .defaultBasename("path/to/long/trajectory/name"));
212 options.addOption(FileNameOption("f2")
213 .description("File name option with a long value")
214 .filetype(eftTrajectory).inputFile().required()
215 .defaultBasename("path/to/long/trajectory"));
216 options.addOption(FileNameOption("lib")
217 .description("File name option with a long value and type")
218 .filetype(eftTrajectory).inputFile().libraryFile()
219 .defaultBasename("path/to/long/trajectory/name"));
220 options.addOption(FileNameOption("longfileopt")
221 .description("File name option with a long name")
222 .filetype(eftGenericData).inputFile()
223 .defaultBasename("deffile"));
224 options.addOption(FileNameOption("longfileopt2")
225 .description("File name option with multiple long fields")
226 .filetype(eftGenericData).inputFile().libraryFile()
227 .defaultBasename("path/to/long/file/name"));
229 gmx::CommandLineHelpWriter writer(options);
230 checkHelp(&writer);
234 * Tests help printing with general options with various values that don't
235 * fit into the allocated columns.
237 TEST_F(CommandLineHelpWriterTest, HandlesLongOptions)
239 using gmx::BooleanOption;
240 using gmx::DoubleOption;
241 using gmx::StringOption;
243 gmx::Options options;
244 options.addOption(BooleanOption("longboolean")
245 .description("Boolean option with a long name")
246 .defaultValue(true));
247 dvec dblvec = {1.135, 2.32, 3.2132};
248 options.addOption(DoubleOption("dvec").description("Double vector option")
249 .vector().store(dblvec));
250 std::vector<std::string> values;
251 values.emplace_back("A very long string value that overflows even the description column");
252 values.emplace_back("Another very long string value that overflows even the description column");
253 options.addOption(StringOption("string")
254 .description("String option with very long values (may "
255 "be less relevant with selections having "
256 "their own option type)")
257 .storeVector(&values));
259 gmx::CommandLineHelpWriter writer(options);
260 checkHelp(&writer);
263 /* TODO: Add corresponding tests to either the selection module, or as part of
264 * trajectoryanalysis tests.
265 * Tests help printing with selection options with values.
267 #if 0
268 TEST_F(CommandLineHelpWriterTest, HandlesSelectionOptions)
270 using gmx::SelectionFileOption;
271 using gmx::SelectionOption;
273 gmx::Options options;
274 gmx::SelectionCollection selections;
275 gmx::SelectionOptionManager manager(&selections);
276 options.addManager(&manager);
277 options.addOption(SelectionFileOption("sf"));
278 options.addOption(SelectionOption("refsel").required()
279 .description("Reference selection option"));
280 options.addOption(SelectionOption("sel").required().valueCount(2)
281 .description("Selection option"));
282 options.finish();
283 manager.parseRequestedFromString(
284 "resname SOL;"
285 "surface = within 0.5 of resname SOL;"
286 "group \"Protein\" and surface;"
287 "group \"Protein\" and not surface;");
289 gmx::CommandLineHelpWriter writer(options);
290 checkHelp(&writer);
292 #endif
295 * Tests help output with option groups.
297 TEST_F(CommandLineHelpWriterTest, HandlesOptionGroups)
299 using gmx::IntegerOption;
301 gmx::Options options;
302 gmx::IOptionsContainer &group1 = options.addGroup();
303 gmx::IOptionsContainer &group2 = options.addGroup();
304 group2.addOption(IntegerOption("sub2").description("Option in group 2"));
305 group1.addOption(IntegerOption("sub11").description("Option in group 1"));
306 options.addOption(IntegerOption("main").description("Option in root group"));
307 group1.addOption(IntegerOption("sub12").description("Option in group 1"));
309 gmx::CommandLineHelpWriter writer(options);
310 checkHelp(&writer);
314 * Tests help output using a help text.
316 TEST_F(CommandLineHelpWriterTest, HandlesHelpText)
318 const char *const help[] = {
319 "Help text",
320 "for testing."
322 using gmx::IntegerOption;
324 gmx::Options options;
325 options.addOption(IntegerOption("int").description("Integer option")
326 .defaultValue(2));
328 gmx::CommandLineHelpWriter writer(options);
329 writer.setHelpText(help);
330 checkHelp(&writer);
334 * Test known issue output.
336 TEST_F(CommandLineHelpWriterTest, HandlesKnownIssues)
338 const char *const bugs[] = {
339 "This is a bug.",
340 "And this is another one."
342 using gmx::IntegerOption;
344 gmx::Options options;
345 options.addOption(IntegerOption("int").description("Integer option")
346 .defaultValue(2));
348 gmx::CommandLineHelpWriter writer(options);
349 writer.setKnownIssues(bugs);
350 checkHelp(&writer);
353 } // namespace