Directory: | ./ |
---|---|
File: | test/parse_numbers.c |
Date: | 2021-09-04 00:13:15 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 207 | 207 | 100.0% |
Branches: | 63 | 126 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /***************************************************************************/ /** | ||
2 | |||
3 | @file parse_numbers.c | ||
4 | |||
5 | @author Stephen Brennan | ||
6 | |||
7 | @date Created Tuesday, 24 November 2015 | ||
8 | |||
9 | @brief Test number parsing. | ||
10 | |||
11 | @copyright Copyright (c) 2015, Stephen Brennan. Released under the | ||
12 | Revised BSD License. See LICENSE.txt for details. | ||
13 | |||
14 | *******************************************************************************/ | ||
15 | |||
16 | #include <unity.h> | ||
17 | |||
18 | #include "nosj.h" | ||
19 | |||
20 | 19 | void setUp(void) | |
21 | { | ||
22 | // set stuff up here | ||
23 | 19 | } | |
24 | |||
25 | 19 | void tearDown(void) | |
26 | { | ||
27 | // clean stuff up here | ||
28 | 19 | } | |
29 | |||
30 | 1 | static void test_single_digit(void) | |
31 | 1 | { | |
32 | 1 | char input[] = "0"; | |
33 | 1 | size_t ntok = 1; | |
34 | 1 | struct json_token tokens[ntok]; | |
35 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
36 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
38 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
39 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 0.0); |
40 | 1 | } | |
41 | |||
42 | 1 | static void test_multiple_digit(void) | |
43 | 1 | { | |
44 | 1 | char input[] = "12"; | |
45 | 1 | size_t ntok = 1; | |
46 | 1 | struct json_token tokens[ntok]; | |
47 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
48 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
49 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
51 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 12.0); |
52 | 1 | } | |
53 | |||
54 | 1 | static void test_starts_with_zero(void) | |
55 | { | ||
56 | /* | ||
57 | It would be nicer if this input actually failed. But the way the | ||
58 | current state machine works is that if it receives incorrect while in | ||
59 | an accepting state, it accepts and leaves the next input to be parsed. | ||
60 | Unfortunately, this means that something like this will be accepted, | ||
61 | and the 1 will go unparsed. (TODO) In the future, I should address | ||
62 | the way this works (would produce nicer error messages), but for now | ||
63 | this is expected behavior. | ||
64 | */ | ||
65 | 1 | char input[] = "01"; | |
66 | 1 | struct json_parser p = json_parse(input, NULL, 0); | |
67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == 1); |
69 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == 1); // ONLY PARSED ONE CHARACTER |
70 | 1 | } | |
71 | |||
72 | 1 | static void test_decimal(void) | |
73 | 1 | { | |
74 | 1 | char input[] = "1.1"; | |
75 | 1 | size_t ntok = 1; | |
76 | 1 | struct json_token tokens[ntok]; | |
77 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
78 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
79 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
81 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1.1); |
82 | 1 | } | |
83 | |||
84 | 1 | static void test_zero_decimal(void) | |
85 | 1 | { | |
86 | 1 | char input[] = "0.1"; | |
87 | 1 | size_t ntok = 1; | |
88 | 1 | struct json_token tokens[ntok]; | |
89 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
90 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
92 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
93 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 0.1); |
94 | 1 | } | |
95 | |||
96 | 1 | static void test_negative_sign(void) | |
97 | 1 | { | |
98 | 1 | char input[] = "-1"; | |
99 | 1 | size_t ntok = 1; | |
100 | 1 | struct json_token tokens[ntok]; | |
101 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
105 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == -1.0); |
106 | 1 | } | |
107 | |||
108 | 1 | static void test_exponent_upper(void) | |
109 | 1 | { | |
110 | 1 | char input[] = "1E5"; | |
111 | 1 | size_t ntok = 1; | |
112 | 1 | struct json_token tokens[ntok]; | |
113 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
115 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
117 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1e5); |
118 | 1 | } | |
119 | |||
120 | 1 | static void test_exponent_lower(void) | |
121 | 1 | { | |
122 | 1 | char input[] = "1e5"; | |
123 | 1 | size_t ntok = 1; | |
124 | 1 | struct json_token tokens[ntok]; | |
125 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
126 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
127 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
128 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
129 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1e5); |
130 | 1 | } | |
131 | |||
132 | 1 | static void test_exponent_plus(void) | |
133 | 1 | { | |
134 | 1 | char input[] = "1e+5"; | |
135 | 1 | size_t ntok = 1; | |
136 | 1 | struct json_token tokens[ntok]; | |
137 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
138 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
141 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1e5); |
142 | 1 | } | |
143 | |||
144 | 1 | static void test_exponent_minus(void) | |
145 | 1 | { | |
146 | 1 | char input[] = "1e-5"; | |
147 | 1 | size_t ntok = 1; | |
148 | 1 | struct json_token tokens[ntok]; | |
149 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
151 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
152 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
153 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1e-5); |
154 | 1 | } | |
155 | |||
156 | 1 | static void test_sign_decimal_exponent(void) | |
157 | 1 | { | |
158 | 1 | char input[] = "-1.5e+5"; | |
159 | 1 | size_t ntok = 1; | |
160 | 1 | struct json_token tokens[ntok]; | |
161 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
163 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
164 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
165 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == -1.5e5); |
166 | 1 | } | |
167 | |||
168 | 1 | static void test_sign_alone(void) | |
169 | { | ||
170 | 1 | char input[] = "-"; | |
171 | 1 | struct json_parser p = json_parse(input, NULL, 0); | |
172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_INVALID_NUMBER); |
173 | 1 | } | |
174 | |||
175 | 1 | static void test_decimal_without_digits(void) | |
176 | { | ||
177 | 1 | char input[] = "1."; | |
178 | 1 | struct json_parser p = json_parse(input, NULL, 0); | |
179 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_INVALID_NUMBER); |
180 | 1 | } | |
181 | |||
182 | 1 | static void test_exponent_without_digits(void) | |
183 | { | ||
184 | 1 | char input[] = "1e"; | |
185 | 1 | struct json_parser p = json_parse(input, NULL, 0); | |
186 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_INVALID_NUMBER); |
187 | 1 | } | |
188 | |||
189 | 1 | static void test_exponent_sign_without_digits(void) | |
190 | { | ||
191 | 1 | char input[] = "1e+"; | |
192 | 1 | struct json_parser p = json_parse(input, NULL, 0); | |
193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_INVALID_NUMBER); |
194 | 1 | } | |
195 | |||
196 | 1 | static void test_negative_zero(void) | |
197 | 1 | { | |
198 | 1 | char input[] = "-0"; // believe it or not, this is valid JSON. | |
199 | 1 | size_t ntok = 1; | |
200 | 1 | struct json_token tokens[ntok]; | |
201 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
202 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
203 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
204 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
205 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 0.0); |
206 | 1 | } | |
207 | |||
208 | 1 | static void test_zero_exp(void) | |
209 | 1 | { | |
210 | 1 | char input[] = "0e5"; // again, doesn't make sense, but is valid | |
211 | 1 | size_t ntok = 1; | |
212 | 1 | struct json_token tokens[ntok]; | |
213 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
214 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
215 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
216 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
217 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 0.0); |
218 | 1 | } | |
219 | |||
220 | 1 | static void test_double_digit_decimal(void) | |
221 | 1 | { | |
222 | 1 | char input[] = "1.23"; | |
223 | 1 | size_t ntok = 1; | |
224 | 1 | struct json_token tokens[ntok]; | |
225 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
226 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
227 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
228 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
229 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1.23); |
230 | 1 | } | |
231 | |||
232 | 1 | static void test_double_digit_exp(void) | |
233 | 1 | { | |
234 | 1 | char input[] = "1e23"; | |
235 | 1 | size_t ntok = 1; | |
236 | 1 | struct json_token tokens[ntok]; | |
237 | 1 | struct json_parser p = json_parse(input, tokens, ntok); | |
238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.error == JSONERR_NO_ERROR); |
239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.tokenidx == ntok); |
240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | TEST_ASSERT(p.textidx == sizeof(input) / sizeof(char) - 1); |
241 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | TEST_ASSERT(json_number_get(input, tokens, 0) == 1e23); |
242 | 1 | } | |
243 | |||
244 | 1 | int main(void) | |
245 | { | ||
246 | 1 | UNITY_BEGIN(); | |
247 | |||
248 | 1 | RUN_TEST(test_single_digit); | |
249 | 1 | RUN_TEST(test_multiple_digit); | |
250 | 1 | RUN_TEST(test_starts_with_zero); | |
251 | 1 | RUN_TEST(test_decimal); | |
252 | 1 | RUN_TEST(test_zero_decimal); | |
253 | 1 | RUN_TEST(test_negative_sign); | |
254 | 1 | RUN_TEST(test_exponent_upper); | |
255 | 1 | RUN_TEST(test_exponent_lower); | |
256 | 1 | RUN_TEST(test_exponent_plus); | |
257 | 1 | RUN_TEST(test_exponent_minus); | |
258 | 1 | RUN_TEST(test_sign_decimal_exponent); | |
259 | 1 | RUN_TEST(test_sign_alone); | |
260 | 1 | RUN_TEST(test_decimal_without_digits); | |
261 | 1 | RUN_TEST(test_exponent_without_digits); | |
262 | 1 | RUN_TEST(test_exponent_sign_without_digits); | |
263 | 1 | RUN_TEST(test_negative_zero); | |
264 | 1 | RUN_TEST(test_zero_exp); | |
265 | 1 | RUN_TEST(test_double_digit_decimal); | |
266 | 1 | RUN_TEST(test_double_digit_exp); | |
267 | |||
268 | 1 | return UNITY_END(); | |
269 | } | ||
270 |