Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // self
21 : //
22 : #include "catch_main.h"
23 :
24 :
25 : // advgetopt lib
26 : //
27 : #include <advgetopt/exception.h>
28 :
29 :
30 : // C++ lib
31 : //
32 : #include <fstream>
33 :
34 :
35 : // last include
36 : //
37 : #include <snapdev/poison.h>
38 :
39 :
40 :
41 :
42 :
43 3 : CATCH_TEST_CASE("to_from_short_name", "[option_info][valid][basic][short_name]")
44 : {
45 2 : CATCH_START_SECTION("Short name to string and back")
46 : {
47 : // wc == U'\0' is a special case
48 : //
49 1 : CATCH_REQUIRE(advgetopt::NO_SHORT_NAME == U'\0');
50 1 : CATCH_REQUIRE(advgetopt::short_name_to_string(U'\0') == std::string());
51 1 : CATCH_REQUIRE(advgetopt::string_to_short_name(std::string()) == U'\0');
52 :
53 1112064 : for(char32_t wc(1); wc < 0x110000; ++wc)
54 : {
55 1112063 : if(wc == 0xD800)
56 : {
57 1 : wc = 0xE000;
58 : }
59 2224126 : std::string str(advgetopt::short_name_to_string(wc));
60 1112063 : CATCH_REQUIRE(advgetopt::string_to_short_name(str) == wc);
61 :
62 : // add a second character to prove that string_to_short_name()
63 : // only works with one character
64 : //
65 1112063 : char32_t const second_char(rand() % (0xD800 - 0x20) + 0x20);
66 1112063 : str += advgetopt::short_name_to_string(second_char);
67 1112063 : CATCH_REQUIRE(advgetopt::string_to_short_name(str) == advgetopt::NO_SHORT_NAME);
68 : }
69 : }
70 : CATCH_END_SECTION()
71 1 : }
72 :
73 :
74 3 : CATCH_TEST_CASE("parsing_string", "[environment][valid]")
75 : {
76 2 : CATCH_START_SECTION("Test parsing of empty environment strings")
77 : {
78 1 : advgetopt::option const options[] =
79 : {
80 : advgetopt::define_option(
81 : advgetopt::Name("empty")
82 : , advgetopt::ShortName('e')
83 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
84 : , advgetopt::Help("the empty option.")
85 : ),
86 : advgetopt::end_options()
87 : };
88 :
89 1 : advgetopt::options_environment environment_options;
90 1 : environment_options.f_project_name = "unittest";
91 1 : environment_options.f_options = options;
92 1 : environment_options.f_help_header = "Usage: test parse_string()";
93 :
94 2 : advgetopt::getopt opt(environment_options);
95 :
96 1 : CATCH_REQUIRE_THROWS_MATCHES(
97 : opt.is_defined("invalid-parameter")
98 : , advgetopt::getopt_initialization
99 : , Catch::Matchers::ExceptionMessage(
100 : "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_integer(), get_double() cannot be called until the parser is done)"));
101 :
102 1 : opt.parse_string("");
103 :
104 : // a parse without anything means that we're still uninitialized
105 : //
106 1 : CATCH_REQUIRE_THROWS_MATCHES(
107 : opt.is_defined("invalid-parameter")
108 : , advgetopt::getopt_initialization
109 : , Catch::Matchers::ExceptionMessage(
110 : "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_integer(), get_double() cannot be called until the parser is done)"));
111 : }
112 : CATCH_END_SECTION()
113 1 : }
114 :
115 :
116 :
117 :
118 :
119 5 : CATCH_TEST_CASE("option_info_basics", "[option_info][valid][basic]")
120 : {
121 6 : CATCH_START_SECTION("Simple option (verify defaults)")
122 2 : advgetopt::option_info verbose("verbose");
123 :
124 1 : CATCH_REQUIRE(verbose.get_name() == "verbose");
125 1 : CATCH_REQUIRE(verbose.get_short_name() == advgetopt::NO_SHORT_NAME);
126 1 : CATCH_REQUIRE_FALSE(verbose.is_default_option());
127 1 : CATCH_REQUIRE(verbose.get_flags() == 0);
128 :
129 1 : advgetopt::flag_t flag(1);
130 31 : do
131 : {
132 32 : CATCH_REQUIRE(verbose.has_flag(flag) == 0);
133 32 : flag <<= 1;
134 : }
135 32 : while(flag != 0);
136 :
137 1 : CATCH_REQUIRE_FALSE(verbose.has_default());
138 1 : CATCH_REQUIRE(verbose.get_default().empty());
139 1 : CATCH_REQUIRE(verbose.get_help().empty());
140 :
141 1 : CATCH_REQUIRE(verbose.get_alias_destination() == nullptr);
142 1 : CATCH_REQUIRE(verbose.get_multiple_separators().empty());
143 1 : CATCH_REQUIRE_FALSE(verbose.is_defined());
144 1 : CATCH_REQUIRE(verbose.size() == 0);
145 : CATCH_END_SECTION()
146 :
147 6 : CATCH_START_SECTION("Auto-default")
148 2 : advgetopt::option_info auto_default("--");
149 :
150 1 : CATCH_REQUIRE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
151 1 : CATCH_REQUIRE(auto_default.is_default_option());
152 :
153 1 : auto_default.add_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
154 :
155 1 : CATCH_REQUIRE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
156 1 : CATCH_REQUIRE(auto_default.is_default_option());
157 :
158 1 : auto_default.remove_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
159 :
160 1 : CATCH_REQUIRE_FALSE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION)); // unfortunate?
161 1 : CATCH_REQUIRE(auto_default.is_default_option());
162 : CATCH_END_SECTION()
163 :
164 6 : CATCH_START_SECTION("Explicit default")
165 2 : advgetopt::option_info explicit_default("filenames", 'f');
166 :
167 1 : CATCH_REQUIRE_FALSE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
168 1 : CATCH_REQUIRE_FALSE(explicit_default.is_default_option());
169 :
170 1 : explicit_default.add_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
171 :
172 1 : CATCH_REQUIRE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
173 1 : CATCH_REQUIRE(explicit_default.is_default_option());
174 :
175 1 : explicit_default.remove_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
176 :
177 1 : CATCH_REQUIRE_FALSE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
178 1 : CATCH_REQUIRE_FALSE(explicit_default.is_default_option());
179 : CATCH_END_SECTION()
180 3 : }
181 :
182 :
183 :
184 3 : CATCH_TEST_CASE("option_info_flags", "[option_info][valid][flags]")
185 : {
186 2 : CATCH_START_SECTION("Check flags")
187 2 : advgetopt::option_info flags("flags", 'f');
188 :
189 1 : advgetopt::flag_t flag(1);
190 31 : do
191 : {
192 32 : CATCH_REQUIRE(flags.get_flags() == 0);
193 :
194 32 : advgetopt::flag_t clear(1);
195 992 : do
196 : {
197 1024 : CATCH_REQUIRE_FALSE(flags.has_flag(clear));
198 1024 : clear <<= 1;
199 : }
200 1024 : while(clear != 0);
201 :
202 32 : flags.add_flag(flag);
203 32 : CATCH_REQUIRE(flags.has_flag(flag));
204 32 : CATCH_REQUIRE(flags.get_flags() == flag);
205 :
206 32 : advgetopt::flag_t set(1);
207 992 : do
208 : {
209 1024 : if(set == flag)
210 : {
211 32 : CATCH_REQUIRE(flags.has_flag(set));
212 : }
213 : else
214 : {
215 992 : CATCH_REQUIRE_FALSE(flags.has_flag(set));
216 : }
217 1024 : set <<= 1;
218 : }
219 1024 : while(set != 0);
220 :
221 32 : flags.remove_flag(flag);
222 32 : CATCH_REQUIRE(flags.get_flags() == 0);
223 :
224 32 : clear = 1;
225 992 : do
226 : {
227 1024 : CATCH_REQUIRE_FALSE(flags.has_flag(clear));
228 1024 : clear <<= 1;
229 : }
230 1024 : while(clear != 0);
231 :
232 32 : flag <<= 1;
233 : }
234 32 : while(flag != 0);
235 :
236 1 : flag = 1;
237 31 : do
238 : {
239 32 : CATCH_REQUIRE(flags.get_flags() == 0);
240 :
241 32 : advgetopt::flag_t clear(1);
242 992 : do
243 : {
244 1024 : CATCH_REQUIRE_FALSE(flags.has_flag(clear));
245 1024 : clear <<= 1;
246 : }
247 1024 : while(clear != 0);
248 :
249 32 : flags.set_flags(flag);
250 32 : CATCH_REQUIRE(flags.has_flag(flag));
251 32 : CATCH_REQUIRE(flags.get_flags() == flag);
252 :
253 32 : advgetopt::flag_t set(1);
254 992 : do
255 : {
256 1024 : if(set == flag)
257 : {
258 32 : CATCH_REQUIRE(flags.has_flag(set));
259 : }
260 : else
261 : {
262 992 : CATCH_REQUIRE_FALSE(flags.has_flag(set));
263 : }
264 1024 : set <<= 1;
265 : }
266 1024 : while(set != 0);
267 :
268 32 : flags.set_flags(0);
269 32 : CATCH_REQUIRE(flags.get_flags() == 0);
270 :
271 32 : clear = 1;
272 992 : do
273 : {
274 1024 : CATCH_REQUIRE_FALSE(flags.has_flag(clear));
275 1024 : clear <<= 1;
276 : }
277 1024 : while(clear != 0);
278 :
279 32 : flag <<= 1;
280 : }
281 32 : while(flag != 0);
282 : CATCH_END_SECTION()
283 1 : }
284 :
285 :
286 :
287 3 : CATCH_TEST_CASE("option_info_default", "[option_info][valid][default]")
288 : {
289 2 : CATCH_START_SECTION("Set/remove default")
290 2 : advgetopt::option_info with_default("with_default", 'w');
291 :
292 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
293 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
294 1 : CATCH_REQUIRE(with_default.get_default().empty());
295 :
296 1 : with_default.set_default("working");
297 1 : CATCH_REQUIRE(with_default.has_default());
298 1 : CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
299 1 : CATCH_REQUIRE(with_default.get_default() == "working");
300 :
301 1 : with_default.remove_default();
302 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
303 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
304 1 : CATCH_REQUIRE(with_default.get_default().empty());
305 :
306 2 : std::string const default_value("other");
307 1 : with_default.set_default(default_value);
308 1 : CATCH_REQUIRE(with_default.has_default());
309 1 : CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
310 1 : CATCH_REQUIRE(with_default.get_default() == default_value);
311 :
312 1 : with_default.remove_default();
313 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
314 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
315 1 : CATCH_REQUIRE(with_default.get_default().empty());
316 :
317 2 : std::string const empty_default;
318 1 : with_default.set_default(empty_default);
319 1 : CATCH_REQUIRE(with_default.has_default());
320 1 : CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
321 1 : CATCH_REQUIRE(with_default.get_default().empty());
322 :
323 1 : with_default.remove_default();
324 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
325 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
326 1 : CATCH_REQUIRE(with_default.get_default().empty());
327 :
328 1 : with_default.set_default(nullptr); // no effects
329 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
330 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
331 1 : CATCH_REQUIRE(with_default.get_default().empty());
332 :
333 2 : std::string const null_value("null works too");
334 1 : with_default.set_default(null_value);
335 1 : CATCH_REQUIRE(with_default.has_default());
336 1 : CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
337 1 : CATCH_REQUIRE(with_default.get_default() == null_value);
338 :
339 1 : with_default.set_default(nullptr); // no effects
340 1 : CATCH_REQUIRE(with_default.has_default());
341 1 : CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
342 1 : CATCH_REQUIRE(with_default.get_default() == null_value);
343 :
344 1 : with_default.remove_default();
345 1 : CATCH_REQUIRE_FALSE(with_default.has_default());
346 1 : CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
347 1 : CATCH_REQUIRE(with_default.get_default().empty());
348 : CATCH_END_SECTION()
349 1 : }
350 :
351 :
352 :
353 3 : CATCH_TEST_CASE("option_info_help", "[option_info][valid][help]")
354 : {
355 2 : CATCH_START_SECTION("Check help")
356 2 : advgetopt::option_info help("help", 'h');
357 :
358 1 : CATCH_REQUIRE(help.get_help().empty());
359 :
360 1 : help.set_help("help me");
361 1 : CATCH_REQUIRE(help.get_help() == "help me");
362 :
363 2 : std::string const msg("help msg");
364 1 : help.set_help(msg);
365 1 : CATCH_REQUIRE(help.get_help() == msg);
366 :
367 1 : help.set_help(nullptr);
368 1 : CATCH_REQUIRE(help.get_help() == msg);
369 :
370 1 : help.set_help("");
371 1 : CATCH_REQUIRE(help.get_help().empty());
372 : CATCH_END_SECTION()
373 1 : }
374 :
375 :
376 :
377 6 : CATCH_TEST_CASE("option_info_validator", "[option_info][valid][validator]")
378 : {
379 8 : CATCH_START_SECTION("Check validator (one value)")
380 : {
381 2 : advgetopt::option_info auto_validate("validator", 'C');
382 1 : auto_validate.set_flags(advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION);
383 :
384 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
385 :
386 1 : auto_validate.set_value(0, "51");
387 1 : CATCH_REQUIRE(auto_validate.size() == 1);
388 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "51");
389 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 51);
390 1 : CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_DIRECT);
391 :
392 1 : auto_validate.set_validator(nullptr);
393 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
394 :
395 2 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", {"1","2","5","6","8"}));
396 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"51\" given to parameter --validator is not considered valid.");
397 1 : auto_validate.set_validator(integer_validator);
398 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
399 1 : CATCH_REQUIRE(auto_validate.get_validator() == integer_validator);
400 :
401 1 : auto_validate.set_value(0, "6", advgetopt::option_source_t::SOURCE_DYNAMIC);
402 1 : CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_DYNAMIC);
403 :
404 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"3\" given to parameter --validator is not considered valid.");
405 1 : auto_validate.set_value(0, "3", advgetopt::option_source_t::SOURCE_CONFIGURATION);
406 1 : CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_UNDEFINED); // it doesn't take... it gets cleared though
407 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
408 :
409 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"11\" given to parameter --validator is not considered valid.");
410 1 : auto_validate.set_value(0, "11", advgetopt::option_source_t::SOURCE_ENVIRONMENT_VARIABLE);
411 1 : CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_UNDEFINED); // it doesn't take... it gets cleared though
412 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
413 : }
414 : CATCH_END_SECTION()
415 :
416 8 : CATCH_START_SECTION("Check validator (multiple values)")
417 : {
418 2 : advgetopt::option_info auto_validate("validator", 'C');
419 :
420 1 : auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
421 :
422 2 : advgetopt::string_list_t list{","};
423 1 : auto_validate.set_multiple_separators(list);
424 :
425 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
426 :
427 1 : auto_validate.set_value(0, "-15", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
428 1 : CATCH_REQUIRE(auto_validate.size() == 1);
429 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "-15");
430 1 : CATCH_REQUIRE(auto_validate.get_long(0) == -15);
431 :
432 1 : auto_validate.set_validator(nullptr);
433 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
434 :
435 2 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", {"-1","2","5","6","18"}));
436 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"-15\" given to parameter --validator is not considered valid.");
437 1 : auto_validate.set_validator(integer_validator);
438 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
439 1 : CATCH_REQUIRE(auto_validate.get_validator() == integer_validator);
440 :
441 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"3\" given to parameter --validator is not considered valid.");
442 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"11\" given to parameter --validator is not considered valid.");
443 1 : CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
444 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
445 1 : CATCH_REQUIRE(auto_validate.size() == 2);
446 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "6");
447 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 6);
448 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "18");
449 1 : CATCH_REQUIRE(auto_validate.get_long(1) == 18);
450 :
451 1 : auto_validate.set_validator(nullptr);
452 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
453 :
454 1 : CATCH_REQUIRE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
455 1 : CATCH_REQUIRE(auto_validate.size() == 4);
456 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "6");
457 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 6);
458 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "3");
459 1 : CATCH_REQUIRE(auto_validate.get_long(1) == 3);
460 1 : CATCH_REQUIRE(auto_validate.get_value(2) == "18");
461 1 : CATCH_REQUIRE(auto_validate.get_long(2) == 18);
462 1 : CATCH_REQUIRE(auto_validate.get_value(3) == "11");
463 1 : CATCH_REQUIRE(auto_validate.get_long(3) == 11);
464 : }
465 : CATCH_END_SECTION()
466 :
467 8 : CATCH_START_SECTION("Check integer validator from string (multiple values)")
468 : {
469 2 : advgetopt::option_info auto_validate("validator", 'C');
470 :
471 1 : auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
472 :
473 2 : advgetopt::string_list_t list{","};
474 1 : auto_validate.set_multiple_separators(list);
475 :
476 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
477 :
478 1 : auto_validate.set_value(0, "35", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
479 1 : CATCH_REQUIRE(auto_validate.size() == 1);
480 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "35");
481 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 35);
482 :
483 1 : auto_validate.set_validator(nullptr);
484 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
485 :
486 1 : auto_validate.set_validator(std::string());
487 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
488 :
489 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"35\" given to parameter --validator is not considered valid.");
490 1 : auto_validate.set_validator("integer(-1,2,5,6,18)");
491 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
492 1 : CATCH_REQUIRE(auto_validate.get_validator() != nullptr);
493 1 : CATCH_REQUIRE(auto_validate.get_validator()->name() == "integer");
494 :
495 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"3\" given to parameter --validator is not considered valid.");
496 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"11\" given to parameter --validator is not considered valid.");
497 1 : CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
498 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
499 1 : CATCH_REQUIRE(auto_validate.size() == 2);
500 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "6");
501 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 6);
502 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "18");
503 1 : CATCH_REQUIRE(auto_validate.get_long(1) == 18);
504 :
505 1 : auto_validate.set_validator(std::string());
506 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
507 :
508 1 : CATCH_REQUIRE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
509 1 : CATCH_REQUIRE(auto_validate.size() == 4);
510 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "6");
511 1 : CATCH_REQUIRE(auto_validate.get_long(0) == 6);
512 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "3");
513 1 : CATCH_REQUIRE(auto_validate.get_long(1) == 3);
514 1 : CATCH_REQUIRE(auto_validate.get_value(2) == "18");
515 1 : CATCH_REQUIRE(auto_validate.get_long(2) == 18);
516 1 : CATCH_REQUIRE(auto_validate.get_value(3) == "11");
517 1 : CATCH_REQUIRE(auto_validate.get_long(3) == 11);
518 : }
519 : CATCH_END_SECTION()
520 :
521 8 : CATCH_START_SECTION("Check regex validator from string (multiple values)")
522 : {
523 2 : advgetopt::option_info auto_validate("validator", 'C');
524 :
525 1 : auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
526 :
527 2 : advgetopt::string_list_t list{","};
528 1 : auto_validate.set_multiple_separators(list);
529 :
530 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
531 :
532 1 : auto_validate.set_value(0, "abc", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
533 1 : CATCH_REQUIRE(auto_validate.size() == 1);
534 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
535 :
536 1 : auto_validate.set_validator(nullptr);
537 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
538 :
539 1 : auto_validate.set_validator(std::string());
540 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
541 :
542 1 : auto_validate.set_validator("/^[a-z]+$/");
543 1 : CATCH_REQUIRE(auto_validate.get_validator() != nullptr);
544 1 : CATCH_REQUIRE(auto_validate.get_validator()->name() == "regex");
545 :
546 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"33\" given to parameter --validator is not considered valid.");
547 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"45\" given to parameter --validator is not considered valid.");
548 1 : CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("abc,qqq,33,zac,pop,45", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
549 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
550 1 : CATCH_REQUIRE(auto_validate.size() == 4);
551 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
552 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "qqq");
553 1 : CATCH_REQUIRE(auto_validate.get_value(2) == "zac");
554 1 : CATCH_REQUIRE(auto_validate.get_value(3) == "pop");
555 :
556 1 : auto_validate.set_validator(std::string());
557 1 : CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
558 :
559 1 : CATCH_REQUIRE(auto_validate.set_multiple_values("abc,-56,zoc", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
560 1 : CATCH_REQUIRE(auto_validate.size() == 3);
561 1 : CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
562 1 : CATCH_REQUIRE(auto_validate.get_value(1) == "-56");
563 1 : CATCH_REQUIRE(auto_validate.get_value(2) == "zoc");
564 : }
565 : CATCH_END_SECTION()
566 4 : }
567 :
568 :
569 :
570 :
571 3 : CATCH_TEST_CASE("option_info_alias", "[option_info][valid][alias]")
572 : {
573 2 : CATCH_START_SECTION("Check alias")
574 2 : advgetopt::option_info::pointer_t option(std::make_shared<advgetopt::option_info>("option", 'o'));
575 2 : advgetopt::option_info alias("alias", 'a');
576 :
577 1 : CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
578 :
579 1 : alias.set_alias_destination(option);
580 :
581 1 : CATCH_REQUIRE(alias.get_alias_destination() == option);
582 : CATCH_END_SECTION()
583 1 : }
584 :
585 :
586 :
587 3 : CATCH_TEST_CASE("option_info_multiple_separators", "[option_info][valid][separators][multiple]")
588 : {
589 2 : CATCH_START_SECTION("Check multiple separators")
590 2 : advgetopt::option_info separators("names", 'n');
591 :
592 1 : separators.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
593 :
594 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
595 :
596 1 : separators.set_multiple_separators(nullptr);
597 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
598 :
599 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
600 1 : CATCH_REQUIRE(separators.size() == 1);
601 1 : CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
602 :
603 2 : advgetopt::string_list_t empty_list;
604 1 : separators.set_multiple_separators(empty_list);
605 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
606 :
607 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
608 1 : CATCH_REQUIRE(separators.size() == 1);
609 1 : CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
610 :
611 1 : char const * const empty_separator_list[]{
612 : nullptr
613 : };
614 1 : separators.set_multiple_separators(empty_separator_list);
615 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
616 :
617 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
618 1 : CATCH_REQUIRE(separators.size() == 1);
619 1 : CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
620 :
621 1 : char const * const separator_list[]{
622 : ",",
623 : ";",
624 : " ",
625 : "^",
626 : nullptr
627 : };
628 1 : separators.set_multiple_separators(separator_list);
629 1 : CATCH_REQUIRE(separators.get_multiple_separators().size() == 4);
630 :
631 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
632 1 : CATCH_REQUIRE(separators.size() == 5);
633 1 : CATCH_REQUIRE(separators.get_value(0) == "n1");
634 1 : CATCH_REQUIRE(separators.get_value(1) == "n2");
635 1 : CATCH_REQUIRE(separators.get_value(2) == "n3");
636 1 : CATCH_REQUIRE(separators.get_value(3) == "n4");
637 1 : CATCH_REQUIRE(separators.get_value(4) == "n5");
638 :
639 1 : separators.set_multiple_separators(empty_separator_list);
640 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
641 :
642 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
643 1 : CATCH_REQUIRE(separators.size() == 1);
644 1 : CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
645 :
646 1 : advgetopt::string_list_t list{
647 : ",",
648 : ";",
649 : " ",
650 : "^",
651 2 : };
652 1 : separators.set_multiple_separators(list);
653 1 : CATCH_REQUIRE(separators.get_multiple_separators().size() == 4);
654 :
655 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
656 1 : CATCH_REQUIRE(separators.size() == 5);
657 1 : CATCH_REQUIRE(separators.get_value(0) == "n1");
658 1 : CATCH_REQUIRE(separators.get_value(1) == "n2");
659 1 : CATCH_REQUIRE(separators.get_value(2) == "n3");
660 1 : CATCH_REQUIRE(separators.get_value(3) == "n4");
661 1 : CATCH_REQUIRE(separators.get_value(4) == "n5");
662 :
663 1 : separators.set_multiple_separators(empty_list);
664 1 : CATCH_REQUIRE(separators.get_multiple_separators().empty());
665 :
666 1 : CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE));
667 1 : CATCH_REQUIRE(separators.size() == 1);
668 1 : CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
669 : CATCH_END_SECTION()
670 1 : }
671 :
672 :
673 :
674 6 : CATCH_TEST_CASE("option_info_add_value", "[option_info][valid][add][multiple]")
675 : {
676 8 : CATCH_START_SECTION("Add value, verify lock (add/remove flag explicitly)")
677 2 : advgetopt::option_info one_value("names", 'n');
678 :
679 1 : CATCH_REQUIRE(one_value.size() == 0);
680 :
681 1 : one_value.add_value("value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
682 1 : CATCH_REQUIRE(one_value.size() == 1);
683 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
684 :
685 1 : one_value.add_value("value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
686 1 : CATCH_REQUIRE(one_value.size() == 1);
687 1 : CATCH_REQUIRE(one_value.get_value(0) == "value two");
688 :
689 1 : one_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
690 :
691 1 : one_value.add_value("value three", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
692 1 : CATCH_REQUIRE(one_value.size() == 1);
693 1 : CATCH_REQUIRE(one_value.get_value(0) == "value two");
694 :
695 1 : one_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
696 :
697 1 : one_value.add_value("value four", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
698 1 : CATCH_REQUIRE(one_value.size() == 1);
699 1 : CATCH_REQUIRE(one_value.get_value(0) == "value four");
700 :
701 1 : one_value.reset();
702 1 : CATCH_REQUIRE(one_value.size() == 0);
703 :
704 : // to verify that the f_integer was reset we kind of very much
705 : // have to re-add a value
706 : //
707 1 : one_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
708 1 : CATCH_REQUIRE(one_value.size() == 1);
709 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
710 : CATCH_END_SECTION()
711 :
712 8 : CATCH_START_SECTION("Add value, verify integer")
713 2 : advgetopt::option_info one_value("names", 'n');
714 :
715 1 : CATCH_REQUIRE(one_value.size() == 0);
716 :
717 1 : one_value.add_value("123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
718 1 : CATCH_REQUIRE(one_value.size() == 1);
719 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
720 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
721 :
722 1 : one_value.add_value("456", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
723 1 : CATCH_REQUIRE(one_value.size() == 1);
724 1 : CATCH_REQUIRE(one_value.get_value(0) == "456");
725 1 : CATCH_REQUIRE(one_value.get_long(0) == 456);
726 :
727 1 : one_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
728 :
729 1 : one_value.add_value("789", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
730 1 : CATCH_REQUIRE(one_value.size() == 1);
731 1 : CATCH_REQUIRE(one_value.get_value(0) == "456");
732 1 : CATCH_REQUIRE(one_value.get_long(0) == 456);
733 :
734 1 : one_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
735 :
736 1 : one_value.add_value("505", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
737 1 : CATCH_REQUIRE(one_value.size() == 1);
738 1 : CATCH_REQUIRE(one_value.get_value(0) == "505");
739 1 : CATCH_REQUIRE(one_value.get_long(0) == 505);
740 :
741 1 : one_value.reset();
742 1 : CATCH_REQUIRE(one_value.size() == 0);
743 :
744 : // to verify that the f_integer was reset we kind of very much
745 : // have to re-add a value
746 : //
747 1 : one_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
748 1 : CATCH_REQUIRE(one_value.size() == 1);
749 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
750 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
751 : CATCH_END_SECTION()
752 :
753 8 : CATCH_START_SECTION("Add value, verify multiple strings")
754 2 : advgetopt::option_info multi_value("names", 'n');
755 :
756 1 : CATCH_REQUIRE(multi_value.size() == 0);
757 :
758 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
759 :
760 1 : multi_value.add_value("value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
761 1 : CATCH_REQUIRE(multi_value.size() == 1);
762 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
763 :
764 1 : multi_value.add_value("value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
765 1 : CATCH_REQUIRE(multi_value.size() == 2);
766 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
767 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
768 :
769 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
770 :
771 1 : multi_value.add_value("value three", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
772 1 : CATCH_REQUIRE(multi_value.size() == 2);
773 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
774 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
775 :
776 1 : multi_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
777 :
778 1 : multi_value.add_value("value four", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
779 1 : CATCH_REQUIRE(multi_value.size() == 3);
780 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
781 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
782 1 : CATCH_REQUIRE(multi_value.get_value(2) == "value four");
783 :
784 1 : multi_value.reset();
785 1 : CATCH_REQUIRE(multi_value.size() == 0);
786 :
787 : // to verify that the f_integer was reset we kind of very much
788 : // have to re-add a value
789 : //
790 1 : multi_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
791 1 : CATCH_REQUIRE(multi_value.size() == 1);
792 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
793 : CATCH_END_SECTION()
794 :
795 8 : CATCH_START_SECTION("Add value, verify multiple integers")
796 2 : advgetopt::option_info multi_value("names", 'n');
797 :
798 1 : CATCH_REQUIRE(multi_value.size() == 0);
799 :
800 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
801 :
802 1 : multi_value.add_value("123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
803 1 : CATCH_REQUIRE(multi_value.size() == 1);
804 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
805 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
806 :
807 1 : multi_value.add_value("456", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
808 1 : CATCH_REQUIRE(multi_value.size() == 2);
809 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
810 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
811 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
812 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
813 :
814 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
815 :
816 1 : multi_value.add_value("789", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
817 1 : CATCH_REQUIRE(multi_value.size() == 2);
818 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
819 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
820 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
821 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
822 :
823 1 : multi_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
824 :
825 1 : multi_value.add_value("505", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
826 1 : CATCH_REQUIRE(multi_value.size() == 3);
827 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
828 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
829 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
830 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
831 1 : CATCH_REQUIRE(multi_value.get_value(2) == "505");
832 1 : CATCH_REQUIRE(multi_value.get_long(2) == 505);
833 :
834 1 : multi_value.reset();
835 1 : CATCH_REQUIRE(multi_value.size() == 0);
836 :
837 : // to verify that the f_integer was reset we kind of very much
838 : // have to re-add a value
839 : //
840 1 : multi_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
841 1 : CATCH_REQUIRE(multi_value.size() == 1);
842 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
843 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
844 : CATCH_END_SECTION()
845 4 : }
846 :
847 :
848 :
849 6 : CATCH_TEST_CASE("option_info_set_value", "[option_info][valid][set][multiple]")
850 : {
851 8 : CATCH_START_SECTION("Set value, verify lock (use lock()/unlock() functions)")
852 2 : advgetopt::option_info one_value("names", 'n');
853 :
854 1 : CATCH_REQUIRE(one_value.size() == 0);
855 :
856 1 : one_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
857 1 : CATCH_REQUIRE(one_value.size() == 1);
858 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
859 :
860 1 : one_value.set_value(0, "value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
861 1 : CATCH_REQUIRE(one_value.size() == 1);
862 1 : CATCH_REQUIRE(one_value.get_value(0) == "value two");
863 :
864 1 : one_value.lock();
865 :
866 1 : one_value.set_value(0, "value three", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
867 1 : CATCH_REQUIRE(one_value.size() == 1);
868 1 : CATCH_REQUIRE(one_value.get_value(0) == "value two");
869 :
870 1 : one_value.unlock();
871 :
872 1 : one_value.set_value(0, "value four", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
873 1 : CATCH_REQUIRE(one_value.size() == 1);
874 1 : CATCH_REQUIRE(one_value.get_value(0) == "value four");
875 :
876 1 : one_value.reset();
877 1 : CATCH_REQUIRE(one_value.size() == 0);
878 :
879 : // to verify that the f_integer was reset we kind of very much
880 : // have to re-add a value
881 : //
882 1 : one_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
883 1 : CATCH_REQUIRE(one_value.size() == 1);
884 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
885 : CATCH_END_SECTION()
886 :
887 8 : CATCH_START_SECTION("Set value, verify integer")
888 2 : advgetopt::option_info one_value("names", 'n');
889 :
890 1 : CATCH_REQUIRE(one_value.size() == 0);
891 :
892 1 : one_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
893 1 : CATCH_REQUIRE(one_value.size() == 1);
894 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
895 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
896 :
897 1 : one_value.set_value(0, "456", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
898 1 : CATCH_REQUIRE(one_value.size() == 1);
899 1 : CATCH_REQUIRE(one_value.get_value(0) == "456");
900 1 : CATCH_REQUIRE(one_value.get_long(0) == 456);
901 :
902 1 : one_value.lock();
903 :
904 1 : one_value.set_value(0, "789", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
905 1 : CATCH_REQUIRE(one_value.size() == 1);
906 1 : CATCH_REQUIRE(one_value.get_value(0) == "456");
907 1 : CATCH_REQUIRE(one_value.get_long(0) == 456);
908 :
909 1 : one_value.unlock();
910 :
911 1 : one_value.set_value(0, "505", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
912 1 : CATCH_REQUIRE(one_value.size() == 1);
913 1 : CATCH_REQUIRE(one_value.get_value(0) == "505");
914 1 : CATCH_REQUIRE(one_value.get_long(0) == 505);
915 :
916 1 : one_value.reset();
917 1 : CATCH_REQUIRE(one_value.size() == 0);
918 :
919 : // to verify that the f_integer was reset we kind of very much
920 : // have to re-add a value
921 : //
922 1 : one_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
923 1 : CATCH_REQUIRE(one_value.size() == 1);
924 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
925 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
926 : CATCH_END_SECTION()
927 :
928 8 : CATCH_START_SECTION("Set value, verify multiple strings (with MULTIPLE & lock(false))")
929 2 : advgetopt::option_info multi_value("names", 'n');
930 :
931 1 : multi_value.lock(false);
932 :
933 1 : CATCH_REQUIRE(multi_value.size() == 0);
934 :
935 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
936 :
937 1 : multi_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
938 1 : CATCH_REQUIRE(multi_value.size() == 1);
939 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
940 :
941 1 : multi_value.set_value(1, "value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
942 1 : CATCH_REQUIRE(multi_value.size() == 2);
943 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
944 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
945 :
946 1 : multi_value.lock(false);
947 :
948 1 : multi_value.set_value(2, "value three", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
949 1 : CATCH_REQUIRE(multi_value.size() == 2);
950 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
951 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
952 :
953 1 : multi_value.unlock();
954 :
955 1 : multi_value.set_value(2, "value four", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
956 1 : CATCH_REQUIRE(multi_value.size() == 3);
957 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
958 1 : CATCH_REQUIRE(multi_value.get_value(1) == "value two");
959 1 : CATCH_REQUIRE(multi_value.get_value(2) == "value four");
960 :
961 1 : multi_value.reset();
962 1 : CATCH_REQUIRE(multi_value.size() == 0);
963 :
964 : // to verify that the f_integer was reset we kind of very much
965 : // have to re-add a value
966 : //
967 1 : multi_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
968 1 : CATCH_REQUIRE(multi_value.size() == 1);
969 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
970 : CATCH_END_SECTION()
971 :
972 8 : CATCH_START_SECTION("Set value, verify multiple integers (with MULTIPLE & lock(false))")
973 2 : advgetopt::option_info multi_value("names", 'n');
974 :
975 1 : CATCH_REQUIRE(multi_value.size() == 0);
976 :
977 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
978 :
979 1 : multi_value.lock(false);
980 :
981 1 : multi_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
982 1 : CATCH_REQUIRE(multi_value.size() == 1);
983 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
984 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
985 :
986 1 : multi_value.set_value(1, "456", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
987 1 : CATCH_REQUIRE(multi_value.size() == 2);
988 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
989 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
990 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
991 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
992 :
993 1 : multi_value.lock(false);
994 :
995 1 : multi_value.set_value(2, "789", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
996 1 : CATCH_REQUIRE(multi_value.size() == 2);
997 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
998 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
999 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
1000 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
1001 :
1002 1 : multi_value.unlock();
1003 :
1004 1 : multi_value.set_value(2, "505", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1005 1 : CATCH_REQUIRE(multi_value.size() == 3);
1006 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
1007 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
1008 1 : CATCH_REQUIRE(multi_value.get_value(1) == "456");
1009 1 : CATCH_REQUIRE(multi_value.get_long(1) == 456);
1010 1 : CATCH_REQUIRE(multi_value.get_value(2) == "505");
1011 1 : CATCH_REQUIRE(multi_value.get_long(2) == 505);
1012 :
1013 1 : multi_value.reset();
1014 1 : CATCH_REQUIRE(multi_value.size() == 0);
1015 :
1016 : // to verify that the f_integer was reset we kind of very much
1017 : // have to re-add a value
1018 : //
1019 1 : multi_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1020 1 : CATCH_REQUIRE(multi_value.size() == 1);
1021 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
1022 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
1023 : CATCH_END_SECTION()
1024 4 : }
1025 :
1026 :
1027 :
1028 6 : CATCH_TEST_CASE("option_info_section_functions", "[option_info][valid][add][section]")
1029 : {
1030 8 : CATCH_START_SECTION("Value without sections")
1031 2 : advgetopt::option_info value("no-sections", 'z');
1032 :
1033 1 : CATCH_REQUIRE(value.get_basename() == "no-sections");
1034 1 : CATCH_REQUIRE(value.get_section_name() == std::string());
1035 1 : CATCH_REQUIRE(value.get_section_name_list().empty());
1036 : CATCH_END_SECTION()
1037 :
1038 8 : CATCH_START_SECTION("Value with one section")
1039 2 : advgetopt::option_info value("one::section", 'o');
1040 :
1041 1 : CATCH_REQUIRE(value.get_basename() == "section");
1042 1 : CATCH_REQUIRE(value.get_section_name() == "one");
1043 2 : advgetopt::string_list_t sections(value.get_section_name_list());
1044 1 : CATCH_REQUIRE(sections.size() == 1);
1045 1 : CATCH_REQUIRE(sections[0] == "one");
1046 : CATCH_END_SECTION()
1047 :
1048 8 : CATCH_START_SECTION("Value with two sections")
1049 2 : advgetopt::option_info value("one::two::section", 't');
1050 :
1051 1 : CATCH_REQUIRE(value.get_basename() == "section");
1052 1 : CATCH_REQUIRE(value.get_section_name() == "one::two");
1053 2 : advgetopt::string_list_t sections(value.get_section_name_list());
1054 1 : CATCH_REQUIRE(sections.size() == 2);
1055 1 : CATCH_REQUIRE(sections[0] == "one");
1056 1 : CATCH_REQUIRE(sections[1] == "two");
1057 : CATCH_END_SECTION()
1058 :
1059 8 : CATCH_START_SECTION("Value with three sections")
1060 2 : advgetopt::option_info value("s1::s2::s3::section", 'f');
1061 :
1062 1 : CATCH_REQUIRE(value.get_basename() == "section");
1063 1 : CATCH_REQUIRE(value.get_section_name() == "s1::s2::s3");
1064 2 : advgetopt::string_list_t sections(value.get_section_name_list());
1065 1 : CATCH_REQUIRE(sections.size() == 3);
1066 1 : CATCH_REQUIRE(sections[0] == "s1");
1067 1 : CATCH_REQUIRE(sections[1] == "s2");
1068 1 : CATCH_REQUIRE(sections[2] == "s3");
1069 : CATCH_END_SECTION()
1070 4 : }
1071 :
1072 :
1073 :
1074 :
1075 3 : CATCH_TEST_CASE("redefine_option_short_name", "[options][valid][config]")
1076 : {
1077 2 : CATCH_START_SECTION("Test adding '-<delta>' to '--config-dir'")
1078 : {
1079 1 : advgetopt::option const options[] =
1080 : {
1081 : advgetopt::define_option(
1082 : advgetopt::Name("group")
1083 : , advgetopt::ShortName('g')
1084 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1085 : , advgetopt::Help("group name.")
1086 : ),
1087 : advgetopt::end_options()
1088 : };
1089 :
1090 1 : advgetopt::options_environment environment_options;
1091 1 : environment_options.f_project_name = "unittest";
1092 1 : environment_options.f_options = options;
1093 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1094 1 : environment_options.f_configuration_filename = "snaplog.conf";
1095 1 : environment_options.f_help_header = "Usage: test --config-dir";
1096 :
1097 1 : char const * cargv[] =
1098 : {
1099 : "/usr/bin/arguments",
1100 : "-g",
1101 : "m2osw",
1102 : "-L",
1103 : "-\xE2\xB5\xA0", // Delta character
1104 : "/opt/advgetopt/config",
1105 : nullptr
1106 : };
1107 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
1108 1 : char ** argv = const_cast<char **>(cargv);
1109 :
1110 2 : advgetopt::getopt opt(environment_options);
1111 1 : opt.parse_program_name(argv);
1112 :
1113 1 : CATCH_REQUIRE(opt.get_option("config-dir") != nullptr);
1114 1 : CATCH_REQUIRE(opt.get_option("config-dir") == opt.get_option("config_dir"));
1115 1 : opt.set_short_name("config-dir", 0x2D60);
1116 :
1117 1 : opt.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1118 :
1119 : // check that the result is valid
1120 :
1121 : // an invalid parameter, MUST NOT EXIST
1122 1 : CATCH_REQUIRE(opt.get_option("invalid-parameter") == nullptr);
1123 1 : CATCH_REQUIRE(opt.get_option("invalid-parameter") == opt.get_option("invalid_parameter"));
1124 1 : CATCH_REQUIRE(opt.get_option('Z') == nullptr);
1125 1 : CATCH_REQUIRE_FALSE(opt.is_defined("invalid-parameter"));
1126 1 : CATCH_REQUIRE(opt.get_default("invalid-parameter").empty());
1127 1 : CATCH_REQUIRE(opt.size("invalid-parameter") == 0);
1128 :
1129 : // the valid parameter
1130 1 : CATCH_REQUIRE(opt.get_option("group") != nullptr);
1131 1 : CATCH_REQUIRE(opt.get_option('g') == opt.get_option("group"));
1132 1 : CATCH_REQUIRE(opt.is_defined("group"));
1133 1 : CATCH_REQUIRE(opt.get_string("group") == "m2osw");
1134 1 : CATCH_REQUIRE(opt.get_string("group", 0) == "m2osw");
1135 1 : CATCH_REQUIRE(opt.get_default("group").empty());
1136 1 : CATCH_REQUIRE(opt.size("group") == 1);
1137 :
1138 : // the license system parameter
1139 1 : CATCH_REQUIRE(opt.get_option("license") != nullptr);
1140 1 : CATCH_REQUIRE(opt.get_option('L') == opt.get_option("license"));
1141 1 : CATCH_REQUIRE(opt.is_defined("license"));
1142 1 : CATCH_REQUIRE(opt.get_default("license").empty());
1143 1 : CATCH_REQUIRE(opt.size("license") == 1);
1144 :
1145 : // the config-dir system parameter
1146 1 : CATCH_REQUIRE(opt.get_option("config-dir") != nullptr);
1147 1 : CATCH_REQUIRE(opt.get_option(static_cast<advgetopt::short_name_t>(0x2D60)) == opt.get_option("config-dir"));
1148 1 : CATCH_REQUIRE(opt.is_defined("config-dir"));
1149 1 : CATCH_REQUIRE(opt.get_default("config-dir").empty());
1150 1 : CATCH_REQUIRE(opt.size("config-dir") == 1);
1151 1 : CATCH_REQUIRE(opt.get_string("config-dir") == "/opt/advgetopt/config");
1152 :
1153 : // other parameters
1154 1 : CATCH_REQUIRE(opt.get_program_name() == "arguments");
1155 1 : CATCH_REQUIRE(opt.get_program_fullname() == "/usr/bin/arguments");
1156 : }
1157 : CATCH_END_SECTION()
1158 1 : }
1159 :
1160 :
1161 :
1162 :
1163 :
1164 :
1165 :
1166 :
1167 :
1168 18 : CATCH_TEST_CASE("invalid_option_info", "[option_info][invalid]")
1169 : {
1170 32 : CATCH_START_SECTION("No name")
1171 1 : CATCH_REQUIRE_THROWS_MATCHES(
1172 : advgetopt::option_info("")
1173 : , advgetopt::getopt_logic_error
1174 : , Catch::Matchers::ExceptionMessage(
1175 : "getopt_logic_error: option_info::option_info(): all options must at least have a long name."));
1176 :
1177 1 : CATCH_REQUIRE_THROWS_MATCHES(
1178 : advgetopt::option_info("", 'v')
1179 : , advgetopt::getopt_logic_error
1180 : , Catch::Matchers::ExceptionMessage(
1181 : "getopt_logic_error: option_info::option_info(): all options must at least have a long name (short name: 'v'.)"));
1182 :
1183 1 : CATCH_REQUIRE_THROWS_MATCHES(
1184 : advgetopt::option_info(std::string())
1185 : , advgetopt::getopt_logic_error
1186 : , Catch::Matchers::ExceptionMessage(
1187 : "getopt_logic_error: option_info::option_info(): all options must at least have a long name."));
1188 :
1189 1 : CATCH_REQUIRE_THROWS_MATCHES(
1190 : advgetopt::option_info(std::string(), 'p')
1191 : , advgetopt::getopt_logic_error
1192 : , Catch::Matchers::ExceptionMessage(
1193 : "getopt_logic_error: option_info::option_info(): all options must at least have a long name (short name: 'p'.)"));
1194 : CATCH_END_SECTION()
1195 :
1196 32 : CATCH_START_SECTION("Default with short name")
1197 1 : CATCH_REQUIRE_THROWS_MATCHES(
1198 : advgetopt::option_info("--", 'f')
1199 : , advgetopt::getopt_logic_error
1200 : , Catch::Matchers::ExceptionMessage(
1201 : "getopt_logic_error: option_info::option_info(): the default parameter \"--\" cannot include a short name ('f'.)"));
1202 : CATCH_END_SECTION()
1203 :
1204 32 : CATCH_START_SECTION("Long name cannot start with a dash (-)")
1205 1 : CATCH_REQUIRE_THROWS_MATCHES(
1206 : advgetopt::option_info("--dashes")
1207 : , advgetopt::getopt_logic_error
1208 : , Catch::Matchers::ExceptionMessage(
1209 : "getopt_logic_error: option_info::option_info(): an option cannot start with a dash (-), \"--dashes\" is not valid."));
1210 : CATCH_END_SECTION()
1211 :
1212 32 : CATCH_START_SECTION("Short name cannot be a dash (-)")
1213 1 : CATCH_REQUIRE_THROWS_MATCHES(
1214 : advgetopt::option_info("dash", '-')
1215 : , advgetopt::getopt_logic_error
1216 : , Catch::Matchers::ExceptionMessage(
1217 : "getopt_logic_error: option_info::option_info(): the short name of an option cannot be the dash (-)."));
1218 : CATCH_END_SECTION()
1219 :
1220 32 : CATCH_START_SECTION("Set value with undefined source")
1221 2 : advgetopt::option_info verbose("verbose", 'v');
1222 1 : CATCH_REQUIRE_THROWS_MATCHES(
1223 : verbose.set_value(0, "true", advgetopt::option_source_t::SOURCE_UNDEFINED)
1224 : , advgetopt::getopt_logic_error
1225 : , Catch::Matchers::ExceptionMessage(
1226 : "getopt_logic_error: option_info::set_value(): called with SOURCE_UNDEFINED (5)."));
1227 : CATCH_END_SECTION()
1228 :
1229 32 : CATCH_START_SECTION("Set multiple values with undefined source")
1230 2 : advgetopt::option_info verbose("verbose", 'v');
1231 1 : CATCH_REQUIRE_THROWS_MATCHES(
1232 : verbose.set_multiple_values("a,b,c", advgetopt::option_source_t::SOURCE_UNDEFINED)
1233 : , advgetopt::getopt_logic_error
1234 : , Catch::Matchers::ExceptionMessage(
1235 : "getopt_logic_error: option_info::set_multiple_values(): called with SOURCE_UNDEFINED (5)."));
1236 : CATCH_END_SECTION()
1237 :
1238 32 : CATCH_START_SECTION("Get value when undefined")
1239 2 : advgetopt::option_info verbose("verbose", 'v');
1240 1 : CATCH_REQUIRE_THROWS_MATCHES(
1241 : verbose.get_value()
1242 : , advgetopt::getopt_undefined
1243 : , Catch::Matchers::ExceptionMessage(
1244 : "getopt_exception: option_info::get_value(): no value at index 0 (idx >= 0) for --verbose so you can't get this value."));
1245 : CATCH_END_SECTION()
1246 :
1247 32 : CATCH_START_SECTION("Get long when undefined")
1248 2 : advgetopt::option_info verbose("verbose", 'v');
1249 1 : CATCH_REQUIRE_THROWS_MATCHES(
1250 : verbose.get_long()
1251 : , advgetopt::getopt_undefined
1252 : , Catch::Matchers::ExceptionMessage(
1253 : "getopt_exception: option_info::get_long(): no value at index 0 (idx >= 0) for --verbose so you can't get this value."));
1254 : CATCH_END_SECTION()
1255 :
1256 32 : CATCH_START_SECTION("Check alias of alias")
1257 2 : advgetopt::option_info::pointer_t option(std::make_shared<advgetopt::option_info>("option", 'o'));
1258 2 : advgetopt::option_info alias("alias", 'a');
1259 :
1260 1 : option->add_flag(advgetopt::GETOPT_FLAG_ALIAS);
1261 :
1262 1 : CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
1263 :
1264 1 : CATCH_REQUIRE_THROWS_MATCHES(
1265 : alias.set_alias_destination(option)
1266 : , advgetopt::getopt_invalid
1267 : , Catch::Matchers::ExceptionMessage(
1268 : "getopt_exception: option_info::set_alias(): you can't set an alias as"
1269 : " an alias of another option."));
1270 :
1271 1 : CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
1272 : CATCH_END_SECTION()
1273 :
1274 32 : CATCH_START_SECTION("Set value, verify multiple strings (with MULTIPLE)")
1275 2 : advgetopt::option_info multi_value("names", 'n');
1276 :
1277 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
1278 :
1279 1 : CATCH_REQUIRE(multi_value.size() == 0);
1280 :
1281 1 : multi_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1282 1 : CATCH_REQUIRE(multi_value.size() == 1);
1283 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
1284 1 : CATCH_REQUIRE(multi_value.source() == advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1285 :
1286 1 : CATCH_REQUIRE_THROWS_MATCHES(
1287 : multi_value.set_value(2, "value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE)
1288 : , advgetopt::getopt_logic_error
1289 : , Catch::Matchers::ExceptionMessage(
1290 : "getopt_logic_error: option_info::set_value(): no value at index 2 and it is not the last available index + 1 (idx > 1) so you can't set this value (try add_value() maybe?)."));
1291 :
1292 1 : CATCH_REQUIRE(multi_value.size() == 1);
1293 1 : CATCH_REQUIRE(multi_value.get_value(0) == "value one");
1294 : CATCH_END_SECTION()
1295 :
1296 32 : CATCH_START_SECTION("Set value, verify multiple integers (with MULTIPLE)")
1297 2 : advgetopt::option_info multi_value("names", 'n');
1298 :
1299 1 : multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
1300 :
1301 1 : CATCH_REQUIRE(multi_value.size() == 0);
1302 :
1303 1 : multi_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1304 1 : CATCH_REQUIRE(multi_value.size() == 1);
1305 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
1306 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
1307 :
1308 1 : CATCH_REQUIRE_THROWS_MATCHES(
1309 : multi_value.set_value(2, "456", advgetopt::option_source_t::SOURCE_COMMAND_LINE)
1310 : , advgetopt::getopt_logic_error
1311 : , Catch::Matchers::ExceptionMessage(
1312 : "getopt_logic_error: option_info::set_value(): no value at index 2 and it is not the last available index + 1 (idx > 1) so you can't set this value (try add_value() maybe?)."));
1313 :
1314 1 : CATCH_REQUIRE(multi_value.size() == 1);
1315 1 : CATCH_REQUIRE(multi_value.get_value(0) == "123");
1316 1 : CATCH_REQUIRE(multi_value.get_long(0) == 123);
1317 : CATCH_END_SECTION()
1318 :
1319 32 : CATCH_START_SECTION("Set value, verify multiple strings (without MULTIPLE)")
1320 2 : advgetopt::option_info one_value("names", 'n');
1321 :
1322 1 : CATCH_REQUIRE(one_value.size() == 0);
1323 :
1324 1 : one_value.set_value(0, "value one", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1325 1 : CATCH_REQUIRE(one_value.size() == 1);
1326 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
1327 :
1328 1 : CATCH_REQUIRE_THROWS_MATCHES(
1329 : one_value.set_value(1, "value two", advgetopt::option_source_t::SOURCE_COMMAND_LINE)
1330 : , advgetopt::getopt_logic_error
1331 : , Catch::Matchers::ExceptionMessage(
1332 : "getopt_logic_error: option_info::set_value(): single value option \"--names\" does not accepts index 1 which is not 0."));
1333 :
1334 1 : CATCH_REQUIRE(one_value.size() == 1);
1335 1 : CATCH_REQUIRE(one_value.get_value(0) == "value one");
1336 : CATCH_END_SECTION()
1337 :
1338 32 : CATCH_START_SECTION("Set value, verify multiple integers (without MULTIPLE)")
1339 2 : advgetopt::option_info one_value("names", 'n');
1340 :
1341 1 : CATCH_REQUIRE(one_value.size() == 0);
1342 :
1343 1 : one_value.set_value(0, "123", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1344 1 : CATCH_REQUIRE(one_value.size() == 1);
1345 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
1346 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
1347 :
1348 1 : CATCH_REQUIRE_THROWS_MATCHES(
1349 : one_value.set_value(1, "456", advgetopt::option_source_t::SOURCE_COMMAND_LINE)
1350 : , advgetopt::getopt_logic_error
1351 : , Catch::Matchers::ExceptionMessage(
1352 : "getopt_logic_error: option_info::set_value(): single value option \"--names\" does not accepts index 1 which is not 0."));
1353 :
1354 1 : CATCH_REQUIRE(one_value.size() == 1);
1355 1 : CATCH_REQUIRE(one_value.get_value(0) == "123");
1356 1 : CATCH_REQUIRE(one_value.get_long(0) == 123);
1357 : CATCH_END_SECTION()
1358 :
1359 32 : CATCH_START_SECTION("Long number too large")
1360 2 : advgetopt::option_info size("size", 's');
1361 :
1362 1 : CATCH_REQUIRE(size.size() == 0);
1363 :
1364 : // really too large
1365 : //
1366 1 : size.set_value(0, "100000000000000000000", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1367 1 : CATCH_REQUIRE(size.size() == 1);
1368 1 : CATCH_REQUIRE(size.get_value(0) == "100000000000000000000");
1369 :
1370 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (100000000000000000000) in parameter --size at offset 0.");
1371 1 : CATCH_REQUIRE(size.get_long(0) == -1);
1372 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1373 :
1374 : // too large by 1
1375 : //
1376 1 : size.set_value(0, "9223372036854775808", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1377 1 : CATCH_REQUIRE(size.size() == 1);
1378 1 : CATCH_REQUIRE(size.get_value(0) == "9223372036854775808");
1379 :
1380 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (9223372036854775808) in parameter --size at offset 0.");
1381 1 : CATCH_REQUIRE(size.get_long(0) == -1);
1382 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1383 :
1384 : // too small by 1
1385 : //
1386 1 : size.set_value(0, "-9223372036854775809", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1387 1 : CATCH_REQUIRE(size.size() == 1);
1388 1 : CATCH_REQUIRE(size.get_value(0) == "-9223372036854775809");
1389 :
1390 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (-9223372036854775809) in parameter --size at offset 0.");
1391 1 : CATCH_REQUIRE(size.get_long(0) == -1);
1392 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1393 :
1394 : // not a valid number
1395 : //
1396 1 : size.set_value(0, "97 potatoes", advgetopt::option_source_t::SOURCE_COMMAND_LINE);
1397 1 : CATCH_REQUIRE(size.size() == 1);
1398 1 : CATCH_REQUIRE(size.get_value(0) == "97 potatoes");
1399 :
1400 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (97 potatoes) in parameter --size at offset 0.");
1401 1 : CATCH_REQUIRE(size.get_long(0) == -1);
1402 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1403 : CATCH_END_SECTION()
1404 :
1405 32 : CATCH_START_SECTION("Check multiple separators")
1406 2 : advgetopt::option_info separators("names", 'n');
1407 :
1408 1 : advgetopt::string_list_t list{
1409 : ",",
1410 : ";",
1411 : " ",
1412 : "^"
1413 2 : };
1414 1 : separators.set_multiple_separators(list);
1415 :
1416 1 : CATCH_REQUIRE_THROWS_MATCHES(
1417 : separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::option_source_t::SOURCE_COMMAND_LINE)
1418 : , advgetopt::getopt_logic_error
1419 : , Catch::Matchers::ExceptionMessage(
1420 : "getopt_logic_error: option_info::set_multiple_value(): parameter --names expects zero or one parameter."
1421 : " The set_multiple_value() function should not be called with parameters that only accept one value."));
1422 :
1423 1 : CATCH_REQUIRE(separators.size() == 0);
1424 : CATCH_END_SECTION()
1425 :
1426 32 : CATCH_START_SECTION("Check multiple separators")
1427 2 : advgetopt::option_info auto_validate("validator", 'C');
1428 1 : CATCH_REQUIRE_THROWS_MATCHES(
1429 : auto_validate.set_validator("regex('^[a-z]+$/'")
1430 : , advgetopt::getopt_logic_error
1431 : , Catch::Matchers::ExceptionMessage(
1432 : "getopt_logic_error: invalid validator parameter definition: \"regex('^[a-z]+$/'\", the ')' is missing."));
1433 : CATCH_END_SECTION()
1434 16 : }
1435 :
1436 :
1437 :
1438 :
1439 4 : CATCH_TEST_CASE("check_invalid_config_dir_short_names", "[arguments][invalid][getopt][config]")
1440 : {
1441 4 : CATCH_START_SECTION("Trying to set NO_SHORT_NAME as '--config-dir' short name (option_info)")
1442 : {
1443 1 : advgetopt::option const options[] =
1444 : {
1445 : advgetopt::define_option(
1446 : advgetopt::Name("print")
1447 : , advgetopt::ShortName(U'p')
1448 : , advgetopt::Flags(advgetopt::command_flags<>())
1449 : , advgetopt::Help("output filename.")
1450 : ),
1451 : advgetopt::end_options()
1452 : };
1453 :
1454 1 : advgetopt::options_environment environment_options;
1455 1 : environment_options.f_project_name = "unittest";
1456 1 : environment_options.f_options = options;
1457 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1458 1 : environment_options.f_environment_variable_name = "ADVGETOPT_TEST_OPTIONS";
1459 1 : environment_options.f_configuration_filename = "snapwatchdog.conf";
1460 1 : environment_options.f_help_header = "Usage: test --config-dir";
1461 :
1462 2 : advgetopt::getopt opt(environment_options);
1463 :
1464 2 : advgetopt::option_info::pointer_t o(opt.get_option("config-dir"));
1465 1 : CATCH_REQUIRE(o != nullptr);
1466 1 : CATCH_REQUIRE(o->get_short_name() == advgetopt::NO_SHORT_NAME);
1467 :
1468 1 : opt.set_short_name("config-dir", advgetopt::NO_SHORT_NAME);
1469 1 : CATCH_REQUIRE(o->get_short_name() == advgetopt::NO_SHORT_NAME);
1470 : }
1471 : CATCH_END_SECTION()
1472 :
1473 4 : CATCH_START_SECTION("Trying to change short name of '--version' (option_info)")
1474 : {
1475 1 : advgetopt::option const options[] =
1476 : {
1477 : advgetopt::define_option(
1478 : advgetopt::Name("print")
1479 : , advgetopt::ShortName('p')
1480 : , advgetopt::Flags(advgetopt::command_flags<>())
1481 : , advgetopt::Help("print all info.")
1482 : ),
1483 : advgetopt::end_options()
1484 : };
1485 :
1486 1 : advgetopt::options_environment environment_options;
1487 1 : environment_options.f_project_name = "unittest";
1488 1 : environment_options.f_options = options;
1489 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1490 1 : environment_options.f_configuration_filename = "";
1491 1 : environment_options.f_help_header = "Usage: test --config-dir";
1492 :
1493 2 : advgetopt::getopt opt(environment_options);
1494 :
1495 2 : advgetopt::option_info::pointer_t o(opt.get_option("version"));
1496 1 : CATCH_REQUIRE(o != nullptr);
1497 1 : CATCH_REQUIRE(o->get_short_name() == U'V');
1498 1 : CATCH_REQUIRE(o == opt.get_option(U'V'));
1499 1 : CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
1500 :
1501 1 : opt.set_short_name("version", U'V'); // keep uppercase...
1502 1 : CATCH_REQUIRE(o->get_short_name() == U'V');
1503 1 : CATCH_REQUIRE(o == opt.get_option(U'V'));
1504 1 : CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
1505 :
1506 1 : opt.set_short_name("version", U'v'); // set to lowercase...
1507 1 : CATCH_REQUIRE(o->get_short_name() == U'v');
1508 1 : CATCH_REQUIRE(o == opt.get_option(U'v'));
1509 1 : CATCH_REQUIRE(opt.get_option(U'V') == nullptr);
1510 :
1511 1 : opt.set_short_name("version", advgetopt::NO_SHORT_NAME); // remove completely...
1512 1 : CATCH_REQUIRE(o->get_short_name() ==advgetopt::NO_SHORT_NAME);
1513 1 : CATCH_REQUIRE(opt.get_option(U'V') == nullptr);
1514 1 : CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
1515 : }
1516 : CATCH_END_SECTION()
1517 2 : }
1518 :
1519 :
1520 :
1521 :
1522 3 : CATCH_TEST_CASE("check_option_callbacks", "[arguments][getopt][config][callback]")
1523 : {
1524 2 : CATCH_START_SECTION("Check option callbacks")
1525 : {
1526 1 : advgetopt::option const options[] =
1527 : {
1528 : advgetopt::define_option(
1529 : advgetopt::Name("print")
1530 : , advgetopt::ShortName(U'p')
1531 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
1532 : , advgetopt::Help("output filename.")
1533 : ),
1534 : advgetopt::end_options()
1535 : };
1536 :
1537 1 : advgetopt::options_environment environment_options;
1538 1 : environment_options.f_project_name = "unittest";
1539 1 : environment_options.f_options = options;
1540 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1541 1 : environment_options.f_configuration_filename = "snapwatchdog.conf";
1542 1 : environment_options.f_help_header = "Usage: test --config-dir";
1543 :
1544 2 : advgetopt::getopt opt(environment_options);
1545 :
1546 4 : struct print_expected
1547 : {
1548 : public:
1549 8 : void set_value(std::string const & value)
1550 : {
1551 8 : f_value = value;
1552 8 : }
1553 :
1554 6 : std::string const & value() const
1555 : {
1556 6 : return f_value;
1557 : }
1558 :
1559 : private:
1560 : std::string f_value = std::string();
1561 : };
1562 :
1563 : struct print_callback
1564 : {
1565 : public:
1566 2 : print_callback(print_expected * expected)
1567 2 : : f_expected(expected)
1568 : {
1569 2 : }
1570 :
1571 6 : void operator() (advgetopt::option_info const & opt)
1572 : {
1573 6 : CATCH_REQUIRE(f_expected->value() == opt.get_value());
1574 6 : }
1575 :
1576 : private:
1577 : print_expected * f_expected = nullptr;
1578 : };
1579 :
1580 2 : print_expected expected1;
1581 1 : print_callback cb1(&expected1);
1582 :
1583 2 : advgetopt::option_info::pointer_t print(opt.get_option("print"));
1584 1 : CATCH_REQUIRE(print != nullptr);
1585 1 : advgetopt::option_info::callback_id_t const id1(print->add_callback(cb1));
1586 :
1587 1 : expected1.set_value("color");
1588 1 : print->set_value(0, "color");
1589 :
1590 : // test with a second callback, both are hit
1591 : //
1592 2 : print_expected expected2;
1593 1 : print_callback cb2(&expected2);
1594 1 : advgetopt::option_info::callback_id_t const id2(print->add_callback(cb2));
1595 :
1596 1 : expected1.set_value("black & white");
1597 1 : expected2.set_value("black & white");
1598 1 : print->set_value(0, "black & white");
1599 :
1600 : // call the remove without a valid identifier so a change still
1601 : // applies
1602 : //
1603 1 : print->remove_callback(id2 + 10);
1604 :
1605 1 : expected1.set_value("stipple");
1606 1 : expected2.set_value("stipple");
1607 1 : print->set_value(0, "stipple");
1608 :
1609 : // remove the first callback and try again
1610 : //
1611 1 : print->remove_callback(id1);
1612 :
1613 1 : expected1.set_value("ignored"); // this was removed
1614 1 : expected2.set_value("dithering");
1615 1 : print->set_value(0, "dithering");
1616 :
1617 : // remove the second callback and try again
1618 : //
1619 1 : print->remove_callback(id2);
1620 :
1621 1 : expected2.set_value("not called anymore either");
1622 1 : print->set_value(0, "cmyk");
1623 : }
1624 : CATCH_END_SECTION()
1625 7 : }
1626 :
1627 :
1628 :
1629 :
1630 :
1631 : // vim: ts=4 sw=4 et
|