1 // Copyright 2010 Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "utils/cmdline/options.hpp"
31 #include <atf-c++.hpp>
33 #include "utils/cmdline/exceptions.hpp"
34 #include "utils/defs.hpp"
36 namespace cmdline
= utils::cmdline
;
41 /// Simple string-based option type for testing purposes.
42 class mock_option
: public cmdline::base_option
{
44 /// Constructs a mock option with a short name and a long name.
47 /// \param short_name_ The short name for the option.
48 /// \param long_name_ The long name for the option.
49 /// \param description_ A user-friendly description for the option.
50 /// \param arg_name_ If not NULL, specifies that the option must receive an
51 /// argument and specifies the name of such argument for documentation
53 /// \param default_value_ If not NULL, specifies that the option has a
54 /// default value for the mandatory argument.
55 mock_option(const char short_name_
, const char* long_name_
,
56 const char* description_
, const char* arg_name_
= NULL
,
57 const char* default_value_
= NULL
) :
58 base_option(short_name_
, long_name_
, description_
, arg_name_
,
61 /// Constructs a mock option with a long name only.
63 /// \param long_name_ The long name for the option.
64 /// \param description_ A user-friendly description for the option.
65 /// \param arg_name_ If not NULL, specifies that the option must receive an
66 /// argument and specifies the name of such argument for documentation
68 /// \param default_value_ If not NULL, specifies that the option has a
69 /// default value for the mandatory argument.
70 mock_option(const char* long_name_
,
71 const char* description_
, const char* arg_name_
= NULL
,
72 const char* default_value_
= NULL
) :
73 base_option(long_name_
, description_
, arg_name_
, default_value_
) {}
75 /// The data type of this option.
76 typedef std::string option_type
;
78 /// Ensures that the argument passed to the option is valid.
80 /// In this particular mock option, this does not perform any validation.
82 /// \param unused_str The user-provided argument to the option.
84 validate(const std::string
& UTILS_UNUSED_PARAM(str
)) const
89 /// Returns the input parameter without any conversion.
91 /// \param str The user-provided argument to the option.
93 /// \return The same value as provided by the user without conversion.
95 convert(const std::string
& str
)
102 } // anonymous namespace
105 ATF_TEST_CASE_WITHOUT_HEAD(base_option__short_name__no_arg
);
106 ATF_TEST_CASE_BODY(base_option__short_name__no_arg
)
108 const mock_option
o('f', "force", "Force execution");
109 ATF_REQUIRE(o
.has_short_name());
110 ATF_REQUIRE_EQ('f', o
.short_name());
111 ATF_REQUIRE_EQ("force", o
.long_name());
112 ATF_REQUIRE_EQ("Force execution", o
.description());
113 ATF_REQUIRE(!o
.needs_arg());
114 ATF_REQUIRE_EQ("-f", o
.format_short_name());
115 ATF_REQUIRE_EQ("--force", o
.format_long_name());
119 ATF_TEST_CASE_WITHOUT_HEAD(base_option__short_name__with_arg__no_default
);
120 ATF_TEST_CASE_BODY(base_option__short_name__with_arg__no_default
)
122 const mock_option
o('c', "conf_file", "Configuration file", "path");
123 ATF_REQUIRE(o
.has_short_name());
124 ATF_REQUIRE_EQ('c', o
.short_name());
125 ATF_REQUIRE_EQ("conf_file", o
.long_name());
126 ATF_REQUIRE_EQ("Configuration file", o
.description());
127 ATF_REQUIRE(o
.needs_arg());
128 ATF_REQUIRE_EQ("path", o
.arg_name());
129 ATF_REQUIRE(!o
.has_default_value());
130 ATF_REQUIRE_EQ("-c path", o
.format_short_name());
131 ATF_REQUIRE_EQ("--conf_file=path", o
.format_long_name());
135 ATF_TEST_CASE_WITHOUT_HEAD(base_option__short_name__with_arg__with_default
);
136 ATF_TEST_CASE_BODY(base_option__short_name__with_arg__with_default
)
138 const mock_option
o('c', "conf_file", "Configuration file", "path",
140 ATF_REQUIRE(o
.has_short_name());
141 ATF_REQUIRE_EQ('c', o
.short_name());
142 ATF_REQUIRE_EQ("conf_file", o
.long_name());
143 ATF_REQUIRE_EQ("Configuration file", o
.description());
144 ATF_REQUIRE(o
.needs_arg());
145 ATF_REQUIRE_EQ("path", o
.arg_name());
146 ATF_REQUIRE(o
.has_default_value());
147 ATF_REQUIRE_EQ("defpath", o
.default_value());
148 ATF_REQUIRE_EQ("-c path", o
.format_short_name());
149 ATF_REQUIRE_EQ("--conf_file=path", o
.format_long_name());
153 ATF_TEST_CASE_WITHOUT_HEAD(base_option__long_name__no_arg
);
154 ATF_TEST_CASE_BODY(base_option__long_name__no_arg
)
156 const mock_option
o("dryrun", "Dry run mode");
157 ATF_REQUIRE(!o
.has_short_name());
158 ATF_REQUIRE_EQ("dryrun", o
.long_name());
159 ATF_REQUIRE_EQ("Dry run mode", o
.description());
160 ATF_REQUIRE(!o
.needs_arg());
161 ATF_REQUIRE_EQ("--dryrun", o
.format_long_name());
165 ATF_TEST_CASE_WITHOUT_HEAD(base_option__long_name__with_arg__no_default
);
166 ATF_TEST_CASE_BODY(base_option__long_name__with_arg__no_default
)
168 const mock_option
o("helper", "Path to helper", "path");
169 ATF_REQUIRE(!o
.has_short_name());
170 ATF_REQUIRE_EQ("helper", o
.long_name());
171 ATF_REQUIRE_EQ("Path to helper", o
.description());
172 ATF_REQUIRE(o
.needs_arg());
173 ATF_REQUIRE_EQ("path", o
.arg_name());
174 ATF_REQUIRE(!o
.has_default_value());
175 ATF_REQUIRE_EQ("--helper=path", o
.format_long_name());
179 ATF_TEST_CASE_WITHOUT_HEAD(base_option__long_name__with_arg__with_default
);
180 ATF_TEST_CASE_BODY(base_option__long_name__with_arg__with_default
)
182 const mock_option
o("executable", "Executable name", "file", "foo");
183 ATF_REQUIRE(!o
.has_short_name());
184 ATF_REQUIRE_EQ("executable", o
.long_name());
185 ATF_REQUIRE_EQ("Executable name", o
.description());
186 ATF_REQUIRE(o
.needs_arg());
187 ATF_REQUIRE_EQ("file", o
.arg_name());
188 ATF_REQUIRE(o
.has_default_value());
189 ATF_REQUIRE_EQ("foo", o
.default_value());
190 ATF_REQUIRE_EQ("--executable=file", o
.format_long_name());
194 ATF_TEST_CASE_WITHOUT_HEAD(bool_option__short_name
);
195 ATF_TEST_CASE_BODY(bool_option__short_name
)
197 const cmdline::bool_option
o('f', "force", "Force execution");
198 ATF_REQUIRE(o
.has_short_name());
199 ATF_REQUIRE_EQ('f', o
.short_name());
200 ATF_REQUIRE_EQ("force", o
.long_name());
201 ATF_REQUIRE_EQ("Force execution", o
.description());
202 ATF_REQUIRE(!o
.needs_arg());
206 ATF_TEST_CASE_WITHOUT_HEAD(bool_option__long_name
);
207 ATF_TEST_CASE_BODY(bool_option__long_name
)
209 const cmdline::bool_option
o("force", "Force execution");
210 ATF_REQUIRE(!o
.has_short_name());
211 ATF_REQUIRE_EQ("force", o
.long_name());
212 ATF_REQUIRE_EQ("Force execution", o
.description());
213 ATF_REQUIRE(!o
.needs_arg());
217 ATF_TEST_CASE_WITHOUT_HEAD(int_option__short_name
);
218 ATF_TEST_CASE_BODY(int_option__short_name
)
220 const cmdline::int_option
o('p', "int", "The int", "arg", "value");
221 ATF_REQUIRE(o
.has_short_name());
222 ATF_REQUIRE_EQ('p', o
.short_name());
223 ATF_REQUIRE_EQ("int", o
.long_name());
224 ATF_REQUIRE_EQ("The int", o
.description());
225 ATF_REQUIRE(o
.needs_arg());
226 ATF_REQUIRE_EQ("arg", o
.arg_name());
227 ATF_REQUIRE(o
.has_default_value());
228 ATF_REQUIRE_EQ("value", o
.default_value());
232 ATF_TEST_CASE_WITHOUT_HEAD(int_option__long_name
);
233 ATF_TEST_CASE_BODY(int_option__long_name
)
235 const cmdline::int_option
o("int", "The int", "arg", "value");
236 ATF_REQUIRE(!o
.has_short_name());
237 ATF_REQUIRE_EQ("int", o
.long_name());
238 ATF_REQUIRE_EQ("The int", o
.description());
239 ATF_REQUIRE(o
.needs_arg());
240 ATF_REQUIRE_EQ("arg", o
.arg_name());
241 ATF_REQUIRE(o
.has_default_value());
242 ATF_REQUIRE_EQ("value", o
.default_value());
246 ATF_TEST_CASE_WITHOUT_HEAD(int_option__type
);
247 ATF_TEST_CASE_BODY(int_option__type
)
249 const cmdline::int_option
o("int", "The int", "arg");
252 ATF_REQUIRE_EQ(123, cmdline::int_option::convert("123"));
255 ATF_REQUIRE_EQ(-567, cmdline::int_option::convert("-567"));
257 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate(""));
258 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("5a"));
259 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("a5"));
260 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("5 a"));
261 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("5.0"));
265 ATF_TEST_CASE_WITHOUT_HEAD(list_option__short_name
);
266 ATF_TEST_CASE_BODY(list_option__short_name
)
268 const cmdline::list_option
o('p', "list", "The list", "arg", "value");
269 ATF_REQUIRE(o
.has_short_name());
270 ATF_REQUIRE_EQ('p', o
.short_name());
271 ATF_REQUIRE_EQ("list", o
.long_name());
272 ATF_REQUIRE_EQ("The list", o
.description());
273 ATF_REQUIRE(o
.needs_arg());
274 ATF_REQUIRE_EQ("arg", o
.arg_name());
275 ATF_REQUIRE(o
.has_default_value());
276 ATF_REQUIRE_EQ("value", o
.default_value());
280 ATF_TEST_CASE_WITHOUT_HEAD(list_option__long_name
);
281 ATF_TEST_CASE_BODY(list_option__long_name
)
283 const cmdline::list_option
o("list", "The list", "arg", "value");
284 ATF_REQUIRE(!o
.has_short_name());
285 ATF_REQUIRE_EQ("list", o
.long_name());
286 ATF_REQUIRE_EQ("The list", o
.description());
287 ATF_REQUIRE(o
.needs_arg());
288 ATF_REQUIRE_EQ("arg", o
.arg_name());
289 ATF_REQUIRE(o
.has_default_value());
290 ATF_REQUIRE_EQ("value", o
.default_value());
294 ATF_TEST_CASE_WITHOUT_HEAD(list_option__type
);
295 ATF_TEST_CASE_BODY(list_option__type
)
297 const cmdline::list_option
o("list", "The list", "arg");
301 const cmdline::list_option::option_type words
=
302 cmdline::list_option::convert("");
303 ATF_REQUIRE(words
.empty());
308 const cmdline::list_option::option_type words
=
309 cmdline::list_option::convert("foo");
310 ATF_REQUIRE_EQ(1, words
.size());
311 ATF_REQUIRE_EQ("foo", words
[0]);
314 o
.validate("foo,bar,baz");
316 const cmdline::list_option::option_type words
=
317 cmdline::list_option::convert("foo,bar,baz");
318 ATF_REQUIRE_EQ(3, words
.size());
319 ATF_REQUIRE_EQ("foo", words
[0]);
320 ATF_REQUIRE_EQ("bar", words
[1]);
321 ATF_REQUIRE_EQ("baz", words
[2]);
324 o
.validate("foo,bar,");
326 const cmdline::list_option::option_type words
=
327 cmdline::list_option::convert("foo,bar,");
328 ATF_REQUIRE_EQ(3, words
.size());
329 ATF_REQUIRE_EQ("foo", words
[0]);
330 ATF_REQUIRE_EQ("bar", words
[1]);
331 ATF_REQUIRE_EQ("", words
[2]);
334 o
.validate(",foo,bar");
336 const cmdline::list_option::option_type words
=
337 cmdline::list_option::convert(",foo,bar");
338 ATF_REQUIRE_EQ(3, words
.size());
339 ATF_REQUIRE_EQ("", words
[0]);
340 ATF_REQUIRE_EQ("foo", words
[1]);
341 ATF_REQUIRE_EQ("bar", words
[2]);
344 o
.validate("foo,,bar");
346 const cmdline::list_option::option_type words
=
347 cmdline::list_option::convert("foo,,bar");
348 ATF_REQUIRE_EQ(3, words
.size());
349 ATF_REQUIRE_EQ("foo", words
[0]);
350 ATF_REQUIRE_EQ("", words
[1]);
351 ATF_REQUIRE_EQ("bar", words
[2]);
356 ATF_TEST_CASE_WITHOUT_HEAD(path_option__short_name
);
357 ATF_TEST_CASE_BODY(path_option__short_name
)
359 const cmdline::path_option
o('p', "path", "The path", "arg", "value");
360 ATF_REQUIRE(o
.has_short_name());
361 ATF_REQUIRE_EQ('p', o
.short_name());
362 ATF_REQUIRE_EQ("path", o
.long_name());
363 ATF_REQUIRE_EQ("The path", o
.description());
364 ATF_REQUIRE(o
.needs_arg());
365 ATF_REQUIRE_EQ("arg", o
.arg_name());
366 ATF_REQUIRE(o
.has_default_value());
367 ATF_REQUIRE_EQ("value", o
.default_value());
371 ATF_TEST_CASE_WITHOUT_HEAD(path_option__long_name
);
372 ATF_TEST_CASE_BODY(path_option__long_name
)
374 const cmdline::path_option
o("path", "The path", "arg", "value");
375 ATF_REQUIRE(!o
.has_short_name());
376 ATF_REQUIRE_EQ("path", o
.long_name());
377 ATF_REQUIRE_EQ("The path", o
.description());
378 ATF_REQUIRE(o
.needs_arg());
379 ATF_REQUIRE_EQ("arg", o
.arg_name());
380 ATF_REQUIRE(o
.has_default_value());
381 ATF_REQUIRE_EQ("value", o
.default_value());
385 ATF_TEST_CASE_WITHOUT_HEAD(path_option__type
);
386 ATF_TEST_CASE_BODY(path_option__type
)
388 const cmdline::path_option
o("path", "The path", "arg");
390 o
.validate("/some/path");
394 fail("option_argument_value_error not raised");
395 } catch (const cmdline::option_argument_value_error
& e
) {
399 const cmdline::path_option::option_type path
=
400 cmdline::path_option::convert("/foo/bar");
401 ATF_REQUIRE_EQ("bar", path
.leaf_name()); // Ensure valid type.
405 ATF_TEST_CASE_WITHOUT_HEAD(property_option__short_name
);
406 ATF_TEST_CASE_BODY(property_option__short_name
)
408 const cmdline::property_option
o('p', "property", "The property", "a=b");
409 ATF_REQUIRE(o
.has_short_name());
410 ATF_REQUIRE_EQ('p', o
.short_name());
411 ATF_REQUIRE_EQ("property", o
.long_name());
412 ATF_REQUIRE_EQ("The property", o
.description());
413 ATF_REQUIRE(o
.needs_arg());
414 ATF_REQUIRE_EQ("a=b", o
.arg_name());
415 ATF_REQUIRE(!o
.has_default_value());
419 ATF_TEST_CASE_WITHOUT_HEAD(property_option__long_name
);
420 ATF_TEST_CASE_BODY(property_option__long_name
)
422 const cmdline::property_option
o("property", "The property", "a=b");
423 ATF_REQUIRE(!o
.has_short_name());
424 ATF_REQUIRE_EQ("property", o
.long_name());
425 ATF_REQUIRE_EQ("The property", o
.description());
426 ATF_REQUIRE(o
.needs_arg());
427 ATF_REQUIRE_EQ("a=b", o
.arg_name());
428 ATF_REQUIRE(!o
.has_default_value());
432 ATF_TEST_CASE_WITHOUT_HEAD(property_option__type
);
433 ATF_TEST_CASE_BODY(property_option__type
)
435 typedef std::pair
< std::string
, std::string
> string_pair
;
436 const cmdline::property_option
o("property", "The property", "a=b");
438 o
.validate("foo=bar");
439 ATF_REQUIRE(string_pair("foo", "bar") ==
440 cmdline::property_option::convert("foo=bar"));
442 o
.validate(" foo = bar baz");
443 ATF_REQUIRE(string_pair(" foo ", " bar baz") ==
444 cmdline::property_option::convert(" foo = bar baz"));
446 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate(""));
447 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("="));
448 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("a="));
449 ATF_REQUIRE_THROW(cmdline::option_argument_value_error
, o
.validate("=b"));
453 ATF_TEST_CASE_WITHOUT_HEAD(string_option__short_name
);
454 ATF_TEST_CASE_BODY(string_option__short_name
)
456 const cmdline::string_option
o('p', "string", "The string", "arg", "value");
457 ATF_REQUIRE(o
.has_short_name());
458 ATF_REQUIRE_EQ('p', o
.short_name());
459 ATF_REQUIRE_EQ("string", o
.long_name());
460 ATF_REQUIRE_EQ("The string", o
.description());
461 ATF_REQUIRE(o
.needs_arg());
462 ATF_REQUIRE_EQ("arg", o
.arg_name());
463 ATF_REQUIRE(o
.has_default_value());
464 ATF_REQUIRE_EQ("value", o
.default_value());
468 ATF_TEST_CASE_WITHOUT_HEAD(string_option__long_name
);
469 ATF_TEST_CASE_BODY(string_option__long_name
)
471 const cmdline::string_option
o("string", "The string", "arg", "value");
472 ATF_REQUIRE(!o
.has_short_name());
473 ATF_REQUIRE_EQ("string", o
.long_name());
474 ATF_REQUIRE_EQ("The string", o
.description());
475 ATF_REQUIRE(o
.needs_arg());
476 ATF_REQUIRE_EQ("arg", o
.arg_name());
477 ATF_REQUIRE(o
.has_default_value());
478 ATF_REQUIRE_EQ("value", o
.default_value());
482 ATF_TEST_CASE_WITHOUT_HEAD(string_option__type
);
483 ATF_TEST_CASE_BODY(string_option__type
)
485 const cmdline::string_option
o("string", "The string", "foo");
488 o
.validate("some string");
490 const cmdline::string_option::option_type string
=
491 cmdline::string_option::convert("foo");
492 ATF_REQUIRE_EQ(3, string
.length()); // Ensure valid type.
496 ATF_INIT_TEST_CASES(tcs
)
498 ATF_ADD_TEST_CASE(tcs
, base_option__short_name__no_arg
);
499 ATF_ADD_TEST_CASE(tcs
, base_option__short_name__with_arg__no_default
);
500 ATF_ADD_TEST_CASE(tcs
, base_option__short_name__with_arg__with_default
);
501 ATF_ADD_TEST_CASE(tcs
, base_option__long_name__no_arg
);
502 ATF_ADD_TEST_CASE(tcs
, base_option__long_name__with_arg__no_default
);
503 ATF_ADD_TEST_CASE(tcs
, base_option__long_name__with_arg__with_default
);
505 ATF_ADD_TEST_CASE(tcs
, bool_option__short_name
);
506 ATF_ADD_TEST_CASE(tcs
, bool_option__long_name
);
508 ATF_ADD_TEST_CASE(tcs
, int_option__short_name
);
509 ATF_ADD_TEST_CASE(tcs
, int_option__long_name
);
510 ATF_ADD_TEST_CASE(tcs
, int_option__type
);
512 ATF_ADD_TEST_CASE(tcs
, list_option__short_name
);
513 ATF_ADD_TEST_CASE(tcs
, list_option__long_name
);
514 ATF_ADD_TEST_CASE(tcs
, list_option__type
);
516 ATF_ADD_TEST_CASE(tcs
, path_option__short_name
);
517 ATF_ADD_TEST_CASE(tcs
, path_option__long_name
);
518 ATF_ADD_TEST_CASE(tcs
, path_option__type
);
520 ATF_ADD_TEST_CASE(tcs
, property_option__short_name
);
521 ATF_ADD_TEST_CASE(tcs
, property_option__long_name
);
522 ATF_ADD_TEST_CASE(tcs
, property_option__type
);
524 ATF_ADD_TEST_CASE(tcs
, string_option__short_name
);
525 ATF_ADD_TEST_CASE(tcs
, string_option__long_name
);
526 ATF_ADD_TEST_CASE(tcs
, string_option__type
);