Branch data Line data Source code
1 : : // Copyright 2011-2025 David Robillard <d@drobilla.net>
2 : : // SPDX-License-Identifier: ISC
3 : :
4 : : #undef NDEBUG
5 : :
6 : : #include "int_test_utils.h"
7 : : #include "num_test_utils.h"
8 : :
9 : : #include <exess/exess.h>
10 : :
11 : : #include <assert.h>
12 : : #include <stdint.h>
13 : : #include <stdio.h>
14 : : #include <string.h>
15 : :
16 : : static void
17 : 12 : check_read(const char* const string,
18 : : const ExessStatus expected_status,
19 : : const int32_t expected_value,
20 : : const size_t expected_count)
21 : : {
22 : 12 : int32_t value = 0;
23 : 12 : const ExessResult r = exess_read_int(string, &value);
24 : :
25 [ - + ]: 12 : assert(r.status == expected_status);
26 [ - + ]: 12 : assert(r.count == expected_count);
27 [ - + ]: 12 : assert(value == expected_value);
28 : 12 : }
29 : :
30 : : static void
31 : 2 : test_read_int(void)
32 : : {
33 : : // Limits
34 : 2 : check_read("-2147483648", EXESS_SUCCESS, INT32_MIN, EXESS_MAX_INT_LENGTH);
35 : 2 : check_read("2147483647", EXESS_SUCCESS, INT32_MAX, 10);
36 : :
37 : : // Out of range
38 : 2 : check_read("-2147483649", EXESS_OUT_OF_RANGE, 0, 11);
39 : 2 : check_read("2147483648", EXESS_OUT_OF_RANGE, 0, 10);
40 : 2 : check_read("10000000000", EXESS_OUT_OF_RANGE, 0, 11);
41 : :
42 : : // Garbage
43 : 2 : check_read("+", EXESS_EXPECTED_DIGIT, 0, 1);
44 : 2 : }
45 : :
46 : : static void
47 : 6 : check_write(const int32_t value,
48 : : const ExessStatus expected_status,
49 : : const size_t buf_size,
50 : : const char* const expected_string)
51 : : {
52 : 6 : char buf[EXESS_MAX_INT_LENGTH + 1] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
53 : :
54 [ - + ]: 6 : assert(buf_size <= sizeof(buf));
55 : :
56 : 6 : const ExessResult r = exess_write_int(value, buf_size, buf);
57 [ - + ]: 6 : assert(r.status == expected_status);
58 [ + + ]: 6 : if (!r.status) {
59 [ - + ]: 4 : assert(!strcmp(buf, expected_string));
60 [ - + ]: 4 : assert(r.count == strlen(buf));
61 [ - + ]: 4 : assert(exess_write_int(value, 0, NULL).count == r.count);
62 : : }
63 : 6 : }
64 : :
65 : : static void
66 : 2 : test_write_int(void)
67 : : {
68 : 2 : check_write(INT32_MIN, EXESS_SUCCESS, 12, "-2147483648");
69 : 2 : check_write(INT32_MAX, EXESS_SUCCESS, 11, "2147483647");
70 : 2 : check_write(INT32_MAX, EXESS_NO_SPACE, 10, "2147483647");
71 : 2 : }
72 : :
73 : : static void
74 : 2 : test_round_trip(const ExessNumTestOptions opts)
75 : : {
76 : 2 : int32_t parsed_value = 0;
77 : 2 : char buf[EXESS_MAX_INT_LENGTH + 1] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
78 : :
79 [ + + ]: 2 : if (opts.exhaustive) {
80 : 1 : fprintf(stderr, "Testing xsd:int exhaustively\n");
81 : :
82 [ + + ]: 514 : for (int64_t i = opts.low; i <= opts.high; ++i) {
83 [ - + ]: 513 : assert(!exess_write_int((int32_t)i, sizeof(buf), buf).status);
84 [ - + ]: 513 : assert(!exess_read_int(buf, &parsed_value).status);
85 [ - + ]: 513 : assert(parsed_value == i);
86 : :
87 : 513 : print_num_test_progress((uint64_t)(i - opts.low), (uint64_t)opts.high);
88 : : }
89 : : } else {
90 : 1 : fprintf(stderr, "Testing xsd:int randomly with seed %u\n", opts.seed);
91 : 1 : uint32_t rep = opts.seed;
92 [ + + ]: 16385 : for (uint64_t i = 0; i < opts.n_tests; ++i) {
93 : 16384 : rep = lcg32(rep);
94 : :
95 : 16384 : const int32_t value = (int32_t)rep;
96 : :
97 [ - + ]: 16384 : assert(!exess_write_int(value, sizeof(buf), buf).status);
98 [ - + ]: 16384 : assert(!exess_read_int(buf, &parsed_value).status);
99 [ - + ]: 16384 : assert(parsed_value == value);
100 : :
101 : 16384 : print_num_test_progress(i, opts.n_tests);
102 : : }
103 : : }
104 : 2 : }
105 : :
106 : : int
107 : 2 : main(int argc, char** argv)
108 : : {
109 : : const ExessNumTestOptions opts =
110 : 2 : parse_num_test_options(argc, argv, 16384U, INT32_MIN, INT32_MAX);
111 : :
112 [ + - ]: 2 : if (!opts.error) {
113 : 2 : test_read_int();
114 : 2 : test_write_int();
115 : 2 : test_round_trip(opts);
116 : : }
117 : :
118 : 2 : return (int)opts.error;
119 : : }
|