Extension completion for FileNameOption.
[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@cbr.su.se>
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/options/basicoptions.h"
50 #include "gromacs/options/filenameoption.h"
51 #include "gromacs/options/options.h"
52 #include "gromacs/selection/selectioncollection.h"
53 #include "gromacs/selection/selectionfileoption.h"
54 #include "gromacs/selection/selectionoption.h"
55 #include "gromacs/selection/selectionoptioninfo.h"
56 #include "gromacs/selection/selectionoptionmanager.h"
57 #include "gromacs/utility/file.h"
58
59 #include "testutils/datapath.h"
60 #include "testutils/stringtest.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     writer->writeHelp(&file);
78     file.close();
79
80     checkFileContents(filename, "HelpText");
81 }
82
83
84 /********************************************************************
85  * Tests start here
86  */
87
88 /*
89  * Tests help printing for each option type, but doesn't contain much
90  * variablity in the options.
91  */
92 TEST_F(CommandLineHelpWriterTest, HandlesOptionTypes)
93 {
94     using namespace gmx;
95
96     Options options("test", "Short Description");
97     options.addOption(BooleanOption("bool").description("Boolean option")
98                         .defaultValue(true));
99     options.addOption(BooleanOption("hidden").description("Hidden option")
100                         .hidden().defaultValue(true));
101     options.addOption(IntegerOption("int").description("Integer option")
102                         .defaultValue(2));
103     ivec intvec = {1, 2, 3};
104     options.addOption(IntegerOption("ivec").description("Integer vector option")
105                         .vector().store(intvec));
106     options.addOption(DoubleOption("double").description("Double option")
107                         .defaultValue(2.5));
108     dvec dblvec = {1.1, 2.3, 3.2};
109     options.addOption(DoubleOption("dvec").description("Double vector option")
110                         .vector().store(dblvec));
111     options.addOption(DoubleOption("time").description("Time option (%t)")
112                         .timeValue().defaultValue(10.0));
113     options.addOption(StringOption("string").description("String option")
114                         .defaultValue("test"));
115     const char * const enumValues[] = {"no", "opt1", "opt2", NULL};
116     options.addOption(StringOption("enum").description("Enum option")
117                         .enumValue(enumValues).defaultEnumIndex(0));
118
119     std::string filename;
120     options.addOption(FileNameOption("f")
121                         .description("Input file description")
122                         .filetype(eftTrajectory).inputFile().required()
123                         .defaultValue("traj"));
124     options.addOption(FileNameOption("lib")
125                         .description("Library file description")
126                         .filetype(eftGenericData).inputFile().libraryFile()
127                         .defaultValueIfSet("libdata"));
128     options.addOption(FileNameOption("io")
129                         .store(&filename)
130                         .description("Input/Output file description")
131                         .filetype(eftGenericData).inputOutputFile()
132                         .defaultValueIfSet("inout"));
133     options.addOption(FileNameOption("o")
134                         .description("Output file description")
135                         .filetype(eftPlot).outputFile());
136
137     options.addOption(SelectionFileOption("sf"));
138     options.addOption(SelectionOption("sel").description("Selection option"));
139
140     CommandLineHelpWriter writer(options);
141     writer.setShowHidden(true);
142     checkHelp(&writer);
143 }
144
145 /*
146  * Tests help printing with file name options with various values that don't
147  * fit into the allocated columns.
148  */
149 TEST_F(CommandLineHelpWriterTest, HandlesLongFileOptions)
150 {
151     using gmx::FileNameOption;
152     using gmx::eftGenericData;
153     using gmx::eftTrajectory;
154
155     gmx::Options options(NULL, NULL);
156     options.addOption(FileNameOption("f")
157                         .description("File name option with a long value")
158                         .filetype(eftTrajectory).inputFile().required()
159                         .defaultValue("path/to/long/trajectory/name"));
160     options.addOption(FileNameOption("f2")
161                         .description("File name option with a long value")
162                         .filetype(eftTrajectory).inputFile().required()
163                         .defaultValue("path/to/long/trajectory"));
164     options.addOption(FileNameOption("lib")
165                         .description("File name option with a long value and type")
166                         .filetype(eftTrajectory).inputFile().libraryFile()
167                         .defaultValue("path/to/long/trajectory/name"));
168     options.addOption(FileNameOption("longfileopt")
169                         .description("File name option with a long name")
170                         .filetype(eftGenericData).inputFile()
171                         .defaultValue("deffile"));
172     options.addOption(FileNameOption("longfileopt2")
173                         .description("File name option with multiple long fields")
174                         .filetype(eftGenericData).inputFile().libraryFile()
175                         .defaultValue("path/to/long/file/name"));
176
177     gmx::CommandLineHelpWriter writer(options);
178     checkHelp(&writer);
179 }
180
181 /*
182  * Tests help printing with general options with various values that don't
183  * fit into the allocated columns.
184  */
185 TEST_F(CommandLineHelpWriterTest, HandlesLongOptions)
186 {
187     using gmx::BooleanOption;
188     using gmx::DoubleOption;
189     using gmx::StringOption;
190
191     gmx::Options options(NULL, NULL);
192     options.addOption(BooleanOption("longboolean")
193                         .description("Boolean option with a long name")
194                         .defaultValue(true));
195     dvec dblvec = {1.135, 2.32, 3.2132};
196     options.addOption(DoubleOption("dvec").description("Double vector option")
197                         .vector().store(dblvec));
198     std::vector<std::string> values;
199     values.push_back("A very long string value that overflows even the description column");
200     values.push_back("Another very long string value that overflows even the description column");
201     options.addOption(StringOption("string")
202                         .description("String option with very long values (may "
203                                      "be less relevant with selections having "
204                                      "their own option type)")
205                         .storeVector(&values));
206
207     gmx::CommandLineHelpWriter writer(options);
208     checkHelp(&writer);
209 }
210
211 /*
212  * Tests help printing with selection options with values.
213  */
214 TEST_F(CommandLineHelpWriterTest, HandlesSelectionOptions)
215 {
216     using gmx::SelectionFileOption;
217     using gmx::SelectionOption;
218
219     gmx::Options options(NULL, NULL);
220     options.addOption(SelectionFileOption("sf"));
221     options.addOption(SelectionOption("refsel").required()
222                         .description("Reference selection option"));
223     options.addOption(SelectionOption("sel").required().valueCount(2)
224                         .description("Selection option"));
225     gmx::SelectionCollection selections;
226     gmx::SelectionOptionManager manager(&selections);
227     setManagerForSelectionOptions(&options, &manager);
228     options.finish();
229     manager.parseRequestedFromString(
230             "resname SOL;"
231             "surface = within 0.5 of resname SOL;"
232             "group \"Protein\" and surface;"
233             "group \"Protein\" and not surface;");
234
235     gmx::CommandLineHelpWriter writer(options);
236     checkHelp(&writer);
237 }
238
239 /*
240  * Tests help printing for multiple sections.
241  */
242 TEST_F(CommandLineHelpWriterTest, HandlesMultipleSections)
243 {
244     using namespace gmx;
245
246     Options options("test", "Main Title");
247     Options subSect1("subsect1", "Subsection 1 Title");
248     Options subSect2("subsect2", "Subsection 2 Title");
249     Options subSect3("subsect3", NULL);
250     options.addSubSection(&subSect1);
251     options.addSubSection(&subSect2);
252     options.addSubSection(&subSect3);
253     options.setDescription("Description for main section.");
254     subSect1.setDescription("Description for subsection 1.");
255     subSect2.setDescription("Description for subsection 2.");
256     subSect3.setDescription("Description for subsection 3.");
257     options.addOption(IntegerOption("main")
258                         .description("Option in main section"));
259     subSect1.addOption(IntegerOption("sub1")
260                          .description("Option in subsection 1"));
261     subSect2.addOption(IntegerOption("sub2")
262                          .description("Option in subsection 2"));
263
264     CommandLineHelpWriter writer(options);
265     writer.setShowDescriptions(true);
266     checkHelp(&writer);
267 }
268
269 } // namespace