Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // advgetopt
21 : //
22 : #include <advgetopt/exception.h>
23 :
24 :
25 : // self
26 : //
27 : #include "catch_main.h"
28 :
29 :
30 : // libutf8
31 : //
32 : #include <libutf8/libutf8.h>
33 :
34 :
35 : // C++
36 : //
37 : #include <fstream>
38 :
39 :
40 : // last include
41 : //
42 : #include <snapdev/poison.h>
43 :
44 :
45 :
46 :
47 :
48 29 : CATCH_TEST_CASE("option_info_ref", "[option_info][valid][reference]")
49 : {
50 54 : CATCH_START_SECTION("Option info reference")
51 : {
52 1 : advgetopt::option const options[] =
53 : {
54 : advgetopt::define_option(
55 : advgetopt::Name("reference")
56 : , advgetopt::ShortName('r')
57 : , advgetopt::Flags(advgetopt::command_flags<
58 : advgetopt::GETOPT_FLAG_REQUIRED
59 : | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
60 : , advgetopt::Help("test reference.")
61 : ),
62 : advgetopt::define_option(
63 : advgetopt::Name("verbose")
64 : , advgetopt::ShortName('v')
65 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
66 : , advgetopt::Help("make it all verbose.")
67 : ),
68 : advgetopt::end_options()
69 : };
70 :
71 1 : advgetopt::options_environment environment_options;
72 1 : environment_options.f_project_name = "unittest";
73 1 : environment_options.f_options = options;
74 1 : environment_options.f_help_header = "Usage: verify references";
75 :
76 1 : char const * cargv[] =
77 : {
78 : "/usr/bin/arguments",
79 : "--reference",
80 : "1001",
81 : "--verbose",
82 : "loud",
83 : nullptr
84 : };
85 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
86 1 : char ** argv = const_cast<char **>(cargv);
87 :
88 2 : advgetopt::getopt opt(environment_options, argc, argv);
89 :
90 : // check that the result is valid
91 :
92 : // verify both parameters the "normal" way
93 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
94 1 : CATCH_REQUIRE(opt.size("reference") == 1);
95 1 : CATCH_REQUIRE(opt.get_string("reference") == "1001");
96 :
97 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
98 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
99 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
100 :
101 : // check the read-only verbose which does not create a reference
102 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "1001");
103 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
104 :
105 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
106 1 : CATCH_REQUIRE(reference_value == "1001");
107 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
108 1 : CATCH_REQUIRE(verbose_value == "loud");
109 :
110 : // get a reference
111 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
112 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
113 :
114 1 : CATCH_REQUIRE_FALSE(reference_ref.empty());
115 1 : CATCH_REQUIRE_FALSE(verbose_ref.empty());
116 :
117 1 : CATCH_REQUIRE(reference_ref.length() == 4);
118 1 : CATCH_REQUIRE(reference_ref.size() == 4);
119 1 : CATCH_REQUIRE(verbose_ref.length() == 4);
120 1 : CATCH_REQUIRE(verbose_ref.size() == 4);
121 :
122 1 : CATCH_REQUIRE(reference_ref == reference_ref);
123 1 : CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
124 1 : CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
125 1 : CATCH_REQUIRE(reference_ref <= reference_ref);
126 1 : CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
127 1 : CATCH_REQUIRE(reference_ref >= reference_ref);
128 :
129 1 : CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
130 1 : CATCH_REQUIRE(reference_ref != verbose_ref);
131 1 : CATCH_REQUIRE(reference_ref < verbose_ref);
132 1 : CATCH_REQUIRE(reference_ref <= verbose_ref);
133 1 : CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
134 1 : CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
135 :
136 1 : reference_ref += "3";
137 1 : CATCH_REQUIRE(reference_ref == "10013");
138 1 : CATCH_REQUIRE("10013" == reference_ref);
139 1 : CATCH_REQUIRE(reference_ref != "17013");
140 1 : CATCH_REQUIRE("10413" != reference_ref);
141 1 : CATCH_REQUIRE(reference_ref < "20");
142 1 : CATCH_REQUIRE("1001" < reference_ref);
143 1 : CATCH_REQUIRE(reference_ref <= "10013");
144 1 : CATCH_REQUIRE("10013" <= reference_ref);
145 1 : CATCH_REQUIRE(reference_ref > "%");
146 1 : CATCH_REQUIRE("10014" > reference_ref);
147 1 : CATCH_REQUIRE(reference_ref >= "!");
148 1 : CATCH_REQUIRE("10013" >= reference_ref);
149 :
150 2 : std::string const new_value("zero");
151 1 : reference_ref = new_value;
152 1 : CATCH_REQUIRE(reference_ref == reference_ref);
153 1 : CATCH_REQUIRE(reference_ref == new_value);
154 1 : CATCH_REQUIRE(new_value == reference_ref);
155 1 : CATCH_REQUIRE_FALSE(reference_ref != new_value);
156 1 : CATCH_REQUIRE_FALSE(new_value != reference_ref);
157 1 : CATCH_REQUIRE_FALSE(reference_ref < new_value);
158 1 : CATCH_REQUIRE_FALSE(new_value < reference_ref);
159 1 : CATCH_REQUIRE(reference_ref <= new_value);
160 1 : CATCH_REQUIRE(new_value <= reference_ref);
161 1 : CATCH_REQUIRE_FALSE(reference_ref > new_value);
162 1 : CATCH_REQUIRE_FALSE(new_value > reference_ref);
163 1 : CATCH_REQUIRE(reference_ref >= new_value);
164 1 : CATCH_REQUIRE(new_value >= reference_ref);
165 :
166 1 : reference_ref += verbose_ref;
167 1 : CATCH_REQUIRE(reference_ref == reference_ref);
168 1 : CATCH_REQUIRE(reference_ref == "zeroloud");
169 1 : CATCH_REQUIRE("zeroloud" == reference_ref);
170 1 : CATCH_REQUIRE_FALSE(reference_ref != "zeroloud");
171 1 : CATCH_REQUIRE_FALSE("zeroloud" != reference_ref);
172 1 : CATCH_REQUIRE_FALSE(reference_ref < "zeroloud");
173 1 : CATCH_REQUIRE_FALSE("zeroloud" < reference_ref);
174 1 : CATCH_REQUIRE(reference_ref <= "zeroloud");
175 1 : CATCH_REQUIRE("zeroloud" <= reference_ref);
176 1 : CATCH_REQUIRE_FALSE(reference_ref > "zeroloud");
177 1 : CATCH_REQUIRE_FALSE("zeroloud" > reference_ref);
178 1 : CATCH_REQUIRE(reference_ref >= "zeroloud");
179 1 : CATCH_REQUIRE("zeroloud" >= reference_ref);
180 :
181 1 : reference_ref += '?';
182 1 : CATCH_REQUIRE(reference_ref == reference_ref);
183 1 : CATCH_REQUIRE(reference_ref == "zeroloud?");
184 1 : CATCH_REQUIRE("zeroloud?" == reference_ref);
185 1 : CATCH_REQUIRE_FALSE(reference_ref != "zeroloud?");
186 1 : CATCH_REQUIRE_FALSE("zeroloud?" != reference_ref);
187 1 : CATCH_REQUIRE_FALSE(reference_ref < "zeroloud?");
188 1 : CATCH_REQUIRE_FALSE("zeroloud?" < reference_ref);
189 1 : CATCH_REQUIRE(reference_ref <= "zeroloud?");
190 1 : CATCH_REQUIRE("zeroloud?" <= reference_ref);
191 1 : CATCH_REQUIRE_FALSE(reference_ref > "zeroloud?");
192 1 : CATCH_REQUIRE_FALSE("zeroloud?" > reference_ref);
193 1 : CATCH_REQUIRE(reference_ref >= "zeroloud?");
194 1 : CATCH_REQUIRE("zeroloud?" >= reference_ref);
195 :
196 1 : CATCH_REQUIRE_FALSE(reference_ref + "more" == reference_ref);
197 1 : CATCH_REQUIRE(reference_ref + "more" == "zeroloud?more");
198 1 : CATCH_REQUIRE("zeroloud?more" == reference_ref + "more");
199 1 : CATCH_REQUIRE(reference_ref + std::string("extra") == "zeroloud?extra");
200 1 : CATCH_REQUIRE("zeroloud?extra" == reference_ref + std::string("extra"));
201 1 : CATCH_REQUIRE(reference_ref + verbose_ref == "zeroloud?loud");
202 1 : CATCH_REQUIRE("zeroloud?loud" == reference_ref + verbose_ref);
203 :
204 1 : CATCH_REQUIRE_FALSE(reference_ref + '+' == reference_ref);
205 1 : CATCH_REQUIRE(reference_ref + '+' == "zeroloud?+");
206 1 : CATCH_REQUIRE("zeroloud?+" == reference_ref + '+');
207 1 : CATCH_REQUIRE('+' + reference_ref == "+zeroloud?");
208 1 : CATCH_REQUIRE("+zeroloud?" == '+' + reference_ref);
209 :
210 1 : CATCH_REQUIRE(reference_ref + '\0' == reference_ref);
211 1 : CATCH_REQUIRE(reference_ref + '\0' == "zeroloud?");
212 1 : CATCH_REQUIRE("zeroloud?" == reference_ref + '\0');
213 1 : CATCH_REQUIRE('\0' + reference_ref == "zeroloud?");
214 1 : CATCH_REQUIRE("zeroloud?" == '\0' + reference_ref);
215 :
216 1 : char32_t c(rand() % 0xFFFFF + ' ');
217 1 : if(c >= 0xD800 && c < 0xE000)
218 : {
219 0 : c += 0x800;
220 : }
221 :
222 1 : CATCH_REQUIRE_FALSE(reference_ref + c == reference_ref);
223 1 : CATCH_REQUIRE(reference_ref + c == "zeroloud?" + libutf8::to_u8string(c));
224 1 : CATCH_REQUIRE("zeroloud?" + libutf8::to_u8string(c) == reference_ref + c);
225 1 : CATCH_REQUIRE(c + reference_ref == libutf8::to_u8string(c) + "zeroloud?");
226 1 : CATCH_REQUIRE(libutf8::to_u8string(c) + "zeroloud?" == c + reference_ref);
227 :
228 1 : c = U'\0';
229 :
230 1 : CATCH_REQUIRE(reference_ref + c == reference_ref);
231 1 : CATCH_REQUIRE(reference_ref + c == "zeroloud?");
232 1 : CATCH_REQUIRE("zeroloud?" == reference_ref + c);
233 1 : CATCH_REQUIRE(c + reference_ref == "zeroloud?");
234 1 : CATCH_REQUIRE("zeroloud?" == c + reference_ref);
235 :
236 1 : reference_ref = "reset";
237 1 : CATCH_REQUIRE('"' + reference_ref + '"' == "\"reset\"");
238 1 : CATCH_REQUIRE('\0' + reference_ref + '\0' == std::string("reset") + '\0'); // we do not control the second + here...
239 1 : CATCH_REQUIRE(c + reference_ref + c == "reset");
240 :
241 1 : reference_ref = verbose_ref;
242 1 : CATCH_REQUIRE('(' + reference_ref + ')' == "(loud)");
243 1 : CATCH_REQUIRE('\0' + reference_ref + '\0' == std::string("loud") + '\0'); // we do not control the second + here...
244 1 : CATCH_REQUIRE(c + reference_ref + c == "loud");
245 :
246 2 : std::string const secret("secret");
247 1 : reference_ref += ' ';
248 1 : reference_ref += secret;
249 1 : CATCH_REQUIRE('>' + reference_ref + '<' == ">loud secret<");
250 1 : char32_t const left(0x1D233);
251 1 : char32_t const right(0x1D234);
252 1 : CATCH_REQUIRE((left + (reference_ref + right)) == "\xF0\x9D\x88\xB3loud secret\xF0\x9D\x88\xB4");
253 1 : CATCH_REQUIRE(((left + reference_ref) + right) == "\xF0\x9D\x88\xB3loud secret\xF0\x9D\x88\xB4");
254 1 : CATCH_REQUIRE(c == U'\0');
255 1 : CATCH_REQUIRE((c + (reference_ref + c)) == "loud secret");
256 1 : CATCH_REQUIRE(((c + reference_ref) + c) == "loud secret");
257 1 : CATCH_REQUIRE(reference_ref + new_value == "loud secretzero");
258 1 : CATCH_REQUIRE(new_value + reference_ref == "zeroloud secret");
259 1 : CATCH_REQUIRE(reference_ref + " more" == "loud secret more");
260 1 : CATCH_REQUIRE("less " + reference_ref == "less loud secret");
261 :
262 1 : reference_ref = '#';
263 1 : CATCH_REQUIRE(reference_ref == "#");
264 1 : reference_ref += '\0';
265 1 : CATCH_REQUIRE(reference_ref == "#");
266 1 : reference_ref += c;
267 1 : CATCH_REQUIRE(reference_ref == "#");
268 :
269 1 : reference_ref = '\0';
270 1 : CATCH_REQUIRE(reference_ref == "");
271 :
272 1 : reference_ref = '?';
273 1 : CATCH_REQUIRE(reference_ref == "?");
274 1 : reference_ref += '\0';
275 1 : CATCH_REQUIRE(reference_ref == "?");
276 1 : reference_ref += c;
277 1 : CATCH_REQUIRE(reference_ref == "?");
278 :
279 1 : reference_ref = c;
280 1 : CATCH_REQUIRE(reference_ref == "");
281 : }
282 : CATCH_END_SECTION()
283 :
284 54 : CATCH_START_SECTION("Non-existant reference")
285 : {
286 1 : advgetopt::option const options[] =
287 : {
288 : advgetopt::define_option(
289 : advgetopt::Name("reference")
290 : , advgetopt::ShortName('r')
291 : , advgetopt::Flags(advgetopt::command_flags<
292 : advgetopt::GETOPT_FLAG_REQUIRED
293 : | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
294 : , advgetopt::Help("test reference.")
295 : ),
296 : advgetopt::define_option(
297 : advgetopt::Name("verbose")
298 : , advgetopt::ShortName('v')
299 : , advgetopt::Flags(advgetopt::command_flags<
300 : advgetopt::GETOPT_FLAG_REQUIRED
301 : | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
302 : , advgetopt::Help("make it all verbose.")
303 : ),
304 : advgetopt::end_options()
305 : };
306 :
307 1 : advgetopt::options_environment environment_options;
308 1 : environment_options.f_project_name = "unittest";
309 1 : environment_options.f_options = options;
310 1 : environment_options.f_help_header = "Usage: verify references";
311 :
312 1 : char const * cargv[] =
313 : {
314 : "/usr/bin/arguments",
315 : "--reference",
316 : "1001",
317 : "--verbose",
318 : "loud",
319 : nullptr
320 : };
321 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
322 1 : char ** argv = const_cast<char **>(cargv);
323 :
324 2 : advgetopt::getopt opt(environment_options, argc, argv);
325 :
326 : // check that the result is valid
327 :
328 : // verify both parameters the "normal" way
329 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
330 1 : CATCH_REQUIRE(opt.size("reference") == 1);
331 1 : CATCH_REQUIRE(opt.get_string("reference") == "1001");
332 :
333 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
334 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
335 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
336 :
337 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
338 :
339 : // check the read-only verbose which does not create a reference
340 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "1001");
341 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
342 :
343 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
344 1 : CATCH_REQUIRE(reference_value == "1001");
345 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
346 1 : CATCH_REQUIRE(verbose_value == "loud");
347 :
348 : // get references
349 2 : advgetopt::option_info_ref unknown_ref(opt["unknown"]);
350 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
351 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
352 :
353 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
354 :
355 1 : char const * null_string(nullptr);
356 :
357 1 : CATCH_REQUIRE(unknown_ref.empty());
358 1 : CATCH_REQUIRE(unknown_ref.length() == 0);
359 1 : CATCH_REQUIRE(unknown_ref.size() == 0);
360 1 : CATCH_REQUIRE(unknown_ref.get_long() == 0);
361 : #pragma GCC diagnostic push
362 : #pragma GCC diagnostic ignored "-Wfloat-equal"
363 : {
364 1 : bool const a1(unknown_ref.get_double() == 0.0);
365 1 : CATCH_REQUIRE(a1);
366 : }
367 : #pragma GCC diagnostic pop
368 1 : CATCH_REQUIRE(static_cast<std::string>(unknown_ref) == "");
369 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
370 :
371 1 : CATCH_REQUIRE_FALSE(static_cast<bool>(unknown_ref));
372 1 : CATCH_REQUIRE(!unknown_ref);
373 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
374 :
375 1 : CATCH_REQUIRE(unknown_ref == nullptr);
376 1 : CATCH_REQUIRE(unknown_ref == "");
377 1 : CATCH_REQUIRE(unknown_ref == std::string());
378 1 : CATCH_REQUIRE_FALSE(unknown_ref == std::string("test"));
379 1 : CATCH_REQUIRE(nullptr == unknown_ref);
380 1 : CATCH_REQUIRE("" == unknown_ref);
381 1 : CATCH_REQUIRE(std::string() == unknown_ref);
382 1 : CATCH_REQUIRE_FALSE(std::string("test") == unknown_ref);
383 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
384 :
385 1 : CATCH_REQUIRE_FALSE(unknown_ref != nullptr);
386 1 : CATCH_REQUIRE_FALSE(unknown_ref != "");
387 1 : CATCH_REQUIRE_FALSE(unknown_ref != std::string());
388 1 : CATCH_REQUIRE(unknown_ref != std::string("test"));
389 1 : CATCH_REQUIRE_FALSE(nullptr != unknown_ref);
390 1 : CATCH_REQUIRE_FALSE("" != unknown_ref);
391 1 : CATCH_REQUIRE_FALSE(std::string() != unknown_ref);
392 1 : CATCH_REQUIRE(std::string("test") != unknown_ref);
393 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
394 :
395 1 : CATCH_REQUIRE_FALSE(unknown_ref < nullptr);
396 1 : CATCH_REQUIRE_FALSE(unknown_ref < "");
397 1 : CATCH_REQUIRE_FALSE(unknown_ref < std::string());
398 1 : CATCH_REQUIRE(unknown_ref < std::string("test"));
399 1 : CATCH_REQUIRE_FALSE(nullptr < unknown_ref);
400 1 : CATCH_REQUIRE_FALSE("" < unknown_ref);
401 1 : CATCH_REQUIRE_FALSE(std::string() < unknown_ref);
402 1 : CATCH_REQUIRE_FALSE(std::string("test") < unknown_ref);
403 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
404 :
405 1 : CATCH_REQUIRE(unknown_ref <= nullptr);
406 1 : CATCH_REQUIRE(unknown_ref <= "");
407 1 : CATCH_REQUIRE(unknown_ref <= std::string());
408 1 : CATCH_REQUIRE(unknown_ref <= std::string("test"));
409 1 : CATCH_REQUIRE(nullptr <= unknown_ref);
410 1 : CATCH_REQUIRE("" <= unknown_ref);
411 1 : CATCH_REQUIRE(std::string() <= unknown_ref);
412 1 : CATCH_REQUIRE_FALSE(std::string("test") <= unknown_ref);
413 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
414 :
415 1 : CATCH_REQUIRE_FALSE(unknown_ref > nullptr);
416 1 : CATCH_REQUIRE_FALSE(unknown_ref > "");
417 1 : CATCH_REQUIRE_FALSE(unknown_ref > std::string());
418 1 : CATCH_REQUIRE_FALSE(unknown_ref > std::string("test"));
419 1 : CATCH_REQUIRE_FALSE(nullptr > unknown_ref);
420 1 : CATCH_REQUIRE_FALSE("" > unknown_ref);
421 1 : CATCH_REQUIRE_FALSE(std::string() > unknown_ref);
422 1 : CATCH_REQUIRE(std::string("test") > unknown_ref);
423 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
424 :
425 1 : CATCH_REQUIRE(unknown_ref >= nullptr);
426 1 : CATCH_REQUIRE(unknown_ref >= "");
427 1 : CATCH_REQUIRE(unknown_ref >= std::string());
428 1 : CATCH_REQUIRE_FALSE(unknown_ref >= std::string("test"));
429 1 : CATCH_REQUIRE(nullptr >= unknown_ref);
430 1 : CATCH_REQUIRE("" >= unknown_ref);
431 1 : CATCH_REQUIRE(std::string() >= unknown_ref);
432 1 : CATCH_REQUIRE(std::string("test") >= unknown_ref);
433 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
434 :
435 1 : CATCH_REQUIRE(unknown_ref + '\0' == "");
436 1 : CATCH_REQUIRE(unknown_ref + '<' == "<");
437 1 : CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\0') == "");
438 1 : CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\x2020') == "\xE2\x80\xA0");
439 1 : CATCH_REQUIRE(unknown_ref + null_string == "");
440 1 : CATCH_REQUIRE(unknown_ref + "abc\xE4\x81\x81" == "abc\xE4\x81\x81");
441 1 : CATCH_REQUIRE(unknown_ref + std::string("xyz\xE4\x9E\x99") == "xyz\xE4\x9E\x99");
442 1 : CATCH_REQUIRE(unknown_ref + reference_ref == "1001");
443 1 : CATCH_REQUIRE(unknown_ref + verbose_ref == "loud");
444 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
445 :
446 1 : CATCH_REQUIRE('\0' + unknown_ref == "");
447 1 : CATCH_REQUIRE('<' + unknown_ref == "<");
448 1 : CATCH_REQUIRE(static_cast<char32_t>(U'\0') + unknown_ref == "");
449 1 : CATCH_REQUIRE(static_cast<char32_t>(U'\x2020') + unknown_ref == "\xE2\x80\xA0");
450 1 : CATCH_REQUIRE(null_string + unknown_ref == "");
451 1 : CATCH_REQUIRE("abc\xE4\x81\x81" + unknown_ref == "abc\xE4\x81\x81");
452 1 : CATCH_REQUIRE(std::string("xyz\xE4\x9E\x99") + unknown_ref == "xyz\xE4\x9E\x99");
453 1 : CATCH_REQUIRE(reference_ref + unknown_ref == "1001");
454 1 : CATCH_REQUIRE(verbose_ref + unknown_ref == "loud");
455 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
456 :
457 1 : unknown_ref = static_cast<char32_t>(U'\x4819'); // == '\xE4\xA0\x99'
458 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
459 :
460 1 : CATCH_REQUIRE_FALSE(unknown_ref.empty());
461 1 : CATCH_REQUIRE(unknown_ref.length() == 3); // 3 UTF-8 bytes
462 1 : CATCH_REQUIRE(unknown_ref.size() == 3);
463 :
464 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (\xE4\xA0\x99) in parameter --unknown at offset 0.");
465 1 : CATCH_REQUIRE(unknown_ref.get_long() == -1);
466 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
467 :
468 : #pragma GCC diagnostic push
469 : #pragma GCC diagnostic ignored "-Wfloat-equal"
470 : {
471 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (\xE4\xA0\x99) in parameter --unknown at offset 0.");
472 1 : bool const a2(unknown_ref.get_double() == -1.0);
473 1 : CATCH_REQUIRE(a2);
474 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
475 : }
476 : #pragma GCC diagnostic pop
477 :
478 1 : CATCH_REQUIRE(static_cast<std::string>(unknown_ref) == "\xE4\xA0\x99");
479 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
480 :
481 1 : CATCH_REQUIRE(static_cast<bool>(unknown_ref));
482 1 : CATCH_REQUIRE_FALSE(!unknown_ref);
483 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
484 :
485 1 : CATCH_REQUIRE_FALSE(unknown_ref == nullptr);
486 1 : CATCH_REQUIRE_FALSE(unknown_ref == "");
487 1 : CATCH_REQUIRE(unknown_ref == "\xE4\xA0\x99");
488 1 : CATCH_REQUIRE_FALSE(unknown_ref == std::string());
489 1 : CATCH_REQUIRE_FALSE(unknown_ref == std::string("test"));
490 1 : CATCH_REQUIRE(unknown_ref == std::string("\xE4\xA0\x99"));
491 1 : CATCH_REQUIRE_FALSE(nullptr == unknown_ref);
492 1 : CATCH_REQUIRE_FALSE("" == unknown_ref);
493 1 : CATCH_REQUIRE("\xE4\xA0\x99" == unknown_ref);
494 1 : CATCH_REQUIRE_FALSE(std::string() == unknown_ref);
495 1 : CATCH_REQUIRE_FALSE(std::string("test") == unknown_ref);
496 1 : CATCH_REQUIRE(std::string("\xE4\xA0\x99") == unknown_ref);
497 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
498 :
499 1 : CATCH_REQUIRE(unknown_ref != nullptr);
500 1 : CATCH_REQUIRE(unknown_ref != "");
501 1 : CATCH_REQUIRE_FALSE(unknown_ref != "\xE4\xA0\x99");
502 1 : CATCH_REQUIRE(unknown_ref != std::string());
503 1 : CATCH_REQUIRE(unknown_ref != std::string("test"));
504 1 : CATCH_REQUIRE_FALSE(unknown_ref != std::string("\xE4\xA0\x99"));
505 1 : CATCH_REQUIRE(nullptr != unknown_ref);
506 1 : CATCH_REQUIRE("" != unknown_ref);
507 1 : CATCH_REQUIRE_FALSE("\xE4\xA0\x99" != unknown_ref);
508 1 : CATCH_REQUIRE(std::string() != unknown_ref);
509 1 : CATCH_REQUIRE(std::string("test") != unknown_ref);
510 1 : CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") != unknown_ref);
511 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
512 :
513 1 : CATCH_REQUIRE_FALSE(unknown_ref < nullptr);
514 1 : CATCH_REQUIRE_FALSE(unknown_ref < "");
515 1 : CATCH_REQUIRE_FALSE(unknown_ref < "\xE4\xA0\x99");
516 1 : CATCH_REQUIRE_FALSE(unknown_ref < std::string());
517 1 : CATCH_REQUIRE_FALSE(unknown_ref < std::string("test"));
518 1 : CATCH_REQUIRE_FALSE(unknown_ref < std::string("\xE4\xA0\x99"));
519 1 : CATCH_REQUIRE(nullptr < unknown_ref);
520 1 : CATCH_REQUIRE("" < unknown_ref);
521 1 : CATCH_REQUIRE_FALSE("\xE4\xA0\x99" < unknown_ref);
522 1 : CATCH_REQUIRE(std::string() < unknown_ref);
523 1 : CATCH_REQUIRE(std::string("test") < unknown_ref);
524 1 : CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") < unknown_ref);
525 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
526 :
527 1 : CATCH_REQUIRE_FALSE(unknown_ref <= nullptr);
528 1 : CATCH_REQUIRE_FALSE(unknown_ref <= "");
529 1 : CATCH_REQUIRE(unknown_ref <= "\xE4\xA0\x99");
530 1 : CATCH_REQUIRE_FALSE(unknown_ref <= std::string());
531 1 : CATCH_REQUIRE_FALSE(unknown_ref <= std::string("test"));
532 1 : CATCH_REQUIRE(unknown_ref <= std::string("\xE4\xA0\x99"));
533 1 : CATCH_REQUIRE(nullptr <= unknown_ref);
534 1 : CATCH_REQUIRE("" <= unknown_ref);
535 1 : CATCH_REQUIRE("\xE4\xA0\x99" <= unknown_ref);
536 1 : CATCH_REQUIRE(std::string() <= unknown_ref);
537 1 : CATCH_REQUIRE(std::string("test") <= unknown_ref);
538 1 : CATCH_REQUIRE(std::string("\xE4\xA0\x99") <= unknown_ref);
539 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
540 :
541 1 : CATCH_REQUIRE(unknown_ref > nullptr);
542 1 : CATCH_REQUIRE(unknown_ref > "");
543 1 : CATCH_REQUIRE_FALSE(unknown_ref > "\xE4\xA0\x99");
544 1 : CATCH_REQUIRE(unknown_ref > std::string());
545 1 : CATCH_REQUIRE(unknown_ref > std::string("test"));
546 1 : CATCH_REQUIRE_FALSE(unknown_ref > std::string("\xE4\xA0\x99"));
547 1 : CATCH_REQUIRE_FALSE(nullptr > unknown_ref);
548 1 : CATCH_REQUIRE_FALSE("" > unknown_ref);
549 1 : CATCH_REQUIRE_FALSE("\xE4\xA0\x99" > unknown_ref);
550 1 : CATCH_REQUIRE_FALSE(std::string() > unknown_ref);
551 1 : CATCH_REQUIRE_FALSE(std::string("test") > unknown_ref);
552 1 : CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") > unknown_ref);
553 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
554 :
555 1 : CATCH_REQUIRE(unknown_ref >= nullptr);
556 1 : CATCH_REQUIRE(unknown_ref >= "");
557 1 : CATCH_REQUIRE(unknown_ref >= "\xE4\xA0\x99");
558 1 : CATCH_REQUIRE(unknown_ref >= std::string());
559 1 : CATCH_REQUIRE(unknown_ref >= std::string("test"));
560 1 : CATCH_REQUIRE(unknown_ref >= std::string("\xE4\xA0\x99"));
561 1 : CATCH_REQUIRE_FALSE(nullptr >= unknown_ref);
562 1 : CATCH_REQUIRE_FALSE("" >= unknown_ref);
563 1 : CATCH_REQUIRE_FALSE(std::string() >= unknown_ref);
564 1 : CATCH_REQUIRE_FALSE(std::string("test") >= unknown_ref);
565 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
566 :
567 1 : CATCH_REQUIRE(unknown_ref + '\0' == "\xE4\xA0\x99");
568 1 : CATCH_REQUIRE(unknown_ref + '<' == "\xE4\xA0\x99<");
569 1 : CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\0') == "\xE4\xA0\x99");
570 1 : CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\x2020') == "\xE4\xA0\x99\xE2\x80\xA0");
571 1 : CATCH_REQUIRE(unknown_ref + null_string == "\xE4\xA0\x99");
572 1 : CATCH_REQUIRE(unknown_ref + "abc\xE4\x81\x81" == "\xE4\xA0\x99\x61\x62\x63\xE4\x81\x81");
573 1 : CATCH_REQUIRE(unknown_ref + std::string("xyz\xE4\x9E\x99") == "\xE4\xA0\x99xyz\xE4\x9E\x99");
574 1 : CATCH_REQUIRE(unknown_ref + reference_ref == "\xE4\xA0\x99\x31\x30\x30\x31");
575 1 : CATCH_REQUIRE(unknown_ref + verbose_ref == "\xE4\xA0\x99loud");
576 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
577 :
578 1 : CATCH_REQUIRE('\0' + unknown_ref == "\xE4\xA0\x99");
579 1 : CATCH_REQUIRE('<' + unknown_ref == "<\xE4\xA0\x99");
580 1 : CATCH_REQUIRE(static_cast<char32_t>(U'\0') + unknown_ref == "\xE4\xA0\x99");
581 1 : CATCH_REQUIRE(static_cast<char32_t>(U'\x2020') + unknown_ref == "\xE2\x80\xA0\xE4\xA0\x99");
582 1 : CATCH_REQUIRE(null_string + unknown_ref == "\xE4\xA0\x99");
583 1 : CATCH_REQUIRE("abc\xE4\x81\x81" + unknown_ref == "abc\xE4\x81\x81\xE4\xA0\x99");
584 1 : CATCH_REQUIRE(std::string("xyz\xE4\x9E\x99") + unknown_ref == "xyz\xE4\x9E\x99\xE4\xA0\x99");
585 1 : CATCH_REQUIRE(reference_ref + unknown_ref == "1001\xE4\xA0\x99");
586 1 : CATCH_REQUIRE(verbose_ref + unknown_ref == "loud\xE4\xA0\x99");
587 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
588 : }
589 : CATCH_END_SECTION()
590 :
591 54 : CATCH_START_SECTION("Set non-existant reference + many CATCH_WHEN()")
592 : {
593 25 : advgetopt::option const options[] =
594 : {
595 : advgetopt::define_option(
596 : advgetopt::Name("reference")
597 : , advgetopt::ShortName('r')
598 : , advgetopt::Flags(advgetopt::command_flags<
599 : advgetopt::GETOPT_FLAG_REQUIRED
600 : | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
601 : , advgetopt::Help("test reference.")
602 : , advgetopt::DefaultValue("978")
603 : ),
604 : advgetopt::define_option(
605 : advgetopt::Name("verbose")
606 : , advgetopt::ShortName('v')
607 : , advgetopt::Flags(advgetopt::command_flags<
608 : advgetopt::GETOPT_FLAG_REQUIRED
609 : | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
610 : , advgetopt::Help("make it all verbose.")
611 : ),
612 : advgetopt::end_options()
613 : };
614 :
615 25 : advgetopt::options_environment environment_options;
616 25 : environment_options.f_project_name = "unittest";
617 25 : environment_options.f_options = options;
618 25 : environment_options.f_help_header = "Usage: verify references";
619 :
620 25 : char const * cargv[] =
621 : {
622 : "/usr/bin/arguments",
623 : "--reference",
624 : "3100",
625 : "--verbose",
626 : "silence",
627 : nullptr
628 : };
629 25 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
630 25 : char ** argv = const_cast<char **>(cargv);
631 :
632 50 : advgetopt::getopt opt(environment_options, argc, argv);
633 :
634 : // check that the result is valid
635 :
636 : // verify both parameters the "normal" way
637 25 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
638 25 : CATCH_REQUIRE(opt.size("reference") == 1);
639 25 : CATCH_REQUIRE(opt.get_string("reference") == "3100");
640 25 : CATCH_REQUIRE(opt.get_long("reference") == 3100);
641 : #pragma GCC diagnostic push
642 : #pragma GCC diagnostic ignored "-Wfloat-equal"
643 : {
644 25 : bool const a3(opt.get_double("reference") == 3100.0);
645 25 : CATCH_REQUIRE(a3);
646 : }
647 : #pragma GCC diagnostic pop
648 :
649 25 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
650 25 : CATCH_REQUIRE(opt.size("verbose") == 1);
651 25 : CATCH_REQUIRE(opt.get_string("verbose") == "silence");
652 :
653 25 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
654 :
655 : // check the read-only verbose which does not create a reference
656 25 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "3100");
657 25 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "silence");
658 :
659 50 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
660 25 : CATCH_REQUIRE(reference_value == "3100");
661 50 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
662 25 : CATCH_REQUIRE(verbose_value == "silence");
663 :
664 : // get references
665 50 : advgetopt::option_info_ref unknown_ref(opt["unknown"]);
666 50 : advgetopt::option_info_ref undefined_ref(opt["undefined"]); // never set, used as rhs to test setting/adding with an undefined ref.
667 50 : advgetopt::option_info_ref reference_ref(opt["reference"]);
668 50 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
669 :
670 25 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
671 25 : CATCH_REQUIRE(opt.is_defined("reference"));
672 25 : CATCH_REQUIRE(opt.is_defined("verbose"));
673 25 : CATCH_REQUIRE(reference_ref.get_long() == 3100);
674 : #pragma GCC diagnostic push
675 : #pragma GCC diagnostic ignored "-Wfloat-equal"
676 : {
677 25 : bool const a4(reference_ref.get_double() == 3100.0);
678 25 : CATCH_REQUIRE(a4);
679 : }
680 : #pragma GCC diagnostic pop
681 :
682 50 : CATCH_WHEN("with = & zero char")
683 : {
684 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
685 :
686 1 : char const c('\0');
687 1 : unknown_ref = c;
688 :
689 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
690 :
691 2 : std::string s;
692 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
693 :
694 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
695 1 : CATCH_REQUIRE(unknown_value == s);
696 :
697 1 : CATCH_REQUIRE(unknown_ref == s);
698 :
699 1 : unknown_ref += c;
700 :
701 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
702 :
703 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
704 :
705 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
706 1 : CATCH_REQUIRE(unknown_value2 == s);
707 :
708 1 : CATCH_REQUIRE(unknown_ref == s);
709 : }
710 :
711 50 : CATCH_WHEN("with = & valid char")
712 : {
713 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
714 :
715 1 : char const c(rand() % 26 + 'a');
716 1 : unknown_ref = c;
717 :
718 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
719 :
720 2 : std::string s;
721 1 : s += c;
722 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
723 :
724 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
725 1 : CATCH_REQUIRE(unknown_value == s);
726 :
727 1 : CATCH_REQUIRE(unknown_ref == s);
728 :
729 1 : char const d(rand() % 26 + 'a');
730 1 : unknown_ref += d;
731 :
732 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
733 :
734 1 : s += d;
735 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
736 :
737 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
738 1 : CATCH_REQUIRE(unknown_value2 == s);
739 :
740 1 : CATCH_REQUIRE(unknown_ref == s);
741 : }
742 :
743 50 : CATCH_WHEN("with = & zero char32_t")
744 : {
745 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
746 :
747 1 : char32_t const c(U'\0');
748 1 : unknown_ref = c;
749 :
750 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
751 :
752 2 : std::string s;
753 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
754 :
755 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
756 1 : CATCH_REQUIRE(unknown_value == s);
757 :
758 1 : CATCH_REQUIRE(unknown_ref == s);
759 :
760 1 : unknown_ref += c;
761 :
762 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
763 :
764 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
765 :
766 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
767 1 : CATCH_REQUIRE(unknown_value2 == s);
768 :
769 1 : CATCH_REQUIRE(unknown_ref == s);
770 : }
771 :
772 50 : CATCH_WHEN("with = & valid char32_t")
773 : {
774 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
775 :
776 1 : char32_t c((rand() & 0xFFFFF) + ' ');
777 1 : if(c >= 0xD800 && c < 0xE000)
778 : {
779 0 : c += 0x0800;
780 : }
781 1 : unknown_ref = c;
782 :
783 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
784 :
785 2 : std::string s;
786 1 : s += libutf8::to_u8string(c);
787 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
788 :
789 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
790 1 : CATCH_REQUIRE(unknown_value == s);
791 :
792 1 : CATCH_REQUIRE(unknown_ref == s);
793 :
794 1 : char32_t d((rand() & 0xFFFFF) + ' ');
795 1 : if(d >= 0xD800 && d < 0xE000)
796 : {
797 0 : d += 0x0800;
798 : }
799 1 : unknown_ref += d;
800 :
801 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
802 :
803 1 : s += libutf8::to_u8string(d);
804 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
805 :
806 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
807 1 : CATCH_REQUIRE(unknown_value2 == s);
808 :
809 1 : CATCH_REQUIRE(unknown_ref == s);
810 : }
811 :
812 50 : CATCH_WHEN("with = & nullptr of 'char const *'")
813 : {
814 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
815 :
816 1 : char const * str(nullptr);
817 1 : unknown_ref = str;
818 :
819 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
820 :
821 2 : std::string s;
822 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
823 :
824 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
825 1 : CATCH_REQUIRE(unknown_value == s);
826 :
827 1 : CATCH_REQUIRE(unknown_ref == s);
828 :
829 1 : unknown_ref += str;
830 :
831 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
832 :
833 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
834 :
835 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
836 1 : CATCH_REQUIRE(unknown_value2 == s);
837 :
838 1 : CATCH_REQUIRE(unknown_ref == s);
839 : }
840 :
841 50 : CATCH_WHEN("with = & empty 'char const *' string")
842 : {
843 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
844 :
845 1 : char const * str("");
846 1 : unknown_ref = str;
847 :
848 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
849 :
850 2 : std::string s;
851 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
852 :
853 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
854 1 : CATCH_REQUIRE(unknown_value == s);
855 :
856 1 : CATCH_REQUIRE(unknown_ref == s);
857 :
858 1 : unknown_ref += str;
859 :
860 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
861 :
862 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
863 :
864 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
865 1 : CATCH_REQUIRE(unknown_value2 == s);
866 :
867 1 : CATCH_REQUIRE(unknown_ref == s);
868 : }
869 :
870 50 : CATCH_WHEN("with = & valid `char const *`")
871 : {
872 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
873 :
874 2 : std::string str;
875 1 : size_t max(rand() % 10 + 1);
876 5 : for(size_t idx(0); idx < max; ++idx)
877 : {
878 4 : char32_t c((rand() & 0xFFFFF) + ' ');
879 4 : if(c >= 0xD800 && c < 0xE000)
880 : {
881 0 : c += 0x0800;
882 : }
883 4 : str += libutf8::to_u8string(c);
884 : }
885 1 : unknown_ref = str.c_str();
886 :
887 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
888 :
889 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
890 :
891 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
892 1 : CATCH_REQUIRE(unknown_value == str);
893 :
894 1 : CATCH_REQUIRE(unknown_ref == str);
895 :
896 2 : std::string add;
897 1 : max = rand() % 10 + 1;
898 11 : for(size_t idx(0); idx < max; ++idx)
899 : {
900 10 : char32_t c((rand() & 0xFFFFF) + ' ');
901 10 : if(c >= 0xD800 && c < 0xE000)
902 : {
903 0 : c += 0x0800;
904 : }
905 10 : add += libutf8::to_u8string(c);
906 : }
907 1 : unknown_ref += add.c_str();
908 :
909 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
910 :
911 1 : str += add;
912 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
913 :
914 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
915 1 : CATCH_REQUIRE(unknown_value2 == str);
916 :
917 1 : CATCH_REQUIRE(unknown_ref == str);
918 : }
919 :
920 50 : CATCH_WHEN("with = & empty std::string")
921 : {
922 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
923 :
924 2 : std::string str;
925 1 : unknown_ref = str;
926 :
927 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
928 :
929 2 : std::string s;
930 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
931 :
932 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
933 1 : CATCH_REQUIRE(unknown_value == s);
934 :
935 1 : CATCH_REQUIRE(unknown_ref == s);
936 :
937 1 : unknown_ref += str;
938 :
939 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
940 :
941 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
942 :
943 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
944 1 : CATCH_REQUIRE(unknown_value2 == s);
945 :
946 1 : CATCH_REQUIRE(unknown_ref == s);
947 : }
948 :
949 50 : CATCH_WHEN("with = & valid std::string")
950 : {
951 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
952 :
953 2 : std::string str;
954 1 : size_t max(rand() % 10 + 1);
955 4 : for(size_t idx(0); idx < max; ++idx)
956 : {
957 3 : char32_t c((rand() & 0xFFFFF) + ' ');
958 3 : if(c >= 0xD800 && c < 0xE000)
959 : {
960 0 : c += 0x0800;
961 : }
962 3 : str += libutf8::to_u8string(c);
963 : }
964 1 : unknown_ref = str;
965 :
966 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
967 :
968 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
969 :
970 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
971 1 : CATCH_REQUIRE(unknown_value == str);
972 :
973 1 : CATCH_REQUIRE(unknown_ref == str);
974 :
975 2 : std::string add;
976 1 : max = rand() % 10 + 1;
977 4 : for(size_t idx(0); idx < max; ++idx)
978 : {
979 3 : char32_t c((rand() & 0xFFFFF) + ' ');
980 3 : if(c >= 0xD800 && c < 0xE000)
981 : {
982 0 : c += 0x0800;
983 : }
984 3 : add += libutf8::to_u8string(c);
985 : }
986 1 : unknown_ref += add;
987 :
988 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
989 :
990 1 : str += add;
991 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
992 :
993 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
994 1 : CATCH_REQUIRE(unknown_value2 == str);
995 :
996 1 : CATCH_REQUIRE(unknown_ref == str);
997 : }
998 :
999 50 : CATCH_WHEN("with = & unknown reference")
1000 : {
1001 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1002 :
1003 1 : unknown_ref = undefined_ref;
1004 :
1005 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1006 :
1007 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
1008 :
1009 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1010 1 : CATCH_REQUIRE(unknown_value == std::string());
1011 :
1012 1 : CATCH_REQUIRE(unknown_ref == std::string());
1013 : }
1014 :
1015 50 : CATCH_WHEN("with = & self reference")
1016 : {
1017 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1018 :
1019 1 : unknown_ref = unknown_ref;
1020 :
1021 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1022 :
1023 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
1024 :
1025 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1026 1 : CATCH_REQUIRE(unknown_value == std::string());
1027 :
1028 1 : CATCH_REQUIRE(unknown_ref == std::string());
1029 :
1030 1 : CATCH_REQUIRE(unknown_ref == unknown_ref);
1031 : }
1032 :
1033 50 : CATCH_WHEN("with = & known reference")
1034 : {
1035 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1036 :
1037 1 : unknown_ref = verbose_ref;
1038 :
1039 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1040 :
1041 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == verbose_value);
1042 :
1043 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1044 1 : CATCH_REQUIRE(unknown_value == verbose_value);
1045 :
1046 1 : CATCH_REQUIRE(unknown_ref == verbose_value);
1047 :
1048 1 : unknown_ref += reference_ref;
1049 :
1050 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1051 :
1052 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == verbose_value + reference_value);
1053 :
1054 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1055 1 : CATCH_REQUIRE(unknown_value2 == verbose_value + reference_value);
1056 :
1057 1 : CATCH_REQUIRE(unknown_ref == verbose_value + reference_value);
1058 : }
1059 :
1060 50 : CATCH_WHEN("with += & zero char")
1061 : {
1062 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1063 :
1064 1 : char const c('\0');
1065 1 : unknown_ref += c;
1066 :
1067 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1068 :
1069 2 : std::string s;
1070 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1071 :
1072 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1073 1 : CATCH_REQUIRE(unknown_value == s);
1074 :
1075 1 : CATCH_REQUIRE(unknown_ref == s);
1076 : }
1077 :
1078 50 : CATCH_WHEN("with += & valid char")
1079 : {
1080 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1081 :
1082 1 : char const c(rand() % 26 + 'a');
1083 1 : unknown_ref += c;
1084 :
1085 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1086 :
1087 2 : std::string s;
1088 1 : s += c;
1089 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1090 :
1091 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1092 1 : CATCH_REQUIRE(unknown_value == s);
1093 :
1094 1 : CATCH_REQUIRE(unknown_ref == s);
1095 : }
1096 :
1097 50 : CATCH_WHEN("with += & zero char32_t")
1098 : {
1099 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1100 :
1101 1 : char32_t const c(U'\0');
1102 1 : unknown_ref += c;
1103 :
1104 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1105 :
1106 2 : std::string s;
1107 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1108 :
1109 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1110 1 : CATCH_REQUIRE(unknown_value == s);
1111 :
1112 1 : CATCH_REQUIRE(unknown_ref == s);
1113 : }
1114 :
1115 50 : CATCH_WHEN("with += & valid char32_t")
1116 : {
1117 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1118 :
1119 1 : char32_t c((rand() & 0xFFFFF) + ' ');
1120 1 : if(c >= 0xD800 && c < 0xE000)
1121 : {
1122 0 : c += 0x0800;
1123 : }
1124 :
1125 1 : unknown_ref += c;
1126 :
1127 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1128 :
1129 2 : std::string s;
1130 1 : s += libutf8::to_u8string(c);
1131 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1132 :
1133 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1134 1 : CATCH_REQUIRE(unknown_value == s);
1135 :
1136 1 : CATCH_REQUIRE(unknown_ref == s);
1137 : }
1138 :
1139 50 : CATCH_WHEN("with += & nullptr of 'char const *'")
1140 : {
1141 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1142 :
1143 1 : char const * str(nullptr);
1144 :
1145 1 : unknown_ref += str;
1146 :
1147 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1148 :
1149 2 : std::string s;
1150 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1151 :
1152 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1153 1 : CATCH_REQUIRE(unknown_value2 == s);
1154 :
1155 1 : CATCH_REQUIRE(unknown_ref == s);
1156 : }
1157 :
1158 50 : CATCH_WHEN("with += & empty 'char const *' string")
1159 : {
1160 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1161 :
1162 1 : char const * str("");
1163 :
1164 1 : unknown_ref += str;
1165 :
1166 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1167 :
1168 2 : std::string s;
1169 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1170 :
1171 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1172 1 : CATCH_REQUIRE(unknown_value == s);
1173 :
1174 1 : CATCH_REQUIRE(unknown_ref == s);
1175 : }
1176 :
1177 50 : CATCH_WHEN("with += & valid `char const *`")
1178 : {
1179 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1180 :
1181 2 : std::string str;
1182 1 : size_t max(rand() % 10 + 1);
1183 11 : for(size_t idx(0); idx < max; ++idx)
1184 : {
1185 10 : char32_t c((rand() & 0xFFFFF) + ' ');
1186 10 : if(c >= 0xD800 && c < 0xE000)
1187 : {
1188 0 : c += 0x0800;
1189 : }
1190 10 : str += libutf8::to_u8string(c);
1191 : }
1192 :
1193 1 : unknown_ref += str.c_str();
1194 :
1195 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1196 :
1197 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
1198 :
1199 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1200 1 : CATCH_REQUIRE(unknown_value == str);
1201 :
1202 1 : CATCH_REQUIRE(unknown_ref == str);
1203 : }
1204 :
1205 50 : CATCH_WHEN("with += & empty std::string")
1206 : {
1207 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1208 :
1209 2 : std::string str;
1210 1 : unknown_ref += str;
1211 :
1212 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1213 :
1214 2 : std::string s;
1215 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
1216 :
1217 2 : std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1218 1 : CATCH_REQUIRE(unknown_value2 == s);
1219 :
1220 1 : CATCH_REQUIRE(unknown_ref == s);
1221 : }
1222 :
1223 50 : CATCH_WHEN("with += & valid std::string")
1224 : {
1225 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1226 :
1227 2 : std::string str;
1228 1 : size_t max(rand() % 10 + 1);
1229 3 : for(size_t idx(0); idx < max; ++idx)
1230 : {
1231 2 : char32_t c((rand() & 0xFFFFF) + ' ');
1232 2 : if(c >= 0xD800 && c < 0xE000)
1233 : {
1234 0 : c += 0x0800;
1235 : }
1236 2 : str += libutf8::to_u8string(c);
1237 : }
1238 1 : unknown_ref += str;
1239 :
1240 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1241 :
1242 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
1243 :
1244 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1245 1 : CATCH_REQUIRE(unknown_value == str);
1246 :
1247 1 : CATCH_REQUIRE(unknown_ref == str);
1248 : }
1249 :
1250 50 : CATCH_WHEN("with += & unknown reference")
1251 : {
1252 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1253 :
1254 1 : unknown_ref += undefined_ref;
1255 :
1256 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1257 :
1258 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
1259 :
1260 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1261 1 : CATCH_REQUIRE(unknown_value == std::string());
1262 :
1263 1 : CATCH_REQUIRE(unknown_ref == std::string());
1264 : }
1265 :
1266 50 : CATCH_WHEN("with += & self reference")
1267 : {
1268 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1269 :
1270 1 : unknown_ref += unknown_ref;
1271 :
1272 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1273 :
1274 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
1275 :
1276 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1277 1 : CATCH_REQUIRE(unknown_value == std::string());
1278 :
1279 1 : CATCH_REQUIRE(unknown_ref == std::string());
1280 :
1281 1 : CATCH_REQUIRE(unknown_ref == unknown_ref);
1282 : }
1283 :
1284 50 : CATCH_WHEN("with += & known reference")
1285 : {
1286 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1287 :
1288 1 : unknown_ref += reference_ref;
1289 :
1290 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1291 :
1292 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == reference_value);
1293 :
1294 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1295 1 : CATCH_REQUIRE(unknown_value == reference_value);
1296 :
1297 1 : CATCH_REQUIRE(unknown_ref == reference_value);
1298 : }
1299 :
1300 50 : CATCH_WHEN("with += & self reference")
1301 : {
1302 1 : CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
1303 :
1304 1 : unknown_ref += unknown_ref;
1305 :
1306 1 : CATCH_REQUIRE(opt.is_defined("unknown"));
1307 :
1308 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
1309 :
1310 2 : std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
1311 1 : CATCH_REQUIRE(unknown_value == "");
1312 :
1313 1 : CATCH_REQUIRE(unknown_ref == "");
1314 : }
1315 : }
1316 : CATCH_END_SECTION()
1317 27 : }
1318 :
1319 :
1320 :
1321 4 : CATCH_TEST_CASE("option_info_ref_with_valid_default", "[option_info][valid][reference][long][default]")
1322 : {
1323 4 : CATCH_START_SECTION("No reference on command line, valid default for get_long()")
1324 : {
1325 1 : advgetopt::option const options[] =
1326 : {
1327 : advgetopt::define_option(
1328 : advgetopt::Name("reference")
1329 : , advgetopt::ShortName('r')
1330 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1331 : , advgetopt::Help("test reference.")
1332 : , advgetopt::DefaultValue("459")
1333 : ),
1334 : advgetopt::define_option(
1335 : advgetopt::Name("verbose")
1336 : , advgetopt::ShortName('v')
1337 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1338 : , advgetopt::Help("make it all verbose.")
1339 : ),
1340 : advgetopt::end_options()
1341 : };
1342 :
1343 1 : advgetopt::options_environment environment_options;
1344 1 : environment_options.f_project_name = "unittest";
1345 1 : environment_options.f_options = options;
1346 1 : environment_options.f_help_header = "Usage: verify references";
1347 :
1348 1 : char const * cargv[] =
1349 : {
1350 : "/usr/bin/arguments",
1351 : "--verbose",
1352 : "loud",
1353 : nullptr
1354 : };
1355 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
1356 1 : char ** argv = const_cast<char **>(cargv);
1357 :
1358 2 : advgetopt::getopt opt(environment_options, argc, argv);
1359 :
1360 : // check that the result is valid
1361 :
1362 : // verify both parameters the "normal" way
1363 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
1364 1 : CATCH_REQUIRE(opt.size("reference") == 0);
1365 1 : CATCH_REQUIRE(opt.get_string("reference") == "459");
1366 :
1367 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
1368 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
1369 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
1370 :
1371 : // check the read-only verbose which does not create a reference
1372 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "459");
1373 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
1374 :
1375 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
1376 1 : CATCH_REQUIRE(reference_value == "459");
1377 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
1378 1 : CATCH_REQUIRE(verbose_value == "loud");
1379 :
1380 : // get a reference
1381 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
1382 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
1383 :
1384 1 : CATCH_REQUIRE(reference_ref.empty());
1385 1 : CATCH_REQUIRE_FALSE(verbose_ref.empty());
1386 :
1387 1 : CATCH_REQUIRE(reference_ref.length() == 3);
1388 1 : CATCH_REQUIRE(reference_ref.size() == 3);
1389 1 : CATCH_REQUIRE(verbose_ref.length() == 4);
1390 1 : CATCH_REQUIRE(verbose_ref.size() == 4);
1391 :
1392 1 : CATCH_REQUIRE(reference_ref.get_long() == 459);
1393 :
1394 1 : CATCH_REQUIRE(reference_ref == reference_ref);
1395 1 : CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
1396 1 : CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
1397 1 : CATCH_REQUIRE(reference_ref <= reference_ref);
1398 1 : CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
1399 1 : CATCH_REQUIRE(reference_ref >= reference_ref);
1400 :
1401 1 : CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
1402 1 : CATCH_REQUIRE(reference_ref != verbose_ref);
1403 1 : CATCH_REQUIRE(reference_ref < verbose_ref);
1404 1 : CATCH_REQUIRE(reference_ref <= verbose_ref);
1405 1 : CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
1406 1 : CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
1407 : }
1408 : CATCH_END_SECTION()
1409 :
1410 4 : CATCH_START_SECTION("No reference on command line, valid default for get_double()")
1411 : {
1412 1 : advgetopt::option const options[] =
1413 : {
1414 : advgetopt::define_option(
1415 : advgetopt::Name("reference")
1416 : , advgetopt::ShortName('r')
1417 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1418 : , advgetopt::Help("test reference.")
1419 : , advgetopt::DefaultValue("45.9")
1420 : ),
1421 : advgetopt::define_option(
1422 : advgetopt::Name("verbose")
1423 : , advgetopt::ShortName('v')
1424 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1425 : , advgetopt::Help("make it all verbose.")
1426 : ),
1427 : advgetopt::end_options()
1428 : };
1429 :
1430 1 : advgetopt::options_environment environment_options;
1431 1 : environment_options.f_project_name = "unittest";
1432 1 : environment_options.f_options = options;
1433 1 : environment_options.f_help_header = "Usage: verify references";
1434 :
1435 1 : char const * cargv[] =
1436 : {
1437 : "/usr/bin/arguments",
1438 : "--verbose",
1439 : "loud",
1440 : nullptr
1441 : };
1442 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
1443 1 : char ** argv = const_cast<char **>(cargv);
1444 :
1445 2 : advgetopt::getopt opt(environment_options, argc, argv);
1446 :
1447 : // check that the result is valid
1448 :
1449 : // verify both parameters the "normal" way
1450 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
1451 1 : CATCH_REQUIRE(opt.size("reference") == 0);
1452 1 : CATCH_REQUIRE(opt.get_string("reference") == "45.9");
1453 :
1454 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
1455 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
1456 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
1457 :
1458 : // check the read-only verbose which does not create a reference
1459 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "45.9");
1460 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
1461 :
1462 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
1463 1 : CATCH_REQUIRE(reference_value == "45.9");
1464 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
1465 1 : CATCH_REQUIRE(verbose_value == "loud");
1466 :
1467 : // get a reference
1468 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
1469 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
1470 :
1471 1 : CATCH_REQUIRE(reference_ref.empty());
1472 1 : CATCH_REQUIRE_FALSE(verbose_ref.empty());
1473 :
1474 1 : CATCH_REQUIRE(reference_ref.length() == 4);
1475 1 : CATCH_REQUIRE(reference_ref.size() == 4);
1476 1 : CATCH_REQUIRE(verbose_ref.length() == 4);
1477 1 : CATCH_REQUIRE(verbose_ref.size() == 4);
1478 :
1479 : #pragma GCC diagnostic push
1480 : #pragma GCC diagnostic ignored "-Wfloat-equal"
1481 : {
1482 1 : bool const a1(reference_ref.get_double() == 45.9);
1483 1 : CATCH_REQUIRE(a1);
1484 : }
1485 : #pragma GCC diagnostic pop
1486 :
1487 1 : CATCH_REQUIRE(reference_ref == reference_ref);
1488 1 : CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
1489 1 : CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
1490 1 : CATCH_REQUIRE(reference_ref <= reference_ref);
1491 1 : CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
1492 1 : CATCH_REQUIRE(reference_ref >= reference_ref);
1493 :
1494 1 : CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
1495 1 : CATCH_REQUIRE(reference_ref != verbose_ref);
1496 1 : CATCH_REQUIRE(reference_ref < verbose_ref);
1497 1 : CATCH_REQUIRE(reference_ref <= verbose_ref);
1498 1 : CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
1499 1 : CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
1500 : }
1501 : CATCH_END_SECTION()
1502 2 : }
1503 :
1504 :
1505 :
1506 4 : CATCH_TEST_CASE("option_info_ref_with_invalid_default", "[option_info][invalid][reference][long][default]")
1507 : {
1508 4 : CATCH_START_SECTION("No reference on command line, not valid for get_long()")
1509 : {
1510 1 : advgetopt::option const options[] =
1511 : {
1512 : advgetopt::define_option(
1513 : advgetopt::Name("reference")
1514 : , advgetopt::ShortName('r')
1515 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1516 : , advgetopt::Help("test reference.")
1517 : , advgetopt::DefaultValue("undefined")
1518 : ),
1519 : advgetopt::define_option(
1520 : advgetopt::Name("verbose")
1521 : , advgetopt::ShortName('v')
1522 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1523 : , advgetopt::Help("make it all verbose.")
1524 : ),
1525 : advgetopt::end_options()
1526 : };
1527 :
1528 1 : advgetopt::options_environment environment_options;
1529 1 : environment_options.f_project_name = "unittest";
1530 1 : environment_options.f_options = options;
1531 1 : environment_options.f_help_header = "Usage: verify references";
1532 :
1533 1 : char const * cargv[] =
1534 : {
1535 : "/usr/bin/arguments",
1536 : "--verbose",
1537 : "loud",
1538 : nullptr
1539 : };
1540 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
1541 1 : char ** argv = const_cast<char **>(cargv);
1542 :
1543 2 : advgetopt::getopt opt(environment_options, argc, argv);
1544 :
1545 : // check that the result is valid
1546 :
1547 : // verify both parameters the "normal" way
1548 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
1549 1 : CATCH_REQUIRE(opt.size("reference") == 0);
1550 1 : CATCH_REQUIRE(opt.get_string("reference") == "undefined");
1551 :
1552 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
1553 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
1554 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
1555 :
1556 : // check the read-only verbose which does not create a reference
1557 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "undefined");
1558 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
1559 :
1560 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
1561 1 : CATCH_REQUIRE(reference_value == "undefined");
1562 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
1563 1 : CATCH_REQUIRE(verbose_value == "loud");
1564 :
1565 : // get a reference
1566 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
1567 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
1568 :
1569 1 : CATCH_REQUIRE(reference_ref.empty());
1570 1 : CATCH_REQUIRE_FALSE(verbose_ref.empty());
1571 :
1572 1 : CATCH_REQUIRE(reference_ref.length() == 9);
1573 1 : CATCH_REQUIRE(reference_ref.size() == 9);
1574 1 : CATCH_REQUIRE(verbose_ref.length() == 4);
1575 1 : CATCH_REQUIRE(verbose_ref.size() == 4);
1576 :
1577 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid default value for a number (undefined) in parameter --reference at offset 0.");
1578 1 : CATCH_REQUIRE(reference_ref.get_long() == -1);
1579 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1580 :
1581 1 : CATCH_REQUIRE(reference_ref == reference_ref);
1582 1 : CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
1583 1 : CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
1584 1 : CATCH_REQUIRE(reference_ref <= reference_ref);
1585 1 : CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
1586 1 : CATCH_REQUIRE(reference_ref >= reference_ref);
1587 :
1588 1 : CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
1589 1 : CATCH_REQUIRE(reference_ref != verbose_ref);
1590 1 : CATCH_REQUIRE_FALSE(reference_ref < verbose_ref);
1591 1 : CATCH_REQUIRE_FALSE(reference_ref <= verbose_ref);
1592 1 : CATCH_REQUIRE(reference_ref > verbose_ref);
1593 1 : CATCH_REQUIRE(reference_ref >= verbose_ref);
1594 : }
1595 : CATCH_END_SECTION()
1596 :
1597 4 : CATCH_START_SECTION("No reference on command line, not valid for get_double()")
1598 : {
1599 1 : advgetopt::option const options[] =
1600 : {
1601 : advgetopt::define_option(
1602 : advgetopt::Name("reference")
1603 : , advgetopt::ShortName('r')
1604 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1605 : , advgetopt::Help("test reference.")
1606 : , advgetopt::DefaultValue("undefined")
1607 : ),
1608 : advgetopt::define_option(
1609 : advgetopt::Name("verbose")
1610 : , advgetopt::ShortName('v')
1611 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1612 : , advgetopt::Help("make it all verbose.")
1613 : ),
1614 : advgetopt::end_options()
1615 : };
1616 :
1617 1 : advgetopt::options_environment environment_options;
1618 1 : environment_options.f_project_name = "unittest";
1619 1 : environment_options.f_options = options;
1620 1 : environment_options.f_help_header = "Usage: verify references";
1621 :
1622 1 : char const * cargv[] =
1623 : {
1624 : "/usr/bin/arguments",
1625 : "--verbose",
1626 : "loud",
1627 : nullptr
1628 : };
1629 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
1630 1 : char ** argv = const_cast<char **>(cargv);
1631 :
1632 2 : advgetopt::getopt opt(environment_options, argc, argv);
1633 :
1634 : // check that the result is valid
1635 :
1636 : // verify both parameters the "normal" way
1637 1 : CATCH_REQUIRE(opt.get_option("reference") != nullptr);
1638 1 : CATCH_REQUIRE(opt.size("reference") == 0);
1639 1 : CATCH_REQUIRE(opt.get_string("reference") == "undefined");
1640 :
1641 1 : CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
1642 1 : CATCH_REQUIRE(opt.size("verbose") == 1);
1643 1 : CATCH_REQUIRE(opt.get_string("verbose") == "loud");
1644 :
1645 : // check the read-only verbose which does not create a reference
1646 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "undefined");
1647 1 : CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
1648 :
1649 2 : std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
1650 1 : CATCH_REQUIRE(reference_value == "undefined");
1651 2 : std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
1652 1 : CATCH_REQUIRE(verbose_value == "loud");
1653 :
1654 : // get a reference
1655 2 : advgetopt::option_info_ref reference_ref(opt["reference"]);
1656 2 : advgetopt::option_info_ref verbose_ref(opt["verbose"]);
1657 :
1658 1 : CATCH_REQUIRE(reference_ref.empty());
1659 1 : CATCH_REQUIRE_FALSE(verbose_ref.empty());
1660 :
1661 1 : CATCH_REQUIRE(reference_ref.length() == 9);
1662 1 : CATCH_REQUIRE(reference_ref.size() == 9);
1663 1 : CATCH_REQUIRE(verbose_ref.length() == 4);
1664 1 : CATCH_REQUIRE(verbose_ref.size() == 4);
1665 :
1666 : #pragma GCC diagnostic push
1667 : #pragma GCC diagnostic ignored "-Wfloat-equal"
1668 : {
1669 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid default value as a double number (undefined) in parameter --reference at offset 0.");
1670 1 : bool const a1(reference_ref.get_double() == -1);
1671 1 : CATCH_REQUIRE(a1);
1672 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1673 : }
1674 : #pragma GCC diagnostic pop
1675 :
1676 1 : CATCH_REQUIRE(reference_ref == reference_ref);
1677 1 : CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
1678 1 : CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
1679 1 : CATCH_REQUIRE(reference_ref <= reference_ref);
1680 1 : CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
1681 1 : CATCH_REQUIRE(reference_ref >= reference_ref);
1682 :
1683 1 : CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
1684 1 : CATCH_REQUIRE(reference_ref != verbose_ref);
1685 1 : CATCH_REQUIRE_FALSE(reference_ref < verbose_ref);
1686 1 : CATCH_REQUIRE_FALSE(reference_ref <= verbose_ref);
1687 1 : CATCH_REQUIRE(reference_ref > verbose_ref);
1688 1 : CATCH_REQUIRE(reference_ref >= verbose_ref);
1689 : }
1690 : CATCH_END_SECTION()
1691 8 : }
1692 :
1693 :
1694 :
1695 :
1696 :
1697 :
1698 :
1699 : // vim: ts=4 sw=4 et
|