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 : // snapdev lib
35 : //
36 : #include <snapdev/safe_setenv.h>
37 :
38 : // C++ lib
39 : //
40 : #include <fstream>
41 :
42 :
43 : namespace
44 : {
45 :
46 41240 : std::int64_t large_rnd()
47 : {
48 41240 : return (static_cast<std::int64_t>(rand()) << 0)
49 41240 : ^ (static_cast<std::int64_t>(rand()) << 16)
50 41240 : ^ (static_cast<std::int64_t>(rand()) << 32)
51 41240 : ^ (static_cast<std::int64_t>(rand()) << 48);
52 : }
53 :
54 : }
55 :
56 :
57 :
58 4 : CATCH_TEST_CASE("unknown_validator", "[validator][valid][validation]")
59 : {
60 4 : CATCH_START_SECTION("Undefined validator")
61 : // this is a valid case, it does not throw, it just returns a nullptr
62 : //
63 1 : CATCH_REQUIRE(advgetopt::validator::create("unknown", advgetopt::string_list_t()) == nullptr);
64 : CATCH_END_SECTION()
65 :
66 4 : CATCH_START_SECTION("Empty string")
67 1 : CATCH_REQUIRE(advgetopt::validator::create(std::string()) == nullptr);
68 : CATCH_END_SECTION()
69 2 : }
70 :
71 :
72 :
73 5 : CATCH_TEST_CASE("integer_validator", "[validator][valid][validation]")
74 : {
75 6 : CATCH_START_SECTION("Verify the integer validator")
76 2 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", advgetopt::string_list_t()));
77 :
78 1 : CATCH_REQUIRE(integer_validator != nullptr);
79 1 : CATCH_REQUIRE(integer_validator->name() == "integer");
80 :
81 1 : CATCH_REQUIRE_FALSE(integer_validator->validate(""));
82 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("+"));
83 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("-"));
84 :
85 1001 : for(int idx(0); idx < 1000; ++idx)
86 : {
87 1000 : std::int64_t value(large_rnd());
88 2000 : std::string const v(std::to_string(value));
89 :
90 1000 : CATCH_REQUIRE(integer_validator->validate(v));
91 :
92 1000 : if(value >= 0)
93 : {
94 535 : CATCH_REQUIRE(integer_validator->validate('+' + v));
95 : }
96 :
97 2000 : std::string const space_before(' ' + v);
98 1000 : CATCH_REQUIRE_FALSE(integer_validator->validate(space_before));
99 :
100 2000 : std::string const space_after(v + ' ');
101 1000 : CATCH_REQUIRE_FALSE(integer_validator->validate(space_after));
102 :
103 2000 : std::string const before(static_cast<char>(rand() % 26 + 'a') + v);
104 1000 : CATCH_REQUIRE_FALSE(integer_validator->validate(before));
105 :
106 2000 : std::string const after(v + static_cast<char>(rand() % 26 + 'a'));
107 1000 : CATCH_REQUIRE_FALSE(integer_validator->validate(after));
108 : }
109 :
110 : // max number
111 1 : CATCH_REQUIRE(integer_validator->validate("9223372036854775807"));
112 1 : CATCH_REQUIRE(integer_validator->validate("+9223372036854775807"));
113 :
114 : // overflow
115 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("9223372036854775808"));
116 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("+9223372036854775808"));
117 :
118 : // min number
119 1 : CATCH_REQUIRE(integer_validator->validate("-9223372036854775808"));
120 :
121 : // underflow
122 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("-9223372036854775809"));
123 :
124 : // too many digits
125 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("92233720368547758091"));
126 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("+92233720368547758092"));
127 1 : CATCH_REQUIRE_FALSE(integer_validator->validate("-92233720368547758093"));
128 : CATCH_END_SECTION()
129 :
130 6 : CATCH_START_SECTION("Verify the integer ranges")
131 1 : bool had_standalone(false);
132 21 : for(int count(0); count < 20 || !had_standalone; ++count)
133 : {
134 20 : std::int64_t min(large_rnd());
135 20 : std::int64_t max(large_rnd());
136 20 : if(min > max)
137 : {
138 7 : std::swap(min, max);
139 : }
140 :
141 40 : std::string const & smin(std::to_string(min));
142 40 : std::string const & smax(std::to_string(max));
143 :
144 40 : std::string range("...");
145 80 : for(int three(0); three < 3; ++three)
146 : {
147 60 : if(rand() % 5 == 0)
148 : {
149 9 : range = ' ' + range;
150 : }
151 60 : if(rand() % 5 == 0)
152 : {
153 10 : range = range + ' ';
154 : }
155 : }
156 20 : range = smin + range + smax;
157 80 : for(int three(0); three < 3; ++three)
158 : {
159 60 : if(rand() % 5 == 0)
160 : {
161 10 : range = ' ' + range;
162 : }
163 60 : if(rand() % 5 == 0)
164 : {
165 12 : range = range + ' ';
166 : }
167 : }
168 :
169 20 : std::int64_t standalone(0);
170 20 : bool standalone_included(rand() % 4 == 0);
171 20 : if(standalone_included)
172 : {
173 12 : if(min == std::numeric_limits<std::int64_t>::min()
174 6 : && max == std::numeric_limits<std::int64_t>::max())
175 : {
176 0 : standalone_included = false;
177 : }
178 : else
179 : {
180 6 : had_standalone = true;
181 16 : do
182 : {
183 22 : standalone = large_rnd();
184 : }
185 22 : while(standalone >= min && standalone <= max);
186 :
187 12 : std::string sep(",");
188 6 : if(rand() % 3 == 0)
189 : {
190 3 : sep = ' ' + sep;
191 : }
192 6 : if(rand() % 3 == 0)
193 : {
194 2 : sep = sep + ' ';
195 : }
196 6 : if(rand() % 2 == 0)
197 : {
198 3 : range = std::to_string(standalone) + "," + range;
199 : }
200 : else
201 : {
202 3 : range = range + "," + std::to_string(standalone);
203 : }
204 : }
205 : }
206 40 : advgetopt::string_list_t range_list;
207 40 : advgetopt::split_string(range
208 : , range_list
209 20 : , {","});
210 40 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range_list));
211 :
212 20 : CATCH_REQUIRE(integer_validator != nullptr);
213 20 : CATCH_REQUIRE(integer_validator->name() == "integer");
214 :
215 20020 : for(int idx(0); idx < 1000; ++idx)
216 : {
217 20000 : std::int64_t value(large_rnd());
218 :
219 : // force valid values otherwise we're likely to only have
220 : // invalid ones
221 : //
222 20000 : if(idx % 10 == 0)
223 : {
224 2000 : value %= max - min + 1;
225 2000 : value += min;
226 : }
227 18000 : else if(idx % 50 == 1 && standalone_included)
228 : {
229 120 : value = standalone;
230 : }
231 :
232 40000 : std::string const v(std::to_string(value));
233 :
234 20000 : if((standalone_included && value == standalone)
235 19880 : || (value >= min && value <= max))
236 : {
237 8635 : CATCH_REQUIRE(integer_validator->validate(v));
238 : }
239 : else
240 : {
241 11365 : CATCH_REQUIRE_FALSE(integer_validator->validate(v));
242 : }
243 :
244 20000 : if(value >= 0)
245 : {
246 9924 : if((standalone_included && value == standalone)
247 9864 : || (value >= min && value <= max))
248 : {
249 4132 : CATCH_REQUIRE(integer_validator->validate('+' + v));
250 : }
251 : else
252 : {
253 5792 : CATCH_REQUIRE_FALSE(integer_validator->validate('+' + v));
254 : }
255 : }
256 :
257 40000 : std::string const space_before(' ' + v);
258 20000 : CATCH_REQUIRE_FALSE(integer_validator->validate(space_before));
259 :
260 40000 : std::string const space_after(v + ' ');
261 20000 : CATCH_REQUIRE_FALSE(integer_validator->validate(space_after));
262 :
263 40000 : std::string const before(static_cast<char>(rand() % 26 + 'a') + v);
264 20000 : CATCH_REQUIRE_FALSE(integer_validator->validate(before));
265 :
266 40000 : std::string const after(v + static_cast<char>(rand() % 26 + 'a'));
267 20000 : CATCH_REQUIRE_FALSE(integer_validator->validate(after));
268 : }
269 : }
270 : CATCH_END_SECTION()
271 :
272 6 : CATCH_START_SECTION("Verify the integer standalone list")
273 21 : for(int count(0); count < 20; ++count)
274 : {
275 20 : int valid(rand() % 10 + 5);
276 40 : std::vector<std::int64_t> numbers;
277 20 : numbers.reserve(valid);
278 40 : std::string standalone_values;
279 198 : for(int idx(0); idx < valid; ++idx)
280 : {
281 178 : std::int64_t const value(large_rnd());
282 178 : numbers.push_back(value);
283 356 : std::string const & svalue(std::to_string(value));
284 178 : if(rand() % 5 == 0)
285 : {
286 33 : standalone_values += ' ';
287 : }
288 178 : if(idx != 0)
289 : {
290 158 : standalone_values += ',';
291 : }
292 178 : if(rand() % 5 == 0)
293 : {
294 30 : standalone_values += ' ';
295 : }
296 178 : standalone_values += svalue;
297 : }
298 20 : if(rand() % 5 == 0)
299 : {
300 7 : standalone_values += ' ';
301 : }
302 40 : advgetopt::string_list_t range_list;
303 40 : advgetopt::split_string(standalone_values
304 : , range_list
305 20 : , {","});
306 :
307 40 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range_list));
308 :
309 20 : CATCH_REQUIRE(integer_validator != nullptr);
310 20 : CATCH_REQUIRE(integer_validator->name() == "integer");
311 :
312 198 : for(size_t idx(0); idx < numbers.size(); ++idx)
313 : {
314 356 : std::string const svalue(std::to_string(numbers[idx]));
315 :
316 178 : CATCH_REQUIRE(integer_validator->validate(svalue));
317 : }
318 :
319 20020 : for(int idx(0); idx < 1000; ++idx)
320 : {
321 : std::int64_t value;
322 :
323 : for(;;)
324 : {
325 20000 : value = large_rnd();
326 20000 : if(std::find(numbers.begin(), numbers.end(), value) == numbers.end())
327 : {
328 20000 : break;
329 : }
330 : }
331 :
332 20000 : CATCH_REQUIRE_FALSE(integer_validator->validate(std::to_string(value)));
333 : }
334 : }
335 : CATCH_END_SECTION()
336 3 : }
337 :
338 :
339 :
340 :
341 6 : CATCH_TEST_CASE("regex_validator", "[validator][valid][validation]")
342 : {
343 8 : CATCH_START_SECTION("Verify the regex validator")
344 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {".*@.*\\..*"}));
345 :
346 1 : CATCH_REQUIRE(regex_validator != nullptr);
347 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
348 :
349 1 : CATCH_REQUIRE(regex_validator->validate("@m2osw."));
350 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
351 1 : CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
352 1 : CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
353 :
354 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
355 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
356 : CATCH_END_SECTION()
357 :
358 8 : CATCH_START_SECTION("Verify the regex string (case sensitive)")
359 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/"}));
360 :
361 1 : CATCH_REQUIRE(regex_validator != nullptr);
362 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
363 :
364 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
365 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
366 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
367 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
368 :
369 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
370 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
371 : CATCH_END_SECTION()
372 :
373 8 : CATCH_START_SECTION("Verify the regex string (case insensitive)")
374 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/i"}));
375 :
376 1 : CATCH_REQUIRE(regex_validator != nullptr);
377 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
378 :
379 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
380 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
381 1 : CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
382 1 : CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
383 :
384 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
385 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
386 : CATCH_END_SECTION()
387 :
388 8 : CATCH_START_SECTION("Verify direct regex string (case insensitive)")
389 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("/contact@.*\\..*/i"));
390 :
391 1 : CATCH_REQUIRE(regex_validator != nullptr);
392 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
393 :
394 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
395 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
396 1 : CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
397 1 : CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
398 :
399 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
400 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
401 : CATCH_END_SECTION()
402 4 : }
403 :
404 :
405 :
406 :
407 :
408 :
409 :
410 :
411 8 : CATCH_TEST_CASE("invalid_validator", "[validator][invalid][validation]")
412 : {
413 12 : CATCH_START_SECTION("Register duplicated factories")
414 0 : class duplicate_integer
415 : : public advgetopt::validator
416 : {
417 : public:
418 0 : virtual std::string const name() const
419 : {
420 0 : return "integer";
421 : }
422 :
423 0 : virtual bool validate(std::string const & value) const override
424 : {
425 0 : return value == "123";
426 : }
427 : };
428 3 : class duplicate_factory
429 : : public advgetopt::validator_factory
430 : {
431 : public:
432 2 : virtual std::string get_name() const
433 : {
434 2 : return "integer";
435 : }
436 :
437 0 : virtual std::shared_ptr<advgetopt::validator> create(advgetopt::string_list_t const & data) const override
438 : {
439 0 : snap::NOTUSED(data); // ignore `data`
440 0 : return std::make_shared<duplicate_integer>();
441 : }
442 : };
443 2 : std::unique_ptr<advgetopt::validator_factory> factory(new duplicate_factory());
444 1 : CATCH_REQUIRE_THROWS_MATCHES(
445 : advgetopt::validator::register_validator(*factory.get())
446 : , advgetopt::getopt_logic_error
447 : , Catch::Matchers::ExceptionMessage(
448 : "getopt_logic_error: you have two or more validator factories named \"integer\"."));
449 : CATCH_END_SECTION()
450 :
451 :
452 12 : CATCH_START_SECTION("Verify invalid ranges")
453 : advgetopt::string_list_t range{
454 : "abc",
455 : "abc...6",
456 : "3...def",
457 2 : "10...1"};
458 :
459 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: abc is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
460 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: abc is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
461 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: def is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
462 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: 10 has to be smaller or equal to 1; you have an invalid range.");
463 :
464 2 : advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range));
465 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
466 : CATCH_END_SECTION()
467 :
468 12 : CATCH_START_SECTION("Verify invalid regex flags")
469 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag f in regular expression \"/contact@.*\\..*/f\".");
470 :
471 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/f"}));
472 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
473 :
474 1 : CATCH_REQUIRE(regex_validator != nullptr);
475 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
476 :
477 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
478 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
479 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
480 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
481 :
482 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
483 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
484 : CATCH_END_SECTION()
485 :
486 12 : CATCH_START_SECTION("Verify invalid regex flags")
487 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag * in regular expression \"/contact@.*\\..*\".");
488 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
489 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
490 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag \\ in regular expression \"/contact@.*\\..*\".");
491 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag * in regular expression \"/contact@.*\\..*\".");
492 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
493 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag @ in regular expression \"/contact@.*\\..*\".");
494 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag t in regular expression \"/contact@.*\\..*\".");
495 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag c in regular expression \"/contact@.*\\..*\".");
496 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag a in regular expression \"/contact@.*\\..*\".");
497 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag t in regular expression \"/contact@.*\\..*\".");
498 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag n in regular expression \"/contact@.*\\..*\".");
499 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag o in regular expression \"/contact@.*\\..*\".");
500 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag c in regular expression \"/contact@.*\\..*\".");
501 1 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid regex definition, ending / is missing in \"/contact@.*\\..*\".");
502 :
503 2 : advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*"}));
504 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
505 :
506 1 : CATCH_REQUIRE(regex_validator != nullptr);
507 1 : CATCH_REQUIRE(regex_validator->name() == "regex");
508 :
509 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
510 1 : CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
511 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
512 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
513 :
514 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
515 1 : CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
516 : CATCH_END_SECTION()
517 :
518 12 : CATCH_START_SECTION("Verify regex refuses more than one parameter")
519 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
520 : "error: validator_regex() only supports one parameter;"
521 : " 2 were supplied;"
522 : " single or double quotation may be required?");
523 1 : advgetopt::validator::create("regex", {"[a-z]+", "[0-9]+"});
524 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
525 :
526 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
527 : "error: validator_regex() only supports one parameter;"
528 : " 2 were supplied;"
529 : " single or double quotation may be required?");
530 1 : advgetopt::validator::create("regex([a-z]+, [0-9]+)");
531 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
532 :
533 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
534 : "error: validator_regex() only supports one parameter;"
535 : " 3 were supplied;"
536 : " single or double quotation may be required?");
537 1 : advgetopt::validator::create("regex", {"[a-z]+", "[0-9]+", "[#!@]"});
538 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
539 :
540 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
541 : "error: validator_regex() only supports one parameter;"
542 : " 3 were supplied;"
543 : " single or double quotation may be required?");
544 1 : advgetopt::validator::create("regex(\"[a-z]+\", \"[0-9]+\", \"[#!@]\")");
545 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
546 : CATCH_END_SECTION()
547 :
548 12 : CATCH_START_SECTION("Verify missing ')' in string based create")
549 1 : CATCH_REQUIRE_THROWS_MATCHES(
550 : advgetopt::validator::create("integer(1...7")
551 : , advgetopt::getopt_logic_error
552 : , Catch::Matchers::ExceptionMessage(
553 : "getopt_logic_error: invalid validator parameter definition: \"integer(1...7\", the ')' is missing."));
554 :
555 1 : CATCH_REQUIRE_THROWS_MATCHES(
556 : advgetopt::validator::create("regex([a-z]+")
557 : , advgetopt::getopt_logic_error
558 : , Catch::Matchers::ExceptionMessage(
559 : "getopt_logic_error: invalid validator parameter definition: \"regex([a-z]+\", the ')' is missing."));
560 : CATCH_END_SECTION()
561 12 : }
562 :
563 :
564 : // vim: ts=4 sw=4 et
|