Update my e-mail address on author lines.
[alexxy/gromacs.git] / src / gromacs / commandline / tests / cmdlinehelpwriter.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Tests gmx::CommandLineHelpWriter.
34  *
35  * These tests fail for any change in the output, and it should be reviewed
36  * whether the change was intentional.
37  * For development, the tests can be run with a '-stdout' command-line option
38  * to print out the help to stdout instead of using the XML reference
39  * framework.
40  *
41  * \author Teemu Murtola <teemu.murtola@gmail.com>
42  * \ingroup module_commandline
43  */
44 #include <gtest/gtest.h>
45
46 #include "gromacs/legacyheaders/types/simple.h"
47
48 #include "gromacs/commandline/cmdlinehelpwriter.h"
49 #include "gromacs/onlinehelp/helpwritercontext.h"
50 #include "gromacs/options/basicoptions.h"
51 #include "gromacs/options/filenameoption.h"
52 #include "gromacs/options/options.h"
53 #include "gromacs/selection/selectioncollection.h"
54 #include "gromacs/selection/selectionfileoption.h"
55 #include "gromacs/selection/selectionoption.h"
56 #include "gromacs/selection/selectionoptionmanager.h"
57 #include "gromacs/utility/file.h"
58
59 #include "testutils/stringtest.h"
60 #include "testutils/testfilemanager.h"
61
62 namespace
63 {
64
65 class CommandLineHelpWriterTest : public ::gmx::test::StringTestBase
66 {
67     public:
68         void checkHelp(gmx::CommandLineHelpWriter *writer);
69
70         gmx::test::TestFileManager tempFiles_;
71 };
72
73 void CommandLineHelpWriterTest::checkHelp(gmx::CommandLineHelpWriter *writer)
74 {
75     std::string            filename = tempFiles_.getTemporaryFilePath("helptext.txt");
76     gmx::File              file(filename, "w");
77     gmx::HelpWriterContext context(&file, gmx::eHelpOutputFormat_Console);
78     writer->writeHelp(context);
79     file.close();
80
81     checkFileContents(filename, "HelpText");
82 }
83
84
85 /********************************************************************
86  * Tests start here
87  */
88
89 /*
90  * Tests help printing for each option type, but doesn't contain much
91  * variablity in the options.
92  */
93 TEST_F(CommandLineHelpWriterTest, HandlesOptionTypes)
94 {
95     using namespace gmx;
96
97     Options options("test", "Short Description");
98     options.addOption(BooleanOption("bool").description("Boolean option")
99                           .defaultValue(true));
100     options.addOption(BooleanOption("hidden").description("Hidden option")
101                           .hidden().defaultValue(true));
102     options.addOption(IntegerOption("int").description("Integer option")
103                           .defaultValue(2));
104     ivec intvec = {1, 2, 3};
105     options.addOption(IntegerOption("ivec").description("Integer vector option")
106                           .vector().store(intvec));
107     options.addOption(DoubleOption("double").description("Double option")
108                           .defaultValue(2.5));
109     dvec dblvec = {1.1, 2.3, 3.2};
110     options.addOption(DoubleOption("dvec").description("Double vector option")
111                           .vector().store(dblvec));
112     options.addOption(DoubleOption("time").description("Time option (%t)")
113                           .timeValue().defaultValue(10.0));
114     options.addOption(StringOption("string").description("String option")
115                           .defaultValue("test"));
116     const char * const enumValues[] = {"no", "opt1", "opt2", NULL};
117     options.addOption(StringOption("enum").description("Enum option")
118                           .enumValue(enumValues).defaultEnumIndex(0));
119
120     std::string filename;
121     options.addOption(FileNameOption("f")
122                           .description("Input file description")
123                           .filetype(eftTrajectory).inputFile().required()
124                           .defaultBasename("traj"));
125     options.addOption(FileNameOption("lib")
126                           .description("Library file description")
127                           .filetype(eftGenericData).inputFile().libraryFile()
128                           .defaultBasename("libdata"));
129     options.addOption(FileNameOption("io")
130                           .store(&filename)
131                           .description("Input/Output file description")
132                           .filetype(eftGenericData).inputOutputFile()
133                           .defaultBasename("inout"));
134     options.addOption(FileNameOption("o")
135                           .description("Output file description")
136                           .filetype(eftPlot).outputFile());
137
138     options.addOption(SelectionFileOption("sf"));
139     options.addOption(SelectionOption("sel").description("Selection option"));
140
141     CommandLineHelpWriter writer(options);
142     writer.setShowHidden(true);
143     checkHelp(&writer);
144 }
145
146 /*
147  * Tests help printing with file name options with various values that don't
148  * fit into the allocated columns.
149  */
150 TEST_F(CommandLineHelpWriterTest, HandlesLongFileOptions)
151 {
152     using gmx::FileNameOption;
153     using gmx::eftGenericData;
154     using gmx::eftTrajectory;
155
156     gmx::Options options(NULL, NULL);
157     options.addOption(FileNameOption("f")
158                           .description("File name option with a long value")
159                           .filetype(eftTrajectory).inputFile().required()
160                           .defaultBasename("path/to/long/trajectory/name"));
161     options.addOption(FileNameOption("f2")
162                           .description("File name option with a long value")
163                           .filetype(eftTrajectory).inputFile().required()
164                           .defaultBasename("path/to/long/trajectory"));
165     options.addOption(FileNameOption("lib")
166                           .description("File name option with a long value and type")
167                           .filetype(eftTrajectory).inputFile().libraryFile()
168                           .defaultBasename("path/to/long/trajectory/name"));
169     options.addOption(FileNameOption("longfileopt")
170                           .description("File name option with a long name")
171                           .filetype(eftGenericData).inputFile()
172                           .defaultBasename("deffile"));
173     options.addOption(FileNameOption("longfileopt2")
174                           .description("File name option with multiple long fields")
175                           .filetype(eftGenericData).inputFile().libraryFile()
176                           .defaultBasename("path/to/long/file/name"));
177
178     gmx::CommandLineHelpWriter writer(options);
179     checkHelp(&writer);
180 }
181
182 /*
183  * Tests help printing with general options with various values that don't
184  * fit into the allocated columns.
185  */
186 TEST_F(CommandLineHelpWriterTest, HandlesLongOptions)
187 {
188     using gmx::BooleanOption;
189     using gmx::DoubleOption;
190     using gmx::StringOption;
191
192     gmx::Options options(NULL, NULL);
193     options.addOption(BooleanOption("longboolean")
194                           .description("Boolean option with a long name")
195                           .defaultValue(true));
196     dvec dblvec = {1.135, 2.32, 3.2132};
197     options.addOption(DoubleOption("dvec").description("Double vector option")
198                           .vector().store(dblvec));
199     std::vector<std::string> values;
200     values.push_back("A very long string value that overflows even the description column");
201     values.push_back("Another very long string value that overflows even the description column");
202     options.addOption(StringOption("string")
203                           .description("String option with very long values (may "
204                                        "be less relevant with selections having "
205                                        "their own option type)")
206                           .storeVector(&values));
207
208     gmx::CommandLineHelpWriter writer(options);
209     checkHelp(&writer);
210 }
211
212 /*
213  * Tests help printing with selection options with values.
214  */
215 TEST_F(CommandLineHelpWriterTest, HandlesSelectionOptions)
216 {
217     using gmx::SelectionFileOption;
218     using gmx::SelectionOption;
219
220     gmx::Options options(NULL, NULL);
221     options.addOption(SelectionFileOption("sf"));
222     options.addOption(SelectionOption("refsel").required()
223                           .description("Reference selection option"));
224     options.addOption(SelectionOption("sel").required().valueCount(2)
225                           .description("Selection option"));
226     gmx::SelectionCollection    selections;
227     gmx::SelectionOptionManager manager(&selections);
228     setManagerForSelectionOptions(&options, &manager);
229     options.finish();
230     manager.parseRequestedFromString(
231             "resname SOL;"
232             "surface = within 0.5 of resname SOL;"
233             "group \"Protein\" and surface;"
234             "group \"Protein\" and not surface;");
235
236     gmx::CommandLineHelpWriter writer(options);
237     checkHelp(&writer);
238 }
239
240 /*
241  * Tests help printing for multiple sections.
242  */
243 TEST_F(CommandLineHelpWriterTest, HandlesMultipleSections)
244 {
245     using namespace gmx;
246
247     Options options("test", "Main Title");
248     Options subSect1("subsect1", "Subsection 1 Title");
249     Options subSect2("subsect2", "Subsection 2 Title");
250     Options subSect3("subsect3", NULL);
251     options.addSubSection(&subSect1);
252     options.addSubSection(&subSect2);
253     options.addSubSection(&subSect3);
254     options.setDescription("Description for main section.");
255     subSect1.setDescription("Description for subsection 1.");
256     subSect2.setDescription("Description for subsection 2.");
257     subSect3.setDescription("Description for subsection 3.");
258     options.addOption(IntegerOption("main")
259                           .description("Option in main section"));
260     subSect1.addOption(IntegerOption("sub1")
261                            .description("Option in subsection 1"));
262     subSect2.addOption(IntegerOption("sub2")
263                            .description("Option in subsection 2"));
264
265     CommandLineHelpWriter writer(options);
266     writer.setShowDescriptions(true);
267     checkHelp(&writer);
268 }
269
270 } // namespace