Merge release-5-0 into master
[alexxy/gromacs.git] / src / gromacs / commandline / tests / pargs.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 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.
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 /*! \internal \file
36  * \brief
37  * Tests parse_common_args().
38  *
39  * Currently, negative tests are not possible, because those trigger
40  * gmx_fatal() and terminate the whole test binary.
41  *
42  * \author Teemu Murtola <teemu.murtola@gmail.com>
43  * \ingroup module_commandline
44  */
45 #include "gromacs/commandline/pargs.h"
46
47 #include <string>
48
49 #include <gtest/gtest.h>
50
51 #include "gromacs/utility/arrayref.h"
52 #include "gromacs/utility/file.h"
53 #include "gromacs/utility/path.h"
54 #include "gromacs/utility/stringutil.h"
55
56 #include "testutils/cmdlinetest.h"
57 #include "testutils/testasserts.h"
58 #include "testutils/testfilemanager.h"
59
60 namespace
61 {
62
63 using gmx::test::CommandLine;
64
65 class ParseCommonArgsTest : public ::testing::Test
66 {
67     public:
68         enum FileArgumentType
69         {
70             efFull,
71             efNoExtension,
72             efEmptyValue
73         };
74
75         ParseCommonArgsTest()
76             : oenv_(NULL), fileCount_(0)
77         {
78         }
79         virtual ~ParseCommonArgsTest()
80         {
81             output_env_done(oenv_);
82         }
83
84         int nfile() const { return fileCount_; }
85
86         void parseFromArgs(unsigned long           flags,
87                            gmx::ArrayRef<t_filenm> fnm,
88                            gmx::ArrayRef<t_pargs>  pa)
89         {
90             fileCount_ = fnm.size();
91             bool bOk = parse_common_args(&args_.argc(), args_.argv(), flags,
92                                          fnm.size(), fnm.data(),
93                                          pa.size(), pa.data(),
94                                          0, NULL, 0, NULL, &oenv_);
95             EXPECT_TRUE(bOk);
96         }
97         void parseFromArray(gmx::ConstArrayRef<const char *> cmdline,
98                             unsigned long                    flags,
99                             gmx::ArrayRef<t_filenm>          fnm,
100                             gmx::ArrayRef<t_pargs>           pa)
101         {
102             args_.initFromArray(cmdline);
103             parseFromArgs(flags, fnm, pa);
104         }
105         std::string addFileArg(const char *name, const char *extension,
106                                FileArgumentType type)
107         {
108             std::string filename(tempFiles_.getTemporaryFilePath(extension));
109             gmx::File::writeFileFromString(filename, "Dummy file");
110             if (name != NULL)
111             {
112                 args_.append(name);
113                 switch (type)
114                 {
115                     case efFull:
116                         args_.append(filename);
117                         break;
118                     case efNoExtension:
119                         args_.append(gmx::Path::stripExtension(filename));
120                         break;
121                     case efEmptyValue:
122                         break;
123                 }
124             }
125             return filename;
126         }
127
128         // This must be a member that persists until the end of the test,
129         // because string arguments are not duplicated in the output.
130         CommandLine                 args_;
131
132     private:
133         output_env_t                oenv_;
134         size_t                      fileCount_;
135         gmx::test::TestFileManager  tempFiles_;
136 };
137
138 /********************************************************************
139  * Tests for different types of options
140  */
141
142 TEST_F(ParseCommonArgsTest, ParsesIntegerArgs)
143 {
144     int               value1 = 0, value2 = 0, value3 = 3;
145     t_pargs           pa[]   = {
146         { "-i1", FALSE, etINT, {&value1}, "Description" },
147         { "-i2", FALSE, etINT, {&value2}, "Description" },
148         { "-i3", FALSE, etINT, {&value3}, "Description" }
149     };
150     const char *const cmdline[] = {
151         "test", "-i1", "2", "-i2", "-3"
152     };
153     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
154     EXPECT_EQ( 2, value1);
155     EXPECT_EQ(-3, value2);
156     EXPECT_EQ( 3, value3);
157 }
158
159 TEST_F(ParseCommonArgsTest, ParsesInt64Args)
160 {
161     gmx_int64_t       value1 = 0, value2 = 0, value3 = 3;
162     t_pargs           pa[]   = {
163         { "-i1", FALSE, etINT64, {&value1}, "Description" },
164         { "-i2", FALSE, etINT64, {&value2}, "Description" },
165         { "-i3", FALSE, etINT64, {&value3}, "Description" }
166     };
167     const char *const cmdline[] = {
168         "test", "-i1", "2", "-i2", "-3"
169     };
170     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
171     EXPECT_EQ( 2, value1);
172     EXPECT_EQ(-3, value2);
173     EXPECT_EQ( 3, value3);
174 }
175
176 TEST_F(ParseCommonArgsTest, ParsesRealArgs)
177 {
178     real              value1 = 0.0, value2 = 0.0, value3 = 2.5;
179     t_pargs           pa[]   = {
180         { "-r1", FALSE, etREAL, {&value1}, "Description" },
181         { "-r2", FALSE, etREAL, {&value2}, "Description" },
182         { "-r3", FALSE, etREAL, {&value3}, "Description" }
183     };
184     const char *const cmdline[] = {
185         "test", "-r1", "2", "-r2", "-.5"
186     };
187     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
188     EXPECT_EQ( 2.0, value1);
189     EXPECT_EQ(-0.5, value2);
190     EXPECT_EQ( 2.5, value3);
191 }
192
193 TEST_F(ParseCommonArgsTest, ParsesStringArgs)
194 {
195     const char       *value1 = "def", *value2 = "", *value3 = "default";
196     t_pargs           pa[]   = {
197         { "-s1", FALSE, etSTR, {&value1}, "Description" },
198         { "-s2", FALSE, etSTR, {&value2}, "Description" },
199         { "-s3", FALSE, etSTR, {&value3}, "Description" }
200     };
201     const char *const cmdline[] = {
202         "test", "-s1", "", "-s2", "test"
203     };
204     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
205     EXPECT_STREQ("", value1);
206     EXPECT_STREQ("test", value2);
207     EXPECT_STREQ("default", value3);
208 }
209
210 TEST_F(ParseCommonArgsTest, ParsesBooleanArgs)
211 {
212     gmx_bool          value1 = TRUE, value2 = FALSE, value3 = TRUE;
213     t_pargs           pa[]   = {
214         { "-b1", FALSE, etBOOL, {&value1}, "Description" },
215         { "-b2", FALSE, etBOOL, {&value2}, "Description" },
216         { "-b3", FALSE, etBOOL, {&value3}, "Description" }
217     };
218     const char *const cmdline[] = {
219         "test", "-nob1", "-b2"
220     };
221     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
222     EXPECT_FALSE(value1);
223     EXPECT_TRUE(value2);
224     EXPECT_TRUE(value3);
225 }
226
227 TEST_F(ParseCommonArgsTest, ParsesVectorArgs)
228 {
229     rvec              value1 = {0, 0, 0}, value2 = {0, 0, 0}, value3 = {1, 2, 3};
230     t_pargs           pa[]   = {
231         { "-v1", FALSE, etRVEC, {&value1}, "Description" },
232         { "-v2", FALSE, etRVEC, {&value2}, "Description" },
233         { "-v3", FALSE, etRVEC, {&value3}, "Description" }
234     };
235     const char *const cmdline[] = {
236         "test", "-v1", "2", "1", "3", "-v2", "1"
237     };
238     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
239     EXPECT_EQ(2.0, value1[XX]);
240     EXPECT_EQ(1.0, value1[YY]);
241     EXPECT_EQ(3.0, value1[ZZ]);
242     EXPECT_EQ(1.0, value2[XX]);
243     EXPECT_EQ(1.0, value2[YY]);
244     EXPECT_EQ(1.0, value2[ZZ]);
245     EXPECT_EQ(1.0, value3[XX]);
246     EXPECT_EQ(2.0, value3[YY]);
247     EXPECT_EQ(3.0, value3[ZZ]);
248 }
249
250 TEST_F(ParseCommonArgsTest, ParsesTimeArgs)
251 {
252     real              value1 = 1.0, value2 = 2.0, value3 = 2.5;
253     t_pargs           pa[]   = {
254         { "-t1", FALSE, etTIME, {&value1}, "Description" },
255         { "-t2", FALSE, etTIME, {&value2}, "Description" },
256         { "-t3", FALSE, etTIME, {&value3}, "Description" }
257     };
258     const char *const cmdline[] = {
259         "test", "-t1", "2", "-t2", "-.5"
260     };
261     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
262     EXPECT_EQ( 2.0, value1);
263     EXPECT_EQ(-0.5, value2);
264     EXPECT_EQ( 2.5, value3);
265 }
266
267 TEST_F(ParseCommonArgsTest, ParsesTimeArgsWithTimeUnit)
268 {
269     real              value1 = 1.0, value2 = 2.0, value3 = 2.5;
270     t_pargs           pa[]   = {
271         { "-t1", FALSE, etTIME, {&value1}, "Description" },
272         { "-t2", FALSE, etTIME, {&value2}, "Description" },
273         { "-t3", FALSE, etTIME, {&value3}, "Description" }
274     };
275     const char *const cmdline[] = {
276         "test", "-t1", "2", "-t2", "-.5", "-tu", "ns"
277     };
278     parseFromArray(cmdline, PCA_TIME_UNIT, gmx::EmptyArrayRef(), pa);
279     EXPECT_EQ( 2000.0, value1);
280     EXPECT_EQ(-500.0, value2);
281     EXPECT_EQ( 2.5, value3);
282 }
283
284 TEST_F(ParseCommonArgsTest, ParsesEnumArgs)
285 {
286     const char       *value1[] = {NULL, "none", "on", "off", NULL };
287     const char       *value2[] = {NULL, "def", "value", "value_other", NULL };
288     const char       *value3[] = {NULL, "default", "value", NULL };
289     t_pargs           pa[]     = {
290         { "-s1", FALSE, etENUM, {value1}, "Description" },
291         { "-s2", FALSE, etENUM, {value2}, "Description" },
292         { "-s3", FALSE, etENUM, {value3}, "Description" }
293     };
294     const char *const cmdline[] = {
295         "test", "-s1", "off", "-s2", "val"
296     };
297     parseFromArray(cmdline, 0, gmx::EmptyArrayRef(), pa);
298     EXPECT_STREQ("off", value1[0]);
299     EXPECT_STREQ("value", value2[0]);
300     EXPECT_STREQ("default", value3[0]);
301     EXPECT_EQ(value1[nenum(value1)], value1[0]);
302     EXPECT_EQ(value2[nenum(value2)], value2[0]);
303     EXPECT_EQ(value3[nenum(value3)], value3[0]);
304 }
305
306 /********************************************************************
307  * Tests for file name options (output files, not dependent on file system)
308  */
309
310 TEST_F(ParseCommonArgsTest, ParsesFileArgs)
311 {
312     t_filenm          fnm[] = {
313         { efXVG, "-o1", "out1", ffOPTWR },
314         { efXVG, "-o2", "out2", ffOPTWR },
315         { efXVG, "-om", "outm", ffWRMULT },
316         { efXVG, "-om2", "outm2", ffWRMULT }
317     };
318     const char *const cmdline[] = {
319         "test", "-o1", "-o2", "test", "-om", "test1", "test2.xvg", "-om2"
320     };
321     parseFromArray(cmdline, 0, fnm, gmx::EmptyArrayRef());
322     EXPECT_STREQ("out1.xvg", opt2fn_null("-o1", nfile(), fnm));
323     EXPECT_STREQ("test.xvg", opt2fn_null("-o2", nfile(), fnm));
324     char **files;
325     EXPECT_EQ(2, opt2fns(&files, "-om", nfile(), fnm));
326     EXPECT_STREQ("test1.xvg", files[0]);
327     EXPECT_STREQ("test2.xvg", files[1]);
328     EXPECT_STREQ("outm2.xvg", opt2fn("-om2", nfile(), fnm));
329     done_filenms(nfile(), fnm);
330 }
331
332 TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaults)
333 {
334     t_filenm          fnm[] = {
335         { efTPS, NULL,  NULL,   ffWRITE },
336         { efTRX, "-f2", NULL,   ffOPTWR },
337         { efTRX, "-f3", "trj3", ffWRITE },
338         { efXVG, "-o",  "out",  ffWRITE },
339         { efXVG, "-om", "outm", ffWRMULT }
340     };
341     const char *const cmdline[] = {
342         "test"
343     };
344     parseFromArray(cmdline, 0, fnm, gmx::EmptyArrayRef());
345     EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm));
346     EXPECT_STREQ("traj.xtc", opt2fn("-f2", nfile(), fnm));
347     EXPECT_NULL(opt2fn_null("-f2", nfile(), fnm));
348     EXPECT_STREQ("trj3.xtc", opt2fn("-f3", nfile(), fnm));
349     EXPECT_STREQ("out.xvg", opt2fn("-o", nfile(), fnm));
350     EXPECT_STREQ("outm.xvg", opt2fn("-om", nfile(), fnm));
351     done_filenms(nfile(), fnm);
352 }
353
354 TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaultFileName)
355 {
356     t_filenm          fnm[] = {
357         { efTPS, "-s",  NULL,   ffWRITE },
358         { efTRX, "-f2", NULL,   ffWRITE },
359         { efTRX, "-f3", "trj3", ffWRITE },
360         { efXVG, "-o",  "out",  ffWRITE },
361         { efXVG, "-om", "outm", ffWRMULT }
362     };
363     const char *const cmdline[] = {
364         "test", "-deffnm", "def", "-f2", "other", "-o"
365     };
366     parseFromArray(cmdline, PCA_CAN_SET_DEFFNM, fnm, gmx::EmptyArrayRef());
367     EXPECT_STREQ("def.tpr", ftp2fn(efTPS, nfile(), fnm));
368     EXPECT_STREQ("other.xtc", opt2fn("-f2", nfile(), fnm));
369     EXPECT_STREQ("def.xtc", opt2fn("-f3", nfile(), fnm));
370     EXPECT_STREQ("def.xvg", opt2fn("-o", nfile(), fnm));
371     EXPECT_STREQ("def.xvg", opt2fn("-om", nfile(), fnm));
372     done_filenms(nfile(), fnm);
373 }
374
375 /********************************************************************
376  * Tests for file name options (input files, dependent on file system contents)
377  */
378
379 TEST_F(ParseCommonArgsTest, HandlesNonExistentInputFiles)
380 {
381     t_filenm          fnm[] = {
382         { efTPS, "-s",  NULL,   ffREAD },
383         { efTRX, "-f",  "trj",  ffREAD },
384         { efTRX, "-f2", "trj2", ffREAD },
385         { efTRX, "-f3", "trj3", ffREAD },
386         { efTRX, "-f4", "trj4", ffREAD },
387         { efGRO, "-g",  "cnf",  ffREAD },
388         { efGRO, "-g2", "cnf2", ffREAD }
389     };
390     const char *const cmdline[] = {
391         "test", "-f2", "-f3", "other", "-f4", "trj.gro", "-g2", "foo"
392     };
393     parseFromArray(cmdline, 0, fnm, gmx::EmptyArrayRef());
394     EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm));
395     EXPECT_STREQ("trj.xtc", opt2fn("-f", nfile(), fnm));
396     EXPECT_STREQ("trj2.xtc", opt2fn("-f2", nfile(), fnm));
397     EXPECT_STREQ("other.xtc", opt2fn("-f3", nfile(), fnm));
398     EXPECT_STREQ("trj.gro", opt2fn("-f4", nfile(), fnm));
399     EXPECT_STREQ("cnf.gro", opt2fn("-g", nfile(), fnm));
400     EXPECT_STREQ("foo.gro", opt2fn("-g2", nfile(), fnm));
401     done_filenms(nfile(), fnm);
402 }
403
404 TEST_F(ParseCommonArgsTest, HandlesCompressedFiles)
405 {
406     t_filenm          fnm[] = {
407         { efTRX, "-f", NULL, ffREAD },
408         { efGRO, "-g", NULL, ffREAD }
409     };
410     args_.append("test");
411     std::string       expectedF = addFileArg("-f", ".pdb.gz", efFull);
412     std::string       expectedG = addFileArg("-g", ".gro.Z", efFull);
413     expectedF = gmx::Path::stripExtension(expectedF);
414     expectedG = gmx::Path::stripExtension(expectedG);
415     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
416     EXPECT_EQ(expectedF, opt2fn("-f", nfile(), fnm));
417     EXPECT_EQ(expectedG, opt2fn("-g", nfile(), fnm));
418     done_filenms(nfile(), fnm);
419 }
420
421 TEST_F(ParseCommonArgsTest, AcceptsUnknownTrajectoryExtension)
422 {
423     t_filenm          fnm[] = {
424         { efTRX, "-f", NULL, ffREAD }
425     };
426     args_.append("test");
427     std::string       expected = addFileArg("-f", ".foo", efFull);
428     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
429     EXPECT_EQ(expected, opt2fn("-f", nfile(), fnm));
430     done_filenms(nfile(), fnm);
431 }
432
433 TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFile)
434 {
435     t_filenm          fnm[] = {
436         { efTRX, "-f1", NULL, ffREAD },
437         { efTRX, "-f2", NULL, ffREAD },
438         { efTRX, "-f3", NULL, ffREAD },
439         { efTRX, "-f4", NULL, ffREAD }
440     };
441     args_.append("test");
442     std::string       expected1 = addFileArg("-f1", "1.xtc", efNoExtension);
443     std::string       expected2 = addFileArg("-f2", "2.gro", efNoExtension);
444     std::string       expected3 = addFileArg("-f3", "3.tng", efNoExtension);
445     std::string       expected4 = addFileArg("-f4", ".gro", efEmptyValue);
446     std::string       def4      = gmx::Path::stripExtension(expected4);
447     fnm[3].fn = def4.c_str();
448     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
449     EXPECT_EQ(expected1, opt2fn("-f1", nfile(), fnm));
450     EXPECT_EQ(expected2, opt2fn("-f2", nfile(), fnm));
451     EXPECT_EQ(expected3, opt2fn("-f3", nfile(), fnm));
452     EXPECT_EQ(expected4, opt2fn("-f4", nfile(), fnm));
453     done_filenms(nfile(), fnm);
454 }
455
456 TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFileWithDefaultFileName)
457 {
458     t_filenm          fnm[] = {
459         { efTRX, "-f1", NULL,  ffREAD },
460         { efTPX, "-f2", "foo", ffREAD },
461         { efTRX, "-f3", NULL,  ffREAD },
462         { efSTX, "-f4", NULL,  ffREAD }
463     };
464     args_.append("test");
465     std::string       expected1 = addFileArg("-f1", "1.trr", efNoExtension);
466     std::string       expected2 = addFileArg("-f2", ".tpa", efEmptyValue);
467     std::string       expected3 = addFileArg("-f3", ".trr", efEmptyValue);
468     std::string       expected4 = addFileArg(NULL, ".pdb", efEmptyValue);
469     std::string       deffnm    = gmx::Path::stripExtension(expected3);
470     args_.append("-deffnm");
471     args_.append(deffnm);
472     parseFromArgs(PCA_CAN_SET_DEFFNM, fnm, gmx::EmptyArrayRef());
473     EXPECT_EQ(expected1, opt2fn("-f1", nfile(), fnm));
474     EXPECT_EQ(expected2, opt2fn("-f2", nfile(), fnm));
475     EXPECT_EQ(expected3, opt2fn("-f3", nfile(), fnm));
476     EXPECT_EQ(expected4, opt2fn("-f4", nfile(), fnm));
477     done_filenms(nfile(), fnm);
478 }
479
480 /********************************************************************
481  * Tests for general behavior
482  */
483
484 TEST_F(ParseCommonArgsTest, HandlesNonReadNode)
485 {
486     t_filenm          fnm[] = {
487         { efTPS, "-s",  NULL,  ffREAD },
488         { efTRX, "-f",  NULL,  ffREAD },
489         { efTRX, "-f2", NULL,  ffREAD }
490     };
491     const char *const cmdline[] = {
492         "test", "-f", "-f2", "other"
493     };
494     parseFromArray(cmdline, PCA_NOT_READ_NODE, fnm, gmx::EmptyArrayRef());
495     EXPECT_NULL(fnm[0].fns);
496     EXPECT_NULL(fnm[1].fns);
497     EXPECT_NULL(fnm[2].fns);
498     done_filenms(nfile(), fnm);
499 }
500
501 TEST_F(ParseCommonArgsTest, HandlesNonReadNodeWithDefaultFileName)
502 {
503     t_filenm          fnm[] = {
504         { efTPS, "-s",  NULL,  ffREAD },
505         { efTRX, "-f",  NULL,  ffREAD },
506         { efTRX, "-f2", NULL,  ffREAD }
507     };
508     const char *const cmdline[] = {
509         "test", "-deffnm", "def", "-f", "-f2", "other"
510     };
511     parseFromArray(cmdline, PCA_CAN_SET_DEFFNM | PCA_NOT_READ_NODE, fnm, gmx::EmptyArrayRef());
512     EXPECT_NULL(fnm[0].fns);
513     EXPECT_NULL(fnm[1].fns);
514     EXPECT_NULL(fnm[2].fns);
515     done_filenms(nfile(), fnm);
516 }
517
518 TEST_F(ParseCommonArgsTest, CanKeepUnknownArgs)
519 {
520     int               ivalue = 0;
521     gmx_bool          bvalue = FALSE;
522     t_pargs           pa[]   = {
523         { "-i", FALSE, etINT, {&ivalue}, "Description" },
524         { "-b", FALSE, etBOOL, {&bvalue}, "Description" },
525     };
526     t_filenm          fnm[] = {
527         { efXVG, "-o1", "out1", ffOPTWR },
528         { efXVG, "-o2", "out2", ffOPTWR }
529     };
530     const char *const cmdline[] = {
531         "test", "foo", "-unk", "-o1", "-unk2", "-o2", "test",
532         "-i", "2", "-unk3", "-b", "-unk4"
533     };
534     parseFromArray(cmdline, PCA_NOEXIT_ON_ARGS, fnm, pa);
535     EXPECT_EQ(2, ivalue);
536     EXPECT_TRUE(bvalue);
537     EXPECT_STREQ("out1.xvg", opt2fn_null("-o1", nfile(), fnm));
538     EXPECT_STREQ("test.xvg", opt2fn_null("-o2", nfile(), fnm));
539     EXPECT_EQ(6, args_.argc());
540     EXPECT_STREQ(cmdline[0],  args_.arg(0));
541     EXPECT_STREQ(cmdline[1],  args_.arg(1));
542     EXPECT_STREQ(cmdline[2],  args_.arg(2));
543     EXPECT_STREQ(cmdline[4],  args_.arg(3));
544     EXPECT_STREQ(cmdline[9],  args_.arg(4));
545     EXPECT_STREQ(cmdline[11], args_.arg(5));
546     done_filenms(nfile(), fnm);
547 }
548
549 } // namespace