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