1 // ==========================================================================
2 // arg_parse
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Stephan Aiche <stephan.aiche@fu-berlin.de>
33 // ==========================================================================
34
35 #ifndef SEQAN_TESTS_ARG_PARSE_TEST_ARG_PARSE_H_
36 #define SEQAN_TESTS_ARG_PARSE_TEST_ARG_PARSE_H_
37
38 #include <seqan/basic.h>
39 #include <seqan/sequence.h>
40
41
42 #include <seqan/arg_parse.h> // Header under test
43
44 #include <seqan/basic.h>
45 #include <iostream>
46
47 using namespace std;
48
49 const char * A_INT_0 = "test";
50 const char * A_INT_1 = "-i";
51 const char * A_INT_2 = "--integer";
52 const char * A_INT_3 = "1";
53 const char * A_INT_5 = "3000000000"; // too large!
54
55 const char * A_INT64_0 = "test";
56 const char * A_INT64_1 = "-i";
57 const char * A_INT64_2 = "--int64";
58 const char * A_INT64_3 = "3000000000";
59 const char * A_INT64_5 = "not-an-int";
60
61 const char * A_DOUBLE_0 = "test";
62 const char * A_DOUBLE_1 = "-d";
63 const char * A_DOUBLE_2 = "--double";
64 const char * A_DOUBLE_3 = "1.56";
65 const char * A_DOUBLE_5 = "not-a-double";
66 const char * A_DOUBLE_6 = "6.0221418e23";
67
68 const char * A_STRING_0 = "test";
69 const char * A_STRING_1 = "-s";
70 const char * A_STRING_2 = "--string";
71 const char * A_STRING_3 = "this-is-a-string-value";
72
73 const char * A_BOOL = "test-boolean-flags";
74 const char * A_BOOL_1 = "-b";
75 const char * A_BOOL_2 = "-c";
76 const char * A_BOOL_3 = "-bc";
77 const char * A_BOOL_4 = "-cb";
78
79 const char * A_BOOL_ARG = "test-boolean-argument";
80 const char * A_BOOL_ARG_SHORT = "-b";
81 const char * A_BOOL_ARG_OFF = "OFF";
82 const char * A_BOOL_ARG_ON = "ON";
83
84 const char * A_IN_FILE_0 = "test";
85 const char * A_IN_FILE_1 = "-i";
86 const char * A_IN_FILE_2 = "--in";
87 const char * A_IN_FILE_3 = "input.fasta";
88
89 const char * A_OUT_FILE_0 = "test";
90 const char * A_OUT_FILE_1 = "-o";
91 const char * A_OUT_FILE_2 = "--out";
92 const char * A_OUT_FILE_3 = "output.fasta";
93 const char * A_OUT_FILE_4 = "output.tar.gz";
94 const char * A_OUT_FILE_5 = "output.txt";
95 const char * A_OUT_FILE_6 = "--out-file-ext";
96 const char * A_OUT_FILE_7 = "fasta";
97 const char * A_OUT_FILE_8 = "txt";
98
99 const char * A_ARGUMENT_0 = "test";
100 const char * A_ARGUMENT_1 = "argument1";
101 const char * A_ARGUMENT_2 = "argument2";
102 const char * A_ARGUMENT_3 = "argument3";
103 const char * A_ARGUMENT_INT_4 = "-10";
104 const char * A_ARGUMENT_DOUBLE_5 = "6.0221418e23";
105
106 const char * A_TUPLE_LIST = "test_tuple_list";
107 const char * A_TUPLE_LIST_L = "-l";
108 const char * A_TUPLE_LIST_L_1 = "10";
109 const char * A_TUPLE_LIST_L_2 = "20";
110 const char * A_TUPLE_LIST_L_3 = "30";
111 const char * A_TUPLE_LIST_L_4 = "40";
112
113 const char * A_TUPLE_LIST_DL = "-k";
114 const char * A_TUPLE_LIST_DL_1 = "5.1";
115 const char * A_TUPLE_LIST_DL_2 = "6.2";
116 const char * A_TUPLE_LIST_DL_3 = "7.3";
117 const char * A_TUPLE_LIST_DL_4 = "5.5";
118 const char * A_TUPLE_LIST_DL_5 = "6.6";
119 const char * A_TUPLE_LIST_DL_6 = "7.7";
120
121 namespace seqan {
122
123 // moved initialization of cmd parser out of the test functions
124 // to have single place to change in case of interface changes
125 // or test extensions
setupDoubleParser(ArgumentParser & parser)126 void setupDoubleParser(ArgumentParser & parser)
127 {
128 addOption(parser, ArgParseOption("d", "double", "set a double option", ArgParseArgument::DOUBLE));
129 }
130
setupIntegerParser(ArgumentParser & parser)131 void setupIntegerParser(ArgumentParser & parser)
132 {
133 addOption(parser, ArgParseOption("i", "integer", "set an integer option", ArgParseArgument::INTEGER));
134 }
135
setupInt64Parser(ArgumentParser & parser)136 void setupInt64Parser(ArgumentParser & parser)
137 {
138 addOption(parser, ArgParseOption("i", "int64", "set a 64 bit integer option", ArgParseArgument::INT64));
139 }
140
setupStringParser(ArgumentParser & parser)141 void setupStringParser(ArgumentParser & parser)
142 {
143 addOption(parser, ArgParseOption("s", "string", "set a string option", ArgParseArgument::STRING, "", true));
144 }
145
setupInputFileParser(ArgumentParser & parser)146 void setupInputFileParser(ArgumentParser & parser)
147 {
148 addOption(parser, ArgParseOption("i", "in", "set an input file", ArgParseArgument::INPUT_FILE));
149 }
150
setupOutputFileParser(ArgumentParser & parser)151 void setupOutputFileParser(ArgumentParser & parser)
152 {
153 addOption(parser, ArgParseOption("o", "out", "set an output file", ArgParseArgument::OUTPUT_FILE));
154 }
155
setupBooleanParser(ArgumentParser & parser)156 void setupBooleanParser(ArgumentParser & parser)
157 {
158 addOption(parser, ArgParseOption("b", "mybool", "set a bool", ArgParseArgument::BOOL));
159 }
160
SEQAN_DEFINE_TEST(test_unset_value)161 SEQAN_DEFINE_TEST(test_unset_value)
162 {
163 ArgumentParser parser;
164 setupIntegerParser(parser);
165
166 int argc = 1;
167 const char * argv[1] = {A_INT_0};
168
169 std::stringstream error_stream;
170 std::stringstream outputStream;
171
172 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
173 SEQAN_ASSERT_EQ(error_stream.str(), "");
174 SEQAN_ASSERT_EQ(outputStream.str(), "");
175
176 int integerValue = 584864836;
177 SEQAN_ASSERT(!getOptionValue(integerValue, parser, "integer"));
178 SEQAN_ASSERT_EQ(integerValue, 584864836);
179 }
180
SEQAN_DEFINE_TEST(test_unset_values)181 SEQAN_DEFINE_TEST(test_unset_values)
182 {
183 ArgumentParser parser;
184 setupIntegerParser(parser);
185
186 int argc = 1;
187 const char * argv[1] = {A_INT_0};
188
189 std::stringstream error_stream;
190 std::stringstream outputStream;
191
192 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
193 SEQAN_ASSERT_EQ(error_stream.str(), "");
194 SEQAN_ASSERT_EQ(outputStream.str(), "");
195
196 std::vector<std::string> values = getOptionValues(parser, "integer");
197 SEQAN_ASSERT_EQ(values.size(), 0u);
198 }
199
SEQAN_DEFINE_TEST(test_boolean_argument_on)200 SEQAN_DEFINE_TEST(test_boolean_argument_on)
201 {
202
203 ArgumentParser parser;
204 setupBooleanParser(parser);
205
206 int argc = 3;
207 const char * argv[3] = {A_BOOL_ARG, A_BOOL_ARG_SHORT, A_BOOL_ARG_ON};
208
209 std::stringstream error_stream;
210 std::stringstream outputStream;
211
212 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
213 SEQAN_ASSERT_EQ(error_stream.str(), "");
214 SEQAN_ASSERT_EQ(outputStream.str(), "");
215
216 bool booleanValue = 0;
217 SEQAN_ASSERT(getOptionValue(booleanValue, parser, "mybool"));
218 SEQAN_ASSERT_EQ(booleanValue, true);
219 }
220
SEQAN_DEFINE_TEST(test_boolean_argument_off)221 SEQAN_DEFINE_TEST(test_boolean_argument_off)
222 {
223
224 ArgumentParser parser;
225 setupBooleanParser(parser);
226
227 int argc = 3;
228 const char * argv[3] = {A_BOOL_ARG, A_BOOL_ARG_SHORT, A_BOOL_ARG_OFF};
229
230 std::stringstream error_stream;
231 std::stringstream outputStream;
232
233 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
234 SEQAN_ASSERT_EQ(error_stream.str(), "");
235 SEQAN_ASSERT_EQ(outputStream.str(), "");
236
237 bool booleanValue = 1;
238 SEQAN_ASSERT(getOptionValue(booleanValue, parser, "mybool"));
239 SEQAN_ASSERT_EQ(booleanValue, false);
240 }
241
SEQAN_DEFINE_TEST(test_int_short_argument)242 SEQAN_DEFINE_TEST(test_int_short_argument)
243 {
244
245 ArgumentParser parser;
246 setupIntegerParser(parser);
247
248 int argc = 3;
249 const char * argv[3] = {A_INT_0, A_INT_1, A_INT_3};
250
251 std::stringstream error_stream;
252 std::stringstream outputStream;
253
254 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
255 SEQAN_ASSERT_EQ(error_stream.str(), "");
256 SEQAN_ASSERT_EQ(outputStream.str(), "");
257
258 int integerValue = 0;
259 SEQAN_ASSERT(getOptionValue(integerValue, parser, "integer"));
260 SEQAN_ASSERT_EQ(integerValue, 1);
261 }
262
SEQAN_DEFINE_TEST(test_int_long_argument)263 SEQAN_DEFINE_TEST(test_int_long_argument)
264 {
265
266 ArgumentParser parser;
267 setupIntegerParser(parser);
268
269 int argc = 3;
270 const char * argv[3] = {A_INT_0, A_INT_2, A_INT_3};
271
272 std::stringstream error_stream;
273 std::stringstream outputStream;
274
275 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
276 SEQAN_ASSERT_EQ(error_stream.str(), "");
277 SEQAN_ASSERT_EQ(outputStream.str(), "");
278
279 int integerValue = 0;
280 SEQAN_ASSERT(getOptionValue(integerValue, parser, "integer"));
281 SEQAN_ASSERT_EQ(integerValue, 1);
282 }
283
SEQAN_DEFINE_TEST(test_non_int_argument)284 SEQAN_DEFINE_TEST(test_non_int_argument)
285 {
286
287 ArgumentParser parser;
288 setupIntegerParser(parser);
289
290 int argc = 3;
291 const char * argv[3] = {A_INT_0, A_INT_1, A_INT_5};
292
293 std::stringstream error_stream;
294 std::stringstream outputStream;
295
296 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
297 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value '3000000000' cannot be casted to integer\n");
298 SEQAN_ASSERT_EQ(outputStream.str(), "");
299 }
300
SEQAN_DEFINE_TEST(test_int64_short_argument)301 SEQAN_DEFINE_TEST(test_int64_short_argument)
302 {
303
304 ArgumentParser parser;
305 setupInt64Parser(parser);
306
307 int argc = 3;
308 const char * argv[3] = {A_INT64_0, A_INT64_1, A_INT64_3};
309
310 std::stringstream error_stream;
311 std::stringstream outputStream;
312
313 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
314 SEQAN_ASSERT_EQ(error_stream.str(), "");
315 SEQAN_ASSERT_EQ(outputStream.str(), "");
316
317 int64_t integerValue = 0;
318 SEQAN_ASSERT(getOptionValue(integerValue, parser, "int64"));
319 SEQAN_ASSERT_EQ(integerValue, 3000000000ll);
320 }
321
SEQAN_DEFINE_TEST(test_int64_long_argument)322 SEQAN_DEFINE_TEST(test_int64_long_argument)
323 {
324
325 ArgumentParser parser;
326 setupInt64Parser(parser);
327
328 int argc = 3;
329 const char * argv[3] = {A_INT64_0, A_INT64_2, A_INT64_3};
330
331 std::stringstream error_stream;
332 std::stringstream outputStream;
333
334 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
335 SEQAN_ASSERT_EQ(error_stream.str(), "");
336 SEQAN_ASSERT_EQ(outputStream.str(), "");
337
338 int64_t integerValue = 0;
339 SEQAN_ASSERT(getOptionValue(integerValue, parser, "int64"));
340 SEQAN_ASSERT_EQ(integerValue, 3000000000ll);
341 }
342
SEQAN_DEFINE_TEST(test_non_int64_argument)343 SEQAN_DEFINE_TEST(test_non_int64_argument)
344 {
345
346 ArgumentParser parser;
347 setupInt64Parser(parser);
348
349 int argc = 3;
350 const char * argv[3] = {A_INT64_0, A_INT64_1, A_INT64_5};
351
352 std::stringstream error_stream;
353 std::stringstream outputStream;
354
355 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
356 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value 'not-an-int' cannot be casted to int64\n");
357 SEQAN_ASSERT_EQ(outputStream.str(), "");
358 }
359
SEQAN_DEFINE_TEST(test_double_short_argument)360 SEQAN_DEFINE_TEST(test_double_short_argument)
361 {
362
363 ArgumentParser parser;
364 setupDoubleParser(parser);
365
366 int argc = 3;
367 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_1, A_DOUBLE_3};
368
369 std::stringstream error_stream;
370 std::stringstream outputStream;
371
372 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
373 SEQAN_ASSERT_EQ(error_stream.str(), "");
374 SEQAN_ASSERT_EQ(outputStream.str(), "");
375
376 double doubleValue = 0.0;
377 SEQAN_ASSERT(getOptionValue(doubleValue, parser, "double"));
378 SEQAN_ASSERT_EQ(doubleValue, 1.56);
379 }
380
SEQAN_DEFINE_TEST(test_double_long_argument)381 SEQAN_DEFINE_TEST(test_double_long_argument)
382 {
383
384 ArgumentParser parser;
385 setupDoubleParser(parser);
386
387 int argc = 3;
388 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_2, A_DOUBLE_3};
389
390 std::stringstream error_stream;
391 std::stringstream outputStream;
392
393 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
394 SEQAN_ASSERT_EQ(error_stream.str(), "");
395 SEQAN_ASSERT_EQ(outputStream.str(), "");
396
397 double doubleValue = 0.0;
398 SEQAN_ASSERT(getOptionValue(doubleValue, parser, "double"));
399 SEQAN_ASSERT_EQ(doubleValue, 1.56);
400 }
401
SEQAN_DEFINE_TEST(test_non_double_argument)402 SEQAN_DEFINE_TEST(test_non_double_argument)
403 {
404
405 ArgumentParser parser;
406 setupDoubleParser(parser);
407
408 int argc = 3;
409 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_1, A_DOUBLE_5};
410
411 std::stringstream error_stream;
412 std::stringstream outputStream;
413
414 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
415 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value 'not-a-double' cannot be casted to double\n");
416 SEQAN_ASSERT_EQ(outputStream.str(), "");
417 }
418
SEQAN_DEFINE_TEST(test_double_scientific_notation)419 SEQAN_DEFINE_TEST(test_double_scientific_notation)
420 {
421
422 ArgumentParser parser;
423 setupDoubleParser(parser);
424
425 int argc = 3;
426 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_1, A_DOUBLE_6};
427
428 std::stringstream error_stream;
429 std::stringstream outputStream;
430
431 double doubleValue = 0.0;
432 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
433 SEQAN_ASSERT_EQ(error_stream.str(), "");
434 SEQAN_ASSERT_EQ(outputStream.str(), "");
435
436 SEQAN_ASSERT(getOptionValue(doubleValue, parser, "double"));
437 SEQAN_ASSERT_EQ(doubleValue, 6.0221418e23);
438 }
439
SEQAN_DEFINE_TEST(test_string_short_argument)440 SEQAN_DEFINE_TEST(test_string_short_argument)
441 {
442
443 ArgumentParser parser;
444 setupStringParser(parser);
445
446 int argc = 3;
447 const char * argv[3] = {A_STRING_0, A_STRING_1, A_STRING_3};
448
449 std::stringstream error_stream;
450 std::stringstream outputStream;
451
452 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
453 SEQAN_ASSERT_EQ(error_stream.str(), "");
454 SEQAN_ASSERT_EQ(outputStream.str(), "");
455
456 CharString value;
457 SEQAN_ASSERT(getOptionValue(value, parser, "string"));
458 SEQAN_ASSERT_EQ(value, "this-is-a-string-value");
459 }
460
SEQAN_DEFINE_TEST(test_string_long_argument)461 SEQAN_DEFINE_TEST(test_string_long_argument)
462 {
463
464 ArgumentParser parser;
465 setupStringParser(parser);
466
467 int argc = 3;
468 const char * argv[3] = {A_STRING_0, A_STRING_2, A_STRING_3};
469
470 std::stringstream error_stream;
471 std::stringstream outputStream;
472 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
473 SEQAN_ASSERT_EQ(error_stream.str(), "");
474 SEQAN_ASSERT_EQ(outputStream.str(), "");
475
476 CharString value;
477 SEQAN_ASSERT(getOptionValue(value, parser, "string"));
478 SEQAN_ASSERT_EQ(value, "this-is-a-string-value");
479 }
480
SEQAN_DEFINE_TEST(test_string_missing_argument)481 SEQAN_DEFINE_TEST(test_string_missing_argument)
482 {
483
484 ArgumentParser parser;
485 setupStringParser(parser);
486
487 int argc = 2;
488 const char * argv[2] = {A_STRING_0, A_STRING_2};
489
490 std::stringstream error_stream;
491 std::stringstream outputStream;
492
493 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
494 SEQAN_ASSERT_EQ(error_stream.str(), "test: option requires an argument -- string\n");
495 SEQAN_ASSERT_EQ(outputStream.str(), "");
496 }
497
SEQAN_DEFINE_TEST(test_string_list)498 SEQAN_DEFINE_TEST(test_string_list)
499 {
500 ArgumentParser parser;
501 setupStringParser(parser);
502
503 int argc = 7;
504 const char * argv[7] = {A_STRING_0, A_STRING_1, A_STRING_3, A_STRING_2, A_STRING_3, A_STRING_1, A_STRING_3};
505
506 std::stringstream error_stream;
507 std::stringstream outputStream;
508
509 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
510 SEQAN_ASSERT_EQ(error_stream.str(), "");
511 SEQAN_ASSERT_EQ(outputStream.str(), "");
512
513 std::vector<std::string> const & values = getOptionValues(parser, "string");
514
515 SEQAN_ASSERT_EQ(length(values), 3u);
516
517 for (unsigned i = 0; i < length(values); ++i)
518 {
519 SEQAN_ASSERT_EQ(value(values, i), "this-is-a-string-value");
520 }
521 }
522
SEQAN_DEFINE_TEST(test_min_max_double_values_in_range)523 SEQAN_DEFINE_TEST(test_min_max_double_values_in_range)
524 {
525 ArgumentParser parser;
526 setupDoubleParser(parser);
527
528 setMinValue(parser, "double", "1.0");
529 setMaxValue(parser, "double", "2.0");
530
531 int argc = 3;
532 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_2, A_DOUBLE_3};
533
534 std::stringstream error_stream;
535 std::stringstream outputStream;
536
537 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
538 SEQAN_ASSERT_EQ(outputStream.str(), "");
539
540 double doubleValue = 0.0;
541 SEQAN_ASSERT(getOptionValue(doubleValue, parser, "double"));
542 SEQAN_ASSERT_EQ(doubleValue, 1.56);
543 }
544
SEQAN_DEFINE_TEST(test_min_max_double_values_to_small)545 SEQAN_DEFINE_TEST(test_min_max_double_values_to_small)
546 {
547 ArgumentParser parser;
548 setupDoubleParser(parser);
549
550 setMinValue(parser, "double", "1.6");
551
552 int argc = 3;
553 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_2, A_DOUBLE_3};
554
555 std::stringstream error_stream;
556 std::stringstream outputStream;
557
558 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
559 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value '1.56' is not in the interval [1.6:+inf]\n");
560 SEQAN_ASSERT_EQ(outputStream.str(), "");
561 }
562
SEQAN_DEFINE_TEST(test_min_max_double_values_to_big)563 SEQAN_DEFINE_TEST(test_min_max_double_values_to_big)
564 {
565 ArgumentParser parser;
566 setupDoubleParser(parser);
567
568 setMaxValue(parser, "double", "1.5");
569
570 int argc = 3;
571 const char * argv[3] = {A_DOUBLE_0, A_DOUBLE_2, A_DOUBLE_3};
572
573 std::stringstream error_stream;
574 std::stringstream outputStream;
575
576 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
577 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value '1.56' is not in the interval [-inf:1.5]\n");
578 SEQAN_ASSERT_EQ(outputStream.str(), "");
579 }
580
SEQAN_DEFINE_TEST(test_min_max_int_values_in_range)581 SEQAN_DEFINE_TEST(test_min_max_int_values_in_range)
582 {
583 ArgumentParser parser;
584 setupIntegerParser(parser);
585
586 setMinValue(parser, "integer", "-10");
587 setMaxValue(parser, "integer", "2");
588
589 int argc = 3;
590 const char * argv[3] = {A_INT_0, A_INT_2, A_INT_3};
591
592 std::stringstream error_stream;
593 std::stringstream outputStream;
594
595 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
596 SEQAN_ASSERT_EQ(error_stream.str(), "");
597 SEQAN_ASSERT_EQ(outputStream.str(), "");
598
599 int integerValue = 0;
600 SEQAN_ASSERT(getOptionValue(integerValue, parser, "integer"));
601 SEQAN_ASSERT_EQ(integerValue, 1);
602 }
603
SEQAN_DEFINE_TEST(test_min_max_int_values_to_small)604 SEQAN_DEFINE_TEST(test_min_max_int_values_to_small)
605 {
606 ArgumentParser parser;
607 setupIntegerParser(parser);
608
609 setMinValue(parser, "integer", "3");
610
611 int argc = 3;
612 const char * argv[3] = {A_INT_0, A_INT_2, A_INT_3};
613
614 std::stringstream error_stream;
615 std::stringstream outputStream;
616
617 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
618 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value '1' is not in the interval [3:+inf]\n");
619 SEQAN_ASSERT_EQ(outputStream.str(), "");
620 }
621
SEQAN_DEFINE_TEST(test_min_max_int_values_to_big)622 SEQAN_DEFINE_TEST(test_min_max_int_values_to_big)
623 {
624 ArgumentParser parser;
625 setupIntegerParser(parser);
626
627 setMaxValue(parser, "integer", "-3");
628
629 int argc = 3;
630 const char * argv[3] = {A_INT_0, A_INT_2, A_INT_3};
631
632 std::stringstream error_stream;
633 std::stringstream outputStream;
634
635 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
636 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value '1' is not in the interval [-inf:-3]\n");
637 SEQAN_ASSERT_EQ(outputStream.str(), "");
638 }
639
SEQAN_DEFINE_TEST(test_allowed_values_contained)640 SEQAN_DEFINE_TEST(test_allowed_values_contained)
641 {
642 ArgumentParser parser;
643 setupStringParser(parser);
644
645 setValidValues(parser, "string", "a b c this-is-a-string-value");
646
647 int argc = 3;
648 const char * argv[3] = {A_STRING_0, A_STRING_2, A_STRING_3};
649
650 std::stringstream error_stream;
651 std::stringstream outputStream;
652
653 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
654 SEQAN_ASSERT_EQ(error_stream.str(), "");
655 SEQAN_ASSERT_EQ(outputStream.str(), "");
656
657 CharString value;
658 SEQAN_ASSERT(getOptionValue(value, parser, "string"));
659 SEQAN_ASSERT_EQ(value, "this-is-a-string-value");
660 }
661
SEQAN_DEFINE_TEST(test_allowed_values_not_contained)662 SEQAN_DEFINE_TEST(test_allowed_values_not_contained)
663 {
664 ArgumentParser parser;
665 setupStringParser(parser);
666
667 setValidValues(parser, "string", "a b c");
668
669 int argc = 3;
670 const char * argv[3] = {A_STRING_0, A_STRING_2, A_STRING_3};
671
672 std::stringstream error_stream;
673 std::stringstream outputStream;
674
675 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
676 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value 'this-is-a-string-value' is not in the list of allowed values [a, b, c]\n");
677 SEQAN_ASSERT_EQ(outputStream.str(), "");
678 }
679
SEQAN_DEFINE_TEST(test_input_file_short)680 SEQAN_DEFINE_TEST(test_input_file_short)
681 {
682 ArgumentParser parser;
683 setupInputFileParser(parser);
684
685 int argc = 3;
686 const char * argv[3] = {A_IN_FILE_0, A_IN_FILE_1, A_IN_FILE_3};
687
688 std::stringstream error_stream;
689 std::stringstream outputStream;
690
691 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
692 SEQAN_ASSERT_EQ(error_stream.str(), "");
693 SEQAN_ASSERT_EQ(outputStream.str(), "");
694
695 CharString value;
696 SEQAN_ASSERT(getOptionValue(value, parser, "in"));
697 SEQAN_ASSERT_EQ(value, "input.fasta");
698 }
699
SEQAN_DEFINE_TEST(test_input_file_long)700 SEQAN_DEFINE_TEST(test_input_file_long)
701 {
702 ArgumentParser parser;
703 setupInputFileParser(parser);
704
705 int argc = 3;
706 const char * argv[3] = {A_IN_FILE_0, A_IN_FILE_2, A_IN_FILE_3};
707
708 std::stringstream error_stream;
709 std::stringstream outputStream;
710
711 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
712 SEQAN_ASSERT_EQ(error_stream.str(), "");
713 SEQAN_ASSERT_EQ(outputStream.str(), "");
714
715 CharString value;
716 SEQAN_ASSERT(getOptionValue(value, parser, "in"));
717 SEQAN_ASSERT_EQ(value, "input.fasta");
718 }
719
SEQAN_DEFINE_TEST(test_input_file_missing)720 SEQAN_DEFINE_TEST(test_input_file_missing)
721 {
722 ArgumentParser parser;
723 setupInputFileParser(parser);
724
725 int argc = 2;
726 const char * argv[2] = {A_IN_FILE_0, A_IN_FILE_1};
727
728 std::stringstream error_stream;
729 std::stringstream outputStream;
730
731 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
732 SEQAN_ASSERT_EQ(error_stream.str(), "test: option requires an argument -- i\n");
733 SEQAN_ASSERT_EQ(outputStream.str(), "");
734 }
735
SEQAN_DEFINE_TEST(test_input_file_invalid_type)736 SEQAN_DEFINE_TEST(test_input_file_invalid_type)
737 {
738 ArgumentParser parser;
739 setupInputFileParser(parser);
740
741 setValidValues(parser, "in", ".fa");
742
743 int argc = 3;
744 const char * argv[3] = {A_IN_FILE_0, A_IN_FILE_2, A_IN_FILE_3};
745
746 std::stringstream error_stream;
747 std::stringstream outputStream;
748
749 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
750 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given path 'input.fasta' does not have one of the valid file extensions [*.fa]\n");
751 SEQAN_ASSERT_EQ(outputStream.str(), "");
752 }
753
SEQAN_DEFINE_TEST(test_input_file_valid_type)754 SEQAN_DEFINE_TEST(test_input_file_valid_type)
755 {
756 ArgumentParser parser;
757 setupInputFileParser(parser);
758
759 setValidValues(parser, "in", ".fasta .FASTA .fa");
760
761 int argc = 3;
762 const char * argv[3] = {A_IN_FILE_0, A_IN_FILE_2, A_IN_FILE_3};
763
764 std::stringstream error_stream;
765 std::stringstream outputStream;
766
767 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
768 SEQAN_ASSERT_EQ(error_stream.str(), "");
769 SEQAN_ASSERT_EQ(outputStream.str(), "");
770
771 CharString value;
772 SEQAN_ASSERT(getOptionValue(value, parser, "in"));
773 SEQAN_ASSERT_EQ(value, "input.fasta");
774 }
775
SEQAN_DEFINE_TEST(test_input_file_extension)776 SEQAN_DEFINE_TEST(test_input_file_extension)
777 {
778 ArgumentParser parser;
779 setupInputFileParser(parser);
780
781 setValidValues(parser, "in", ".fasta .FASTA .fa");
782
783 int argc = 3;
784 const char * argv[3] = {A_IN_FILE_0, A_IN_FILE_2, A_IN_FILE_3};
785
786 std::stringstream error_stream;
787 std::stringstream outputStream;
788
789 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
790 SEQAN_ASSERT_EQ(error_stream.str(), "");
791 SEQAN_ASSERT_EQ(outputStream.str(), "");
792
793 std::string value;
794 value = getOptionFileExtension(parser, "in");
795 SEQAN_ASSERT_EQ(value, ".fasta");
796 }
797
798 // Test that an automatic --${OPTION}-file-ext option is added with the same list flag and number of values.
SEQAN_DEFINE_TEST(test_input_file_auto_file_ext_option)799 SEQAN_DEFINE_TEST(test_input_file_auto_file_ext_option)
800 {
801 std::vector<std::string> expectedValidValues;
802 expectedValidValues.push_back("fa");
803 expectedValidValues.push_back("TXT");
804
805 // No list, one value.
806 {
807 ArgumentParser parser;
808
809 addOption(parser, ArgParseOption("short", "long", "help text", ArgParseOption::INPUT_FILE));
810 setValidValues(parser, "long", ".fa .TXT");
811
812 SEQAN_ASSERT_NOT(hasOption(parser, "short-file-ext"));
813 SEQAN_ASSERT(hasOption(parser, "long-file-ext"));
814
815 ArgParseOption & option = getOption(parser, "long-file-ext");
816 SEQAN_ASSERT(isStringArgument(option));
817 SEQAN_ASSERT_NOT(isListArgument(option));
818 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 1u);
819 SEQAN_ASSERT(option.validValues == expectedValidValues);
820 }
821
822 // No list, two values.
823 {
824 ArgumentParser parser;
825
826 addOption(parser, ArgParseOption("short", "long", "help text", ArgParseOption::INPUT_FILE,
827 "label", false, 2));
828 setValidValues(parser, "long", ".fa .TXT");
829
830 SEQAN_ASSERT_NOT(hasOption(parser, "short-file-ext"));
831 SEQAN_ASSERT(hasOption(parser, "long-file-ext"));
832
833 ArgParseOption & option = getOption(parser, "long-file-ext");
834 SEQAN_ASSERT(isStringArgument(option));
835 SEQAN_ASSERT_NOT(isListArgument(option));
836 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 2u);
837 SEQAN_ASSERT(option.validValues == expectedValidValues);
838 }
839
840 // List.
841 {
842 ArgumentParser parser;
843
844 addOption(parser, ArgParseOption("short", "long", "help text", ArgParseOption::INPUT_FILE,
845 "label", true));
846 setValidValues(parser, "long", ".fa .TXT");
847
848 SEQAN_ASSERT_NOT(hasOption(parser, "short-file-ext"));
849 SEQAN_ASSERT(hasOption(parser, "long-file-ext"));
850
851 ArgParseOption & option = getOption(parser, "long-file-ext");
852 SEQAN_ASSERT(isStringArgument(option));
853 SEQAN_ASSERT(isListArgument(option));
854 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 1u);
855 SEQAN_ASSERT(option.validValues == expectedValidValues);
856 }
857 }
858
SEQAN_DEFINE_TEST(test_output_file_short)859 SEQAN_DEFINE_TEST(test_output_file_short)
860 {
861 ArgumentParser parser;
862 setupOutputFileParser(parser);
863
864 int argc = 3;
865 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_1, A_OUT_FILE_3};
866
867 std::stringstream error_stream;
868 std::stringstream outputStream;
869
870 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
871 SEQAN_ASSERT_EQ(error_stream.str(), "");
872 SEQAN_ASSERT_EQ(outputStream.str(), "");
873
874 CharString value;
875 SEQAN_ASSERT(getOptionValue(value, parser, "out"));
876 SEQAN_ASSERT_EQ(value, "output.fasta");
877 }
878
SEQAN_DEFINE_TEST(test_output_file_long)879 SEQAN_DEFINE_TEST(test_output_file_long)
880 {
881 ArgumentParser parser;
882 setupOutputFileParser(parser);
883
884 int argc = 3;
885 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_3};
886
887 std::stringstream error_stream;
888 std::stringstream outputStream;
889
890 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
891 SEQAN_ASSERT_EQ(error_stream.str(), "");
892 SEQAN_ASSERT_EQ(outputStream.str(), "");
893
894 CharString value;
895 SEQAN_ASSERT(getOptionValue(value, parser, "out"));
896 SEQAN_ASSERT_EQ(value, "output.fasta");
897 }
898
SEQAN_DEFINE_TEST(test_output_file_missing)899 SEQAN_DEFINE_TEST(test_output_file_missing)
900 {
901 ArgumentParser parser;
902 setupOutputFileParser(parser);
903
904 int argc = 2;
905 const char * argv[2] = {A_OUT_FILE_0, A_OUT_FILE_1};
906
907 std::stringstream error_stream;
908 std::stringstream outputStream;
909
910 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
911 SEQAN_ASSERT_EQ(error_stream.str(), "test: option requires an argument -- o\n");
912 SEQAN_ASSERT_EQ(outputStream.str(), "");
913 }
914
SEQAN_DEFINE_TEST(test_output_file_invalid_type)915 SEQAN_DEFINE_TEST(test_output_file_invalid_type)
916 {
917 ArgumentParser parser;
918 setupOutputFileParser(parser);
919
920 setValidValues(parser, "out", ".fa");
921
922 int argc = 3;
923 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_3};
924
925 std::stringstream error_stream;
926 std::stringstream outputStream;
927
928 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
929 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given path 'output.fasta' does not have one of the valid file extensions [*.fa]\n");
930 SEQAN_ASSERT_EQ(outputStream.str(), "");
931 }
932
SEQAN_DEFINE_TEST(test_output_file_valid_type)933 SEQAN_DEFINE_TEST(test_output_file_valid_type)
934 {
935 ArgumentParser parser;
936 setupOutputFileParser(parser);
937
938 setValidValues(parser, "out", ".fasta .FASTA .fa");
939
940 int argc = 3;
941 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_3};
942
943 std::stringstream error_stream;
944 std::stringstream outputStream;
945
946 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
947 SEQAN_ASSERT_EQ(error_stream.str(), "");
948 SEQAN_ASSERT_EQ(outputStream.str(), "");
949
950 CharString value;
951 SEQAN_ASSERT(getOptionValue(value, parser, "out"));
952 SEQAN_ASSERT_EQ(value, "output.fasta");
953 }
954
SEQAN_DEFINE_TEST(test_output_file_extension)955 SEQAN_DEFINE_TEST(test_output_file_extension)
956 {
957 ArgumentParser parser;
958 setupOutputFileParser(parser);
959
960 setValidValues(parser, "out", ".fasta .FASTA .fa");
961
962 int argc = 3;
963 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_3};
964
965 std::stringstream error_stream;
966 std::stringstream outputStream;
967
968 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
969 SEQAN_ASSERT_EQ(error_stream.str(), "");
970 SEQAN_ASSERT_EQ(outputStream.str(), "");
971
972 CharString value;
973 value = getOptionFileExtension(parser, "out");
974 SEQAN_ASSERT_EQ(value, ".fasta");
975 }
976
SEQAN_DEFINE_TEST(test_output_file_extension_targz)977 SEQAN_DEFINE_TEST(test_output_file_extension_targz)
978 {
979 ArgumentParser parser;
980 setupOutputFileParser(parser);
981
982 setValidValues(parser, "out", ".tar.gz .tar");
983
984 int argc = 3;
985 const char * argv[3] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_4};
986
987 std::stringstream error_stream;
988 std::stringstream outputStream;
989
990 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
991 SEQAN_ASSERT_EQ(error_stream.str(), "");
992 SEQAN_ASSERT_EQ(outputStream.str(), "");
993
994 CharString value;
995 value = getOptionFileExtension(parser, "out");
996 SEQAN_ASSERT_EQ(value, ".tar.gz");
997 }
998
999 // Value with invalid extension given on command line but overridden with valid extension.
SEQAN_DEFINE_TEST(test_output_file_explicit_extension_valid)1000 SEQAN_DEFINE_TEST(test_output_file_explicit_extension_valid)
1001 {
1002 ArgumentParser parser;
1003 setupOutputFileParser(parser);
1004
1005 setValidValues(parser, "out", ".fasta .FASTA .fa");
1006
1007 int argc = 5;
1008 const char * argv[5] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_5, A_OUT_FILE_6, A_OUT_FILE_7};
1009
1010 std::stringstream error_stream;
1011 std::stringstream outputStream;
1012
1013 SEQAN_ASSERT_EQ(parse(parser, argc, argv, std::cerr, std::cerr), ArgumentParser::PARSE_OK);
1014 SEQAN_ASSERT_EQ(error_stream.str(), "");
1015 SEQAN_ASSERT_EQ(outputStream.str(), "");
1016
1017 CharString value;
1018 value = getOptionFileExtension(parser, "out");
1019 SEQAN_ASSERT_EQ(value, ".fasta");
1020 }
1021
1022 // Value with valid extension given on command line but overridden with invalid extension.
SEQAN_DEFINE_TEST(test_output_file_explicit_extension_invalid)1023 SEQAN_DEFINE_TEST(test_output_file_explicit_extension_invalid)
1024 {
1025 ArgumentParser parser;
1026 setupOutputFileParser(parser);
1027
1028 setValidValues(parser, "out", ".fasta .FASTA .fa");
1029
1030 int argc = 5;
1031 const char * argv[5] = {A_OUT_FILE_0, A_OUT_FILE_2, A_OUT_FILE_3, A_OUT_FILE_6, A_OUT_FILE_8};
1032
1033 std::stringstream error_stream;
1034 std::stringstream outputStream;
1035
1036 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
1037 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given path 'output.fasta' does not have one of the valid file extensions [*.fasta, *.FASTA, *.fa]; the file extension was overridden to be '.txt'\n");
1038 SEQAN_ASSERT_EQ(outputStream.str(), "");
1039 }
1040
SEQAN_DEFINE_TEST(test_argument_string)1041 SEQAN_DEFINE_TEST(test_argument_string)
1042 {
1043 ArgumentParser parser;
1044 addArgument(parser, ArgParseArgument(ArgParseArgument::STRING));
1045 addArgument(parser, ArgParseArgument(ArgParseArgument::STRING));
1046
1047 int argc = 3;
1048 const char * argv[3] = {A_ARGUMENT_0, A_ARGUMENT_1, A_ARGUMENT_2};
1049
1050 std::stringstream error_stream;
1051 std::stringstream outputStream;
1052
1053 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1054 SEQAN_ASSERT_EQ(error_stream.str(), "");
1055 SEQAN_ASSERT_EQ(outputStream.str(), "");
1056 }
1057
SEQAN_DEFINE_TEST(test_argument_not_all_set)1058 SEQAN_DEFINE_TEST(test_argument_not_all_set)
1059 {
1060 ArgumentParser parser;
1061 addArgument(parser, ArgParseArgument(ArgParseArgument::STRING));
1062 addArgument(parser, ArgParseArgument(ArgParseArgument::STRING));
1063
1064 int argc = 2;
1065 const char * argv[2] = {A_ARGUMENT_0, A_ARGUMENT_1};
1066
1067 std::stringstream error_stream;
1068 std::stringstream outputStream;
1069
1070 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
1071 SEQAN_ASSERT_EQ(error_stream.str(), "test: Not enough arguments were provided.\nTry 'test --help' for more information.\n");
1072 SEQAN_ASSERT_EQ(outputStream.str(), "");
1073 }
1074
SEQAN_DEFINE_TEST(test_argument_double)1075 SEQAN_DEFINE_TEST(test_argument_double)
1076 {
1077 ArgumentParser parser;
1078 addArgument(parser, ArgParseArgument(ArgParseArgument::DOUBLE));
1079
1080 int argc = 2;
1081 const char * argv[2] = {A_ARGUMENT_0, A_ARGUMENT_DOUBLE_5};
1082
1083 std::stringstream error_stream;
1084 std::stringstream outputStream;
1085
1086 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1087 SEQAN_ASSERT_EQ(error_stream.str(), "");
1088 SEQAN_ASSERT_EQ(outputStream.str(), "");
1089
1090 double doubleValue = 0.0;
1091 SEQAN_ASSERT(getArgumentValue(doubleValue, parser, 0));
1092 SEQAN_ASSERT_EQ(doubleValue, 6.0221418e23);
1093 }
1094
SEQAN_DEFINE_TEST(test_argument_not_a_double)1095 SEQAN_DEFINE_TEST(test_argument_not_a_double)
1096 {
1097 ArgumentParser parser;
1098 addArgument(parser, ArgParseArgument(ArgParseArgument::DOUBLE));
1099
1100 int argc = 2;
1101 const char * argv[2] = {A_ARGUMENT_0, A_ARGUMENT_1};
1102
1103 std::stringstream error_stream;
1104 std::stringstream outputStream;
1105
1106 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
1107 SEQAN_ASSERT_EQ(error_stream.str(), "test: the given value 'argument1' cannot be casted to double\n");
1108 SEQAN_ASSERT_EQ(outputStream.str(), "");
1109 }
1110
SEQAN_DEFINE_TEST(test_argument_auto_file_ext_option)1111 SEQAN_DEFINE_TEST(test_argument_auto_file_ext_option)
1112 {
1113 std::vector<std::string> expectedValidValues;
1114 expectedValidValues.push_back("fa");
1115 expectedValidValues.push_back("TXT");
1116
1117 // No list, one value.
1118 {
1119 ArgumentParser parser;
1120 addArgument(parser, ArgParseArgument(ArgParseArgument::INPUT_FILE));
1121 setValidValues(parser, 0, "fa TXT");
1122
1123 SEQAN_ASSERT(hasOption(parser, "arg-1-file-ext"));
1124
1125 ArgParseOption & option = getOption(parser, "arg-1-file-ext");
1126 SEQAN_ASSERT(isStringArgument(option));
1127 SEQAN_ASSERT_NOT(isListArgument(option));
1128 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 1u);
1129 SEQAN_ASSERT(option.validValues == expectedValidValues);
1130 }
1131
1132 // NB: tuple arguments unsupported
1133
1134 // List, one value.
1135 {
1136 ArgumentParser parser;
1137 addArgument(parser, ArgParseArgument(ArgParseArgument::INPUT_FILE, "LABEL", true));
1138 setValidValues(parser, 0, "fa TXT");
1139
1140 SEQAN_ASSERT(hasOption(parser, "arg-1-file-ext"));
1141
1142 ArgParseOption & option = getOption(parser, "arg-1-file-ext");
1143 SEQAN_ASSERT(isStringArgument(option));
1144 SEQAN_ASSERT(isListArgument(option));
1145 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 1u);
1146 SEQAN_ASSERT(option.validValues == expectedValidValues);
1147 }
1148
1149 // Second argument, just to make sure.
1150 {
1151 ArgumentParser parser;
1152 addArgument(parser, ArgParseArgument(ArgParseArgument::DOUBLE));
1153 addArgument(parser, ArgParseArgument(ArgParseArgument::INPUT_FILE));
1154 setValidValues(parser, 1, "fa TXT");
1155
1156 SEQAN_ASSERT(hasOption(parser, "arg-2-file-ext"));
1157
1158 ArgParseOption & option = getOption(parser, "arg-2-file-ext");
1159
1160 SEQAN_ASSERT(isStringArgument(option));
1161 SEQAN_ASSERT_NOT(isListArgument(option));
1162 SEQAN_ASSERT_EQ(numberOfAllowedValues(option), 1u);
1163 SEQAN_ASSERT(option.validValues == expectedValidValues);
1164 }
1165 }
1166
SEQAN_DEFINE_TEST(test_isDouble)1167 SEQAN_DEFINE_TEST(test_isDouble)
1168 {
1169 CharString a = "this is not a double";
1170 CharString b = "2.5";
1171 CharString c = "-45.5245";
1172 CharString d = "6.0221418e23";
1173 CharString e = "-45.5245aeeeb";
1174
1175 SEQAN_ASSERT(!_isDouble(a));
1176 SEQAN_ASSERT(_isDouble(b));
1177 SEQAN_ASSERT(_isDouble(c));
1178 SEQAN_ASSERT(_isDouble(d));
1179 SEQAN_ASSERT(!_isDouble(e));
1180 }
1181
SEQAN_DEFINE_TEST(test_isInt)1182 SEQAN_DEFINE_TEST(test_isInt)
1183 {
1184 CharString a = "this is not an int";
1185 CharString b = "2";
1186 CharString c = "-4253252";
1187 CharString d = "6aaefgeag";
1188
1189 SEQAN_ASSERT(!_isInt(a));
1190 SEQAN_ASSERT(_isInt(b));
1191 SEQAN_ASSERT(_isInt(c));
1192 SEQAN_ASSERT(!_isInt(d));
1193 }
1194
1195 // Testing lists of tuples
SEQAN_DEFINE_TEST(test_int_list_option)1196 SEQAN_DEFINE_TEST(test_int_list_option)
1197 {
1198 ArgumentParser parser;
1199 addOption(parser, ArgParseOption("l", "list", "this is a list option", ArgParseArgument::INTEGER, "", true, 2));
1200
1201 int argc = 7;
1202 const char * argv[7] = {A_TUPLE_LIST, A_TUPLE_LIST_L, A_TUPLE_LIST_L_1, A_TUPLE_LIST_L_2, A_TUPLE_LIST_L, A_TUPLE_LIST_L_3, A_TUPLE_LIST_L_4};
1203
1204 std::stringstream error_stream;
1205 std::stringstream outputStream;
1206
1207 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1208 SEQAN_ASSERT_EQ(error_stream.str(), "");
1209 SEQAN_ASSERT_EQ(outputStream.str(), "");
1210
1211 SEQAN_ASSERT_EQ(getOptionValueCount(parser, "list"), 4u);
1212
1213 int value = 0;
1214 SEQAN_ASSERT(getOptionValue(value, parser, "list", 0));
1215 SEQAN_ASSERT_EQ(value, 10);
1216 SEQAN_ASSERT(getOptionValue(value, parser, "list", 1));
1217 SEQAN_ASSERT_EQ(value, 20);
1218
1219 SEQAN_ASSERT(getOptionValue(value, parser, "list", 2));
1220 SEQAN_ASSERT_EQ(value, 30);
1221 SEQAN_ASSERT(getOptionValue(value, parser, "list", 3));
1222 SEQAN_ASSERT_EQ(value, 40);
1223 }
1224
SEQAN_DEFINE_TEST(test_double_list_option)1225 SEQAN_DEFINE_TEST(test_double_list_option)
1226 {
1227 ArgumentParser parser;
1228 addOption(parser, ArgParseOption("k", "double-list", "this is a list option", ArgParseArgument::DOUBLE, "", true, 3));
1229
1230 int argc = 9;
1231 const char * argv[9] = {A_TUPLE_LIST, A_TUPLE_LIST_DL, A_TUPLE_LIST_DL_1, A_TUPLE_LIST_DL_2, A_TUPLE_LIST_DL_3, A_TUPLE_LIST_DL, A_TUPLE_LIST_DL_4, A_TUPLE_LIST_DL_5, A_TUPLE_LIST_DL_6};
1232
1233 std::stringstream error_stream;
1234 std::stringstream outputStream;
1235
1236 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1237 SEQAN_ASSERT_EQ(error_stream.str(), "");
1238 SEQAN_ASSERT_EQ(outputStream.str(), "");
1239
1240 SEQAN_ASSERT_EQ(getOptionValueCount(parser, "double-list"), 6u);
1241
1242 double value = 0;
1243 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 0));
1244 SEQAN_ASSERT_EQ(value, 5.1);
1245 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 1));
1246 SEQAN_ASSERT_EQ(value, 6.2);
1247 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 2));
1248 SEQAN_ASSERT_EQ(value, 7.3);
1249
1250 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 3));
1251 SEQAN_ASSERT_EQ(value, 5.5);
1252 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 4));
1253 SEQAN_ASSERT_EQ(value, 6.6);
1254 SEQAN_ASSERT(getOptionValue(value, parser, "double-list", 5));
1255 SEQAN_ASSERT_EQ(value, 7.7);
1256
1257 }
1258
SEQAN_DEFINE_TEST(test_double_list_option_not_enough_arguments)1259 SEQAN_DEFINE_TEST(test_double_list_option_not_enough_arguments)
1260 {
1261 ArgumentParser parser;
1262 addOption(parser, ArgParseOption("k", "double-list", "this is a list option", ArgParseArgument::DOUBLE, "", true, 3));
1263
1264 int argc = 8;
1265 const char * argv[8] = {A_TUPLE_LIST, A_TUPLE_LIST_DL, A_TUPLE_LIST_DL_1, A_TUPLE_LIST_DL_2, A_TUPLE_LIST_DL_3, A_TUPLE_LIST_DL, A_TUPLE_LIST_DL_4, A_TUPLE_LIST_DL_5};
1266
1267 std::stringstream error_stream;
1268 std::stringstream outputStream;
1269
1270 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_ERROR);
1271 SEQAN_ASSERT_EQ(error_stream.str(), "test_tuple_list: option requires an argument -- k\n");
1272 SEQAN_ASSERT_EQ(outputStream.str(), "");
1273 }
1274
setUpBoolParser(ArgumentParser & parser)1275 void setUpBoolParser(ArgumentParser & parser)
1276 {
1277 addOption(parser, ArgParseOption("b", "", "This is a boolean flag"));
1278 addOption(parser, ArgParseOption("c", "", "This is a boolean flag"));
1279 addOption(parser, ArgParseOption("d", "", "This is a boolean flag that we will not set."));
1280 }
1281
SEQAN_DEFINE_TEST(test_boolean_flags)1282 SEQAN_DEFINE_TEST(test_boolean_flags)
1283 {
1284 ArgumentParser parser;
1285 setUpBoolParser(parser);
1286
1287 int argc = 3;
1288 const char * argv[3] = { A_BOOL, A_BOOL_1, A_BOOL_2 };
1289
1290 std::stringstream error_stream;
1291 std::stringstream outputStream;
1292
1293 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1294 SEQAN_ASSERT_EQ(error_stream.str(), "");
1295 SEQAN_ASSERT_EQ(outputStream.str(), "");
1296
1297 bool isSet = false;
1298 SEQAN_ASSERT(getOptionValue(isSet, parser, "b"));
1299 SEQAN_ASSERT(isSet);
1300
1301 isSet = false;
1302 SEQAN_ASSERT(getOptionValue(isSet, parser, "c"));
1303 SEQAN_ASSERT(isSet);
1304
1305 isSet = true;
1306 SEQAN_ASSERT(getOptionValue(isSet, parser, "d"));
1307 SEQAN_ASSERT(!isSet);
1308 }
1309
SEQAN_DEFINE_TEST(test_combined_boolean_flags)1310 SEQAN_DEFINE_TEST(test_combined_boolean_flags)
1311 {
1312 ArgumentParser parser;
1313 setUpBoolParser(parser);
1314
1315 int argc = 2;
1316 const char * argv[2] = { A_BOOL, A_BOOL_3 };
1317
1318 std::stringstream error_stream;
1319 std::stringstream outputStream;
1320
1321 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1322 SEQAN_ASSERT_EQ(error_stream.str(), "");
1323 SEQAN_ASSERT_EQ(outputStream.str(), "");
1324
1325 bool isSet = false;
1326 SEQAN_ASSERT(getOptionValue(isSet, parser, "b"));
1327 SEQAN_ASSERT(isSet);
1328
1329 isSet = false;
1330 SEQAN_ASSERT(getOptionValue(isSet, parser, "c"));
1331 SEQAN_ASSERT(isSet);
1332
1333 isSet = true;
1334 SEQAN_ASSERT(getOptionValue(isSet, parser, "d"));
1335 SEQAN_ASSERT(!isSet);
1336 }
1337
SEQAN_DEFINE_TEST(test_long_short_flag_name)1338 SEQAN_DEFINE_TEST(test_long_short_flag_name)
1339 {
1340 ArgumentParser parser;
1341 addOption(parser, ArgParseOption("bc", "", "This is a boolean flag"));
1342 addOption(parser, ArgParseOption("d", "", "This is a boolean flag"));
1343
1344 int argc = 2;
1345 const char * argv[2] = { A_BOOL, A_BOOL_3 };
1346
1347 std::stringstream error_stream;
1348 std::stringstream outputStream;
1349
1350 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1351 SEQAN_ASSERT_EQ(error_stream.str(), "");
1352 SEQAN_ASSERT_EQ(outputStream.str(), "");
1353
1354 bool isSet = false;
1355 SEQAN_ASSERT(getOptionValue(isSet, parser, "bc"));
1356 SEQAN_ASSERT(isSet);
1357
1358 isSet = true;
1359 SEQAN_ASSERT(getOptionValue(isSet, parser, "d"));
1360 SEQAN_ASSERT(!isSet);
1361 }
1362
SEQAN_DEFINE_TEST(test_default_value)1363 SEQAN_DEFINE_TEST(test_default_value)
1364 {
1365 ArgumentParser parser;
1366 setupStringParser(parser);
1367 setDefaultValue(parser, "string", "default-string-value");
1368
1369 CharString defaultValue;
1370 SEQAN_ASSERT(getOptionValue(defaultValue, parser, "string"));
1371 SEQAN_ASSERT_EQ(defaultValue, "default-string-value");
1372
1373 int argc = 3;
1374 const char * argv[3] = {A_STRING_0, A_STRING_1, A_STRING_3};
1375
1376 std::stringstream error_stream;
1377 std::stringstream outputStream;
1378
1379 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, error_stream), ArgumentParser::PARSE_OK);
1380 SEQAN_ASSERT_EQ(error_stream.str(), "");
1381 SEQAN_ASSERT_EQ(outputStream.str(), "");
1382
1383 CharString value;
1384 SEQAN_ASSERT(getOptionValue(value, parser, "string"));
1385 SEQAN_ASSERT_EQ(value, "this-is-a-string-value");
1386 }
1387
1388
SEQAN_DEFINE_TEST(test_parse_non_const_cstring)1389 SEQAN_DEFINE_TEST(test_parse_non_const_cstring)
1390 {
1391 // Call parse() with (char **) and not (char const **) to test that this works as well.
1392 ArgumentParser parser;
1393 setupIntegerParser(parser);
1394 setDefaultValue(parser, "integer", "2");
1395 setMaxValue(parser, "integer", "3");
1396
1397 int defaultValue;
1398 SEQAN_ASSERT(getOptionValue(defaultValue, parser, "integer"));
1399 SEQAN_ASSERT_EQ(defaultValue, 2);
1400
1401 char buffer1[100];
1402 strncpy(buffer1, "program_name", 100);
1403 char buffer2[100];
1404 strncpy(buffer2, "-i", 100);
1405 char buffer3[100];
1406 strncpy(buffer3, "1", 100);
1407 int argc = 3;
1408 char * argv[3] = {&buffer1[0], &buffer2[0], &buffer3[0]};
1409
1410 std::stringstream error_stream;
1411 std::stringstream outputStream;
1412
1413 SEQAN_ASSERT_EQ(parse(parser, argc, argv, outputStream, std::cout), ArgumentParser::PARSE_OK);
1414 SEQAN_ASSERT_EQ(error_stream.str(), "");
1415 SEQAN_ASSERT_EQ(outputStream.str(), "");
1416
1417 int value;
1418 SEQAN_ASSERT(getOptionValue(value, parser, "integer"));
1419 SEQAN_ASSERT_EQ(value, 1);
1420 }
1421
1422 } // namespace seqan
1423
1424 #endif // SEQAN_TESTS_ARG_PARSE_TEST_ARG_PARSE_H_
1425