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 : 25 : check_read(const char* const string,
18 : : const ExessStatus expected_status,
19 : : const int16_t expected_value,
20 : : const size_t expected_count)
21 : : {
22 : 25 : int16_t value = 0;
23 : :
24 : 25 : const ExessResult r = exess_read_short(string, &value);
25 [ - + ]: 25 : assert(value == expected_value);
26 [ - + ]: 25 : assert(r.status == expected_status);
27 [ - + ]: 25 : assert(r.count == expected_count);
28 : 25 : }
29 : :
30 : : static void
31 : 5 : test_read_short(void)
32 : : {
33 : : // Limits
34 : 5 : check_read("-32768", EXESS_SUCCESS, INT16_MIN, EXESS_MAX_SHORT_LENGTH);
35 : 5 : check_read("32767", EXESS_SUCCESS, INT16_MAX, 5);
36 : :
37 : : // Out of range
38 : 5 : check_read("-32769", EXESS_OUT_OF_RANGE, 0, 6);
39 : 5 : check_read("32768", EXESS_OUT_OF_RANGE, 0, 5);
40 : :
41 : : // Garbage
42 : 5 : check_read("+", EXESS_EXPECTED_DIGIT, 0, 1);
43 : 5 : }
44 : :
45 : : static void
46 : 15 : check_write(const int16_t value,
47 : : const ExessStatus expected_status,
48 : : const size_t buf_size,
49 : : const char* const expected_string)
50 : : {
51 : 15 : char buf[EXESS_MAX_SHORT_LENGTH + 1] = {1, 2, 3, 4, 5, 6};
52 : :
53 [ - + ]: 15 : assert(buf_size <= sizeof(buf));
54 : :
55 : 15 : const ExessResult r = exess_write_short(value, buf_size, buf);
56 [ - + ]: 15 : assert(r.status == expected_status);
57 [ + + ]: 15 : if (!r.status) {
58 [ - + ]: 10 : assert(!strcmp(buf, expected_string));
59 [ - + ]: 10 : assert(r.count == strlen(buf));
60 [ + - - + ]: 10 : assert(r.status || exess_write_short(value, 0, NULL).count == r.count);
61 : : }
62 : 15 : }
63 : :
64 : : static void
65 : 5 : test_write_short(void)
66 : : {
67 : 5 : check_write(INT16_MIN, EXESS_SUCCESS, 7, "-32768");
68 : 5 : check_write(INT16_MAX, EXESS_SUCCESS, 6, "32767");
69 : 5 : check_write(INT16_MAX, EXESS_NO_SPACE, 5, "32767");
70 : 5 : }
71 : :
72 : : static void
73 : 5 : test_round_trip(const ExessNumTestOptions opts)
74 : : {
75 : 5 : int16_t parsed_value = 0;
76 : 5 : char buf[EXESS_MAX_SHORT_LENGTH + 1] = {1, 2, 3, 4, 5, 6};
77 : :
78 [ + + ]: 5 : if (opts.exhaustive) {
79 : 2 : fprintf(stderr, "Testing xsd:short exhaustively\n");
80 : :
81 [ + + ]: 65650 : for (int64_t i = opts.low; i <= opts.high; ++i) {
82 [ - + ]: 65648 : assert(!exess_write_short((int16_t)i, sizeof(buf), buf).status);
83 [ - + ]: 65648 : assert(!exess_read_short(buf, &parsed_value).status);
84 [ - + ]: 65648 : assert(parsed_value == i);
85 : : }
86 : : } else {
87 : 3 : fprintf(stderr, "Testing xsd:short randomly with seed %u\n", opts.seed);
88 : :
89 : 3 : uint32_t seed = opts.seed;
90 [ + + ]: 33795 : for (uint64_t i = 0; i < opts.n_tests; ++i) {
91 : 33792 : seed = lcg32(seed);
92 : :
93 : 33792 : const int16_t value = (int16_t)(seed % INT16_MAX);
94 : :
95 [ - + ]: 33792 : assert(!exess_write_short(value, sizeof(buf), buf).status);
96 [ - + ]: 33792 : assert(!exess_read_short(buf, &parsed_value).status);
97 [ - + ]: 33792 : assert(parsed_value == value);
98 : :
99 : 33792 : print_num_test_progress(i, opts.n_tests);
100 : : }
101 : : }
102 : 5 : }
103 : :
104 : : int
105 : 10 : main(int argc, char** argv)
106 : : {
107 : : const ExessNumTestOptions opts =
108 : 10 : parse_num_test_options(argc, argv, 16384U, INT16_MIN, INT16_MAX);
109 : :
110 [ + + ]: 10 : if (!opts.error) {
111 : 5 : test_read_short();
112 : 5 : test_write_short();
113 : 5 : test_round_trip(opts);
114 : : }
115 : :
116 : 10 : return (int)opts.error;
117 : : }
|