Line data Source code
1 : // Copyright (c) 2023 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/versiontheca
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 3 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
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // tested file
20 : //
21 : #include "versiontheca/part.h"
22 :
23 :
24 : // self
25 : //
26 : #include "catch_main.h"
27 :
28 :
29 :
30 : // versiontheca
31 : //
32 : #include "versiontheca/exception.h"
33 : #include "versiontheca/versiontheca.h"
34 :
35 :
36 : // C++
37 : //
38 : #include <cstring>
39 : #include <iomanip>
40 : #include <stdexcept>
41 :
42 :
43 :
44 :
45 : namespace
46 : {
47 :
48 :
49 100 : bool is_number(std::string value)
50 : {
51 100 : for(auto const c : value)
52 : {
53 100 : if(c < '0' || c > '9')
54 : {
55 100 : return false;
56 : }
57 : }
58 :
59 0 : return !value.empty();
60 : }
61 :
62 :
63 :
64 : }
65 : // no name namespace
66 :
67 :
68 8 : CATCH_TEST_CASE("part_integer", "[part][integer][valid]")
69 : {
70 12 : CATCH_START_SECTION("part_integer: verify default part")
71 : {
72 2 : versiontheca::part p;
73 :
74 1 : CATCH_REQUIRE(p.get_separator() == U'\0');
75 1 : CATCH_REQUIRE(p.get_width() == 0);
76 1 : CATCH_REQUIRE(p.get_type() == '\0');
77 1 : CATCH_REQUIRE(p.is_integer());
78 : //CATCH_REQUIRE(p.get_string()); -- would throw
79 1 : CATCH_REQUIRE(p.get_integer() == 0);
80 1 : CATCH_REQUIRE(p.to_string() == "0");
81 1 : CATCH_REQUIRE(p.get_last_error().empty());
82 1 : CATCH_REQUIRE(p.is_zero());
83 :
84 1 : CATCH_REQUIRE(p.next());
85 1 : CATCH_REQUIRE(p.get_integer() == 1);
86 : }
87 : CATCH_END_SECTION()
88 :
89 12 : CATCH_START_SECTION("part_integer: set_value(\"\") sets the value to integer 0")
90 : {
91 2 : versiontheca::part p;
92 :
93 1 : p.set_value(std::string());
94 :
95 1 : CATCH_REQUIRE(p.get_separator() == U'\0');
96 1 : CATCH_REQUIRE(p.get_width() == 0);
97 1 : CATCH_REQUIRE(p.get_type() == '\0');
98 1 : CATCH_REQUIRE(p.is_integer());
99 : //CATCH_REQUIRE(p.get_string()); -- would throw
100 1 : CATCH_REQUIRE(p.get_integer() == 0);
101 1 : CATCH_REQUIRE(p.to_string() == "0");
102 1 : CATCH_REQUIRE(p.get_last_error().empty());
103 1 : CATCH_REQUIRE(p.is_zero());
104 : }
105 : CATCH_END_SECTION()
106 :
107 12 : CATCH_START_SECTION("part_integer: random integers, using set_integer()")
108 : {
109 101 : for(int i(0); i < 100; ++i)
110 : {
111 200 : versiontheca::part p;
112 :
113 100 : versiontheca::part_integer_t value;
114 100 : SNAP_CATCH2_NAMESPACE::random(value);
115 100 : p.set_integer(value);
116 :
117 100 : CATCH_REQUIRE(p.get_separator() == U'\0');
118 100 : CATCH_REQUIRE(p.get_width() == 0);
119 100 : CATCH_REQUIRE(p.get_type() == '\0');
120 100 : CATCH_REQUIRE(p.is_integer());
121 : //CATCH_REQUIRE(p.get_string() == value); -- would throw
122 100 : CATCH_REQUIRE(p.get_integer() == value);
123 200 : std::stringstream ss;
124 100 : ss << value;
125 100 : CATCH_REQUIRE(p.to_string() == ss.str());
126 100 : CATCH_REQUIRE(p.get_last_error().empty());
127 100 : if(value == 0)
128 : {
129 0 : CATCH_REQUIRE(p.is_zero());
130 : }
131 : else
132 : {
133 100 : CATCH_REQUIRE_FALSE(p.is_zero());
134 : }
135 : }
136 : }
137 : CATCH_END_SECTION()
138 :
139 12 : CATCH_START_SECTION("part_integer: random integers from string, using set_value()")
140 : {
141 101 : for(int i(0); i < 100; ++i)
142 : {
143 200 : versiontheca::part p;
144 :
145 100 : versiontheca::part_integer_t value;
146 100 : SNAP_CATCH2_NAMESPACE::random(value);
147 200 : std::stringstream ss;
148 100 : ss << value;
149 100 : p.set_value(ss.str());
150 :
151 100 : CATCH_REQUIRE(p.get_separator() == U'\0');
152 100 : CATCH_REQUIRE(p.get_width() == 0);
153 100 : CATCH_REQUIRE(p.get_type() == '\0');
154 100 : CATCH_REQUIRE(p.is_integer());
155 : //CATCH_REQUIRE(p.get_string() == value); -- would throw
156 100 : CATCH_REQUIRE(p.get_integer() == value);
157 100 : CATCH_REQUIRE(p.to_string() == ss.str());
158 100 : CATCH_REQUIRE(p.get_last_error().empty());
159 100 : if(value == 0)
160 : {
161 0 : CATCH_REQUIRE(p.is_zero());
162 : }
163 : else
164 : {
165 100 : CATCH_REQUIRE_FALSE(p.is_zero());
166 : }
167 : }
168 : }
169 : CATCH_END_SECTION()
170 :
171 12 : CATCH_START_SECTION("part_integer: check minimum integer")
172 : {
173 2 : versiontheca::part p;
174 1 : p.set_integer(0);
175 1 : CATCH_REQUIRE(p.is_integer());
176 1 : CATCH_REQUIRE(p.get_integer() == 0U);
177 :
178 1 : CATCH_REQUIRE_FALSE(p.previous());
179 1 : CATCH_REQUIRE(p.get_integer() == 0U);
180 : }
181 : CATCH_END_SECTION()
182 :
183 12 : CATCH_START_SECTION("part_integer: check maximum integer")
184 : {
185 2 : versiontheca::part p;
186 1 : p.set_to_max_integer();
187 1 : CATCH_REQUIRE(p.is_integer());
188 1 : CATCH_REQUIRE(p.get_integer() == std::numeric_limits<versiontheca::part_integer_t>::max());
189 :
190 1 : CATCH_REQUIRE_FALSE(p.next());
191 1 : CATCH_REQUIRE(p.get_integer() == std::numeric_limits<versiontheca::part_integer_t>::max());
192 : }
193 : CATCH_END_SECTION()
194 6 : }
195 :
196 :
197 10 : CATCH_TEST_CASE("part_string", "[part][integer][valid]")
198 : {
199 16 : CATCH_START_SECTION("part_string: strings of digits, using set_string()")
200 : {
201 101 : for(int i(0); i < 100; ++i)
202 : {
203 200 : versiontheca::part p;
204 :
205 100 : versiontheca::part_integer_t number;
206 100 : SNAP_CATCH2_NAMESPACE::random(number);
207 200 : std::stringstream ss;
208 100 : ss << number;
209 100 : p.set_string(ss.str());
210 :
211 100 : CATCH_REQUIRE(p.get_separator() == U'\0');
212 100 : CATCH_REQUIRE(p.get_width() == 0);
213 100 : CATCH_REQUIRE(p.get_type() == '\0');
214 100 : CATCH_REQUIRE_FALSE(p.is_integer());
215 100 : CATCH_REQUIRE(p.get_string() == ss.str());
216 : //CATCH_REQUIRE(p.get_integer() == value); -- would throw
217 100 : CATCH_REQUIRE(p.to_string() == ss.str());
218 100 : CATCH_REQUIRE(p.get_last_error().empty());
219 100 : CATCH_REQUIRE_FALSE(p.is_zero());
220 : }
221 : }
222 : CATCH_END_SECTION()
223 :
224 16 : CATCH_START_SECTION("part_string: random strings, using set_string()")
225 : {
226 101 : for(int i(0); i < 100; ++i)
227 : {
228 200 : versiontheca::part p;
229 :
230 200 : std::string value;
231 100 : value = SNAP_CATCH2_NAMESPACE::random_string(1, 25, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_UNICODE);
232 100 : p.set_string(value);
233 :
234 100 : CATCH_REQUIRE(p.get_separator() == U'\0');
235 100 : CATCH_REQUIRE(p.get_width() == 0);
236 100 : CATCH_REQUIRE(p.get_type() == '\0');
237 100 : CATCH_REQUIRE_FALSE(p.is_integer());
238 100 : CATCH_REQUIRE(p.get_string() == value);
239 : //CATCH_REQUIRE(p.get_integer() == value); -- would throw
240 100 : CATCH_REQUIRE(p.to_string() == value);
241 100 : CATCH_REQUIRE(p.get_last_error().empty());
242 100 : CATCH_REQUIRE_FALSE(p.is_zero());
243 : }
244 : }
245 : CATCH_END_SECTION()
246 :
247 16 : CATCH_START_SECTION("part_string: random strings, using set_value()")
248 : {
249 101 : for(int i(0); i < 100; ++i)
250 : {
251 200 : versiontheca::part p;
252 :
253 200 : std::string value;
254 0 : do
255 : {
256 100 : value = SNAP_CATCH2_NAMESPACE::random_string(1, 25, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_UNICODE);
257 : }
258 100 : while(is_number(value));
259 100 : p.set_value(value);
260 :
261 100 : CATCH_REQUIRE(p.get_separator() == U'\0');
262 100 : CATCH_REQUIRE(p.get_width() == 0);
263 100 : CATCH_REQUIRE(p.get_type() == '\0');
264 100 : CATCH_REQUIRE_FALSE(p.is_integer());
265 100 : CATCH_REQUIRE(p.get_string() == value);
266 : //CATCH_REQUIRE(p.get_integer() == value); -- would throw
267 100 : CATCH_REQUIRE(p.to_string() == value);
268 100 : CATCH_REQUIRE(p.get_last_error().empty());
269 100 : CATCH_REQUIRE_FALSE(p.is_zero());
270 : }
271 : }
272 : CATCH_END_SECTION()
273 :
274 16 : CATCH_START_SECTION("part_string: check maximum string")
275 : {
276 11 : for(int sz(1); sz <= 10; ++sz)
277 : {
278 20 : versiontheca::part p;
279 10 : p.set_to_max_string(sz);
280 10 : CATCH_REQUIRE_FALSE(p.is_integer());
281 20 : std::string expected;
282 10 : expected.reserve(sz);
283 65 : for(int i(0); i < sz; ++i)
284 : {
285 55 : expected += 'z';
286 : }
287 10 : CATCH_REQUIRE(p.get_string() == expected);
288 : }
289 : }
290 : CATCH_END_SECTION()
291 :
292 16 : CATCH_START_SECTION("part_string: next on two letters up to max.")
293 : {
294 1 : char buf[3] = { 'A', 'A', '\0' };
295 2 : versiontheca::part p;
296 1 : p.set_value(buf);
297 1 : CATCH_REQUIRE_FALSE(p.is_integer());
298 1 : CATCH_REQUIRE(p.get_string() == buf);
299 52 : for(int j(0); j < 51; ++j)
300 : {
301 1326 : for(int i(0); i < 25; ++i) // AA to AZ
302 : {
303 1275 : CATCH_REQUIRE(p.next());
304 1275 : ++buf[1];
305 1275 : CATCH_REQUIRE(p.get_string() == buf);
306 : }
307 51 : CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
308 51 : buf[1] = 'a';
309 51 : CATCH_REQUIRE(p.get_string() == buf);
310 1326 : for(int i(0); i < 25; ++i)
311 : {
312 1275 : CATCH_REQUIRE(p.next());
313 1275 : ++buf[1];
314 1275 : CATCH_REQUIRE(p.get_string() == buf);
315 : }
316 51 : CATCH_REQUIRE(p.next()); // z + 1 = 'A' + carry
317 51 : if(buf[0] == 'Z')
318 : {
319 1 : buf[0] = 'a';
320 : }
321 : else
322 : {
323 50 : ++buf[0];
324 : }
325 51 : buf[1] = 'A';
326 51 : CATCH_REQUIRE(p.get_string() == buf);
327 : }
328 :
329 : // one more time on the lower character
330 : //
331 26 : for(int i(0); i < 25; ++i) // AA to AZ
332 : {
333 25 : CATCH_REQUIRE(p.next());
334 25 : ++buf[1];
335 25 : CATCH_REQUIRE(p.get_string() == buf);
336 : }
337 1 : CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
338 1 : buf[1] = 'a';
339 1 : CATCH_REQUIRE(p.get_string() == buf);
340 26 : for(int i(0); i < 25; ++i)
341 : {
342 25 : CATCH_REQUIRE(p.next());
343 25 : ++buf[1];
344 25 : CATCH_REQUIRE(p.get_string() == buf);
345 : }
346 1 : CATCH_REQUIRE_FALSE(p.next());
347 1 : CATCH_REQUIRE(p.get_string() == buf);
348 : }
349 : CATCH_END_SECTION()
350 :
351 16 : CATCH_START_SECTION("part_string: next on two letters separated by + up to max.")
352 : {
353 1 : char buf[4] = { 'A', '+', 'A', '\0' };
354 2 : versiontheca::part p;
355 1 : p.set_value(buf);
356 1 : CATCH_REQUIRE_FALSE(p.is_integer());
357 1 : CATCH_REQUIRE(p.get_string() == buf);
358 52 : for(int j(0); j < 51; ++j)
359 : {
360 1326 : for(int i(0); i < 25; ++i)
361 : {
362 1275 : CATCH_REQUIRE(p.next());
363 1275 : ++buf[2];
364 1275 : CATCH_REQUIRE(p.get_string() == buf);
365 : }
366 51 : CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
367 51 : buf[2] = 'a';
368 51 : CATCH_REQUIRE(p.get_string() == buf);
369 1326 : for(int i(0); i < 25; ++i)
370 : {
371 1275 : CATCH_REQUIRE(p.next());
372 1275 : ++buf[2];
373 1275 : CATCH_REQUIRE(p.get_string() == buf);
374 : }
375 51 : CATCH_REQUIRE(p.next()); // z + 1 = 'A' + carry
376 51 : if(buf[0] == 'Z')
377 : {
378 1 : buf[0] = 'a';
379 : }
380 : else
381 : {
382 50 : ++buf[0];
383 : }
384 51 : buf[2] = 'A';
385 51 : CATCH_REQUIRE(p.get_string() == buf);
386 : }
387 :
388 : // one more time on the lower character
389 : //
390 26 : for(int i(0); i < 25; ++i) // AA to AZ
391 : {
392 25 : CATCH_REQUIRE(p.next());
393 25 : ++buf[2];
394 25 : CATCH_REQUIRE(p.get_string() == buf);
395 : }
396 1 : CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
397 1 : buf[2] = 'a';
398 1 : CATCH_REQUIRE(p.get_string() == buf);
399 26 : for(int i(0); i < 25; ++i)
400 : {
401 25 : CATCH_REQUIRE(p.next());
402 25 : ++buf[2];
403 25 : CATCH_REQUIRE(p.get_string() == buf);
404 : }
405 1 : CATCH_REQUIRE_FALSE(p.next());
406 1 : CATCH_REQUIRE(p.get_string() == buf);
407 : }
408 : CATCH_END_SECTION()
409 :
410 16 : CATCH_START_SECTION("part_string: previous on two letters up to min.")
411 : {
412 1 : char buf[3] = { 'z', 'z', '\0' };
413 2 : versiontheca::part p;
414 1 : p.set_value(buf);
415 1 : CATCH_REQUIRE_FALSE(p.is_integer());
416 1 : CATCH_REQUIRE(p.get_string() == buf);
417 52 : for(int j(0); j < 51; ++j)
418 : {
419 1326 : for(int i(0); i < 25; ++i)
420 : {
421 1275 : CATCH_REQUIRE(p.previous());
422 1275 : --buf[1];
423 1275 : CATCH_REQUIRE(p.get_string() == buf);
424 : }
425 51 : CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
426 51 : buf[1] = 'Z';
427 51 : CATCH_REQUIRE(p.get_string() == buf);
428 1326 : for(int i(0); i < 25; ++i)
429 : {
430 1275 : CATCH_REQUIRE(p.previous());
431 1275 : --buf[1];
432 1275 : CATCH_REQUIRE(p.get_string() == buf);
433 : }
434 51 : CATCH_REQUIRE(p.previous()); // a - 1 = 'Z' + carry
435 51 : if(buf[0] == 'a')
436 : {
437 1 : buf[0] = 'Z';
438 : }
439 : else
440 : {
441 50 : --buf[0];
442 : }
443 51 : buf[1] = 'z';
444 51 : CATCH_REQUIRE(p.get_string() == buf);
445 : }
446 :
447 : // one more time on the lower character
448 : //
449 26 : for(int i(0); i < 25; ++i) // AA to AZ
450 : {
451 25 : CATCH_REQUIRE(p.previous());
452 25 : --buf[1];
453 25 : CATCH_REQUIRE(p.get_string() == buf);
454 : }
455 1 : CATCH_REQUIRE(p.previous()); // a + 1 = 'Z'
456 1 : buf[1] = 'Z';
457 1 : CATCH_REQUIRE(p.get_string() == buf);
458 26 : for(int i(0); i < 25; ++i)
459 : {
460 25 : CATCH_REQUIRE(p.previous());
461 25 : --buf[1];
462 25 : CATCH_REQUIRE(p.get_string() == buf);
463 : }
464 1 : CATCH_REQUIRE_FALSE(p.previous());
465 1 : CATCH_REQUIRE(p.get_string() == buf);
466 : }
467 : CATCH_END_SECTION()
468 :
469 16 : CATCH_START_SECTION("part_string: previous on two letters separated by + up to min.")
470 : {
471 1 : char buf[4] = { 'z', '+', 'z', '\0' };
472 2 : versiontheca::part p;
473 1 : p.set_value(buf);
474 1 : CATCH_REQUIRE_FALSE(p.is_integer());
475 1 : CATCH_REQUIRE(p.get_string() == buf);
476 52 : for(int j(0); j < 51; ++j)
477 : {
478 1326 : for(int i(0); i < 25; ++i)
479 : {
480 1275 : CATCH_REQUIRE(p.previous());
481 1275 : --buf[2];
482 1275 : CATCH_REQUIRE(p.get_string() == buf);
483 : }
484 51 : CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
485 51 : buf[2] = 'Z';
486 51 : CATCH_REQUIRE(p.get_string() == buf);
487 1326 : for(int i(0); i < 25; ++i)
488 : {
489 1275 : CATCH_REQUIRE(p.previous());
490 1275 : --buf[2];
491 1275 : CATCH_REQUIRE(p.get_string() == buf);
492 : }
493 51 : CATCH_REQUIRE(p.previous()); // a - 1 = 'Z' + carry
494 51 : if(buf[0] == 'a')
495 : {
496 1 : buf[0] = 'Z';
497 : }
498 : else
499 : {
500 50 : --buf[0];
501 : }
502 51 : buf[2] = 'z';
503 51 : CATCH_REQUIRE(p.get_string() == buf);
504 : }
505 :
506 : // one more time on the lower character
507 : //
508 26 : for(int i(0); i < 25; ++i) // AA to AZ
509 : {
510 25 : CATCH_REQUIRE(p.previous());
511 25 : --buf[2];
512 25 : CATCH_REQUIRE(p.get_string() == buf);
513 : }
514 1 : CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
515 1 : buf[2] = 'Z';
516 1 : CATCH_REQUIRE(p.get_string() == buf);
517 26 : for(int i(0); i < 25; ++i)
518 : {
519 25 : CATCH_REQUIRE(p.previous());
520 25 : --buf[2];
521 25 : CATCH_REQUIRE(p.get_string() == buf);
522 : }
523 1 : CATCH_REQUIRE_FALSE(p.previous());
524 1 : CATCH_REQUIRE(p.get_string() == buf);
525 : }
526 : CATCH_END_SECTION()
527 8 : }
528 :
529 :
530 5 : CATCH_TEST_CASE("part_compare", "[part][compare][valid]")
531 : {
532 6 : CATCH_START_SECTION("part_compare: integers")
533 : {
534 2 : versiontheca::part a;
535 2 : versiontheca::part b;
536 :
537 1 : CATCH_REQUIRE(a.compare(b) == 0);
538 1 : a.set_integer(10);
539 1 : CATCH_REQUIRE(a.compare(b) == 1);
540 1 : b.set_integer(253);
541 1 : CATCH_REQUIRE(a.compare(b) == -1);
542 : }
543 : CATCH_END_SECTION()
544 :
545 6 : CATCH_START_SECTION("part_compare: strings")
546 : {
547 2 : versiontheca::part a;
548 2 : versiontheca::part b;
549 :
550 1 : a.set_string("abc");
551 1 : b.set_string("xyz");
552 :
553 1 : CATCH_REQUIRE(a.compare(b) == -1);
554 1 : CATCH_REQUIRE(a.compare(a) == 0);
555 1 : CATCH_REQUIRE(b.compare(b) == 0);
556 1 : a.set_string("xyz~more");
557 1 : CATCH_REQUIRE(a.compare(b) == 1);
558 1 : b.set_string("xyz~more");
559 1 : CATCH_REQUIRE(a.compare(b) == 0);
560 : }
561 : CATCH_END_SECTION()
562 :
563 6 : CATCH_START_SECTION("part_compare: mix")
564 : {
565 2 : versiontheca::part a;
566 2 : versiontheca::part b;
567 :
568 1 : a.set_string("10");
569 1 : b.set_integer(2);
570 :
571 1 : CATCH_REQUIRE(a.compare(b) == -1); // 10 > 2 but as string "10" < "2"
572 1 : CATCH_REQUIRE(b.compare(a) == 1);
573 : }
574 : CATCH_END_SECTION()
575 3 : }
576 :
577 :
578 5 : CATCH_TEST_CASE("part_meta", "[part][valid]")
579 : {
580 6 : CATCH_START_SECTION("part_meta: separators")
581 : {
582 1114081 : for(char32_t sep(U' '); sep < 0x110000; ++sep)
583 : {
584 1116161 : if((sep >= 0x7F && sep <= 0x9F)
585 1114047 : || (sep >= 0xD800 && sep <= 0xDFFF))
586 : {
587 2081 : continue;
588 : }
589 2223998 : versiontheca::part p;
590 1111999 : p.set_separator(sep);
591 1111999 : CATCH_REQUIRE(p.get_separator() == sep);
592 :
593 : // we can always reset back to U'\0'
594 : //
595 1111999 : p.set_separator(U'\0');
596 1111999 : CATCH_REQUIRE(p.get_separator() == U'\0');
597 : }
598 : }
599 : CATCH_END_SECTION()
600 :
601 6 : CATCH_START_SECTION("part_meta: width")
602 : {
603 257 : for(int width(0); width < 256; ++width)
604 : {
605 512 : versiontheca::part p;
606 256 : CATCH_REQUIRE(p.get_width() == 0);
607 256 : p.set_width(width);
608 256 : CATCH_REQUIRE(p.get_width() == width);
609 : }
610 : }
611 : CATCH_END_SECTION()
612 :
613 6 : CATCH_START_SECTION("part_meta: type")
614 : {
615 257 : for(int type(0); type < 256; ++type)
616 : {
617 512 : versiontheca::part p;
618 256 : CATCH_REQUIRE(p.get_type() == '\0');
619 256 : p.set_type(type);
620 256 : CATCH_REQUIRE(p.get_type() == static_cast<char>(type));
621 : }
622 : }
623 : CATCH_END_SECTION()
624 3 : }
625 :
626 :
627 7 : CATCH_TEST_CASE("part_invalid", "[part][invalid]")
628 : {
629 10 : CATCH_START_SECTION("part_invalid: bad separators (controls)")
630 : {
631 32 : for(char32_t sep(U'\x01'); sep < U' '; ++sep)
632 : {
633 62 : versiontheca::part p;
634 31 : CATCH_REQUIRE_THROWS_MATCHES(
635 : p.set_separator(sep)
636 : , versiontheca::invalid_parameter
637 : , Catch::Matchers::ExceptionMessage(
638 : "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
639 : }
640 : }
641 : CATCH_END_SECTION()
642 :
643 10 : CATCH_START_SECTION("part_invalid: bad separators (graphical controls)")
644 : {
645 34 : for(char32_t sep(U'\x7F'); sep < U'\xA0'; ++sep)
646 : {
647 66 : versiontheca::part p;
648 33 : CATCH_REQUIRE_THROWS_MATCHES(
649 : p.set_separator(sep)
650 : , versiontheca::invalid_parameter
651 : , Catch::Matchers::ExceptionMessage(
652 : "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
653 : }
654 : }
655 : CATCH_END_SECTION()
656 :
657 10 : CATCH_START_SECTION("part_invalid: bad separators (surrogates)")
658 : {
659 2048 : for(char32_t sep(0XD800); sep < 0xDFFF; ++sep)
660 : {
661 4094 : versiontheca::part p;
662 2047 : CATCH_REQUIRE_THROWS_MATCHES(
663 : p.set_separator(sep)
664 : , versiontheca::invalid_parameter
665 : , Catch::Matchers::ExceptionMessage(
666 : "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
667 : }
668 : }
669 : CATCH_END_SECTION()
670 :
671 10 : CATCH_START_SECTION("part_invalid: get_string() when integer")
672 : {
673 2 : versiontheca::part p;
674 1 : CATCH_REQUIRE_THROWS_MATCHES(
675 : p.get_string()
676 : , versiontheca::wrong_type
677 : , Catch::Matchers::ExceptionMessage(
678 : "versiontheca_exception: this part is not a string."));
679 : }
680 : CATCH_END_SECTION()
681 :
682 10 : CATCH_START_SECTION("part_invalid: get_integer() when string")
683 : {
684 2 : versiontheca::part p;
685 1 : p.set_string("now this is a string");
686 1 : CATCH_REQUIRE_THROWS_MATCHES(
687 : p.get_integer()
688 : , versiontheca::wrong_type
689 : , Catch::Matchers::ExceptionMessage(
690 : "versiontheca_exception: this part is not an integer."));
691 : }
692 : CATCH_END_SECTION()
693 11 : }
694 :
695 :
696 :
697 : // vim: ts=4 sw=4 et
|