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