blob: 96fcc05582162303641d3ee8b309aa0cabad694a [file] [log] [blame]
Radek Krejci50f0c6b2020-06-18 16:31:48 +02001/*
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_json.c
Radek Krejci50f0c6b2020-06-18 16:31:48 +02003 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for a generic JSON parser
5 *
6 * Copyright (c) 2020 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Radek Krejci50f0c6b2020-06-18 16:31:48 +020016
Radek Krejci50f0c6b2020-06-18 16:31:48 +020017#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020018#include "in_internal.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010019#include "json.h"
20#include "utests.h"
Radek Krejci50f0c6b2020-06-18 16:31:48 +020021
Radek Krejci50f0c6b2020-06-18 16:31:48 +020022static void
23test_general(void **state)
24{
25 struct lyjson_ctx *jsonctx;
26 struct ly_in *in;
27 const char *str;
28
Radek Krejci50f0c6b2020-06-18 16:31:48 +020029 /* empty */
30 str = "";
31 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020032 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020033 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
34 lyjson_ctx_free(jsonctx);
35
36 str = " \n\t \n";
37 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +020038 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020039 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
40 lyjson_ctx_free(jsonctx);
41
42 /* constant values */
43 str = "true";
44 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +020045 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020046 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
47 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
48 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
49 lyjson_ctx_free(jsonctx);
50
51 str = "false";
52 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +020053 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020054 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
55 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
56 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
57 lyjson_ctx_free(jsonctx);
58
59 str = "null";
60 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +020061 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020062 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
63 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
64 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
65 lyjson_ctx_free(jsonctx);
66
67 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +020068}
69
70static void
71test_number(void **state)
72{
73 struct lyjson_ctx *jsonctx;
74 struct ly_in *in;
75 const char *str;
76
Radek Krejci50f0c6b2020-06-18 16:31:48 +020077 /* simple value */
78 str = "11";
79 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020080 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020081 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
82 assert_string_equal("11", jsonctx->value);
83 assert_int_equal(2, jsonctx->value_len);
84 assert_int_equal(0, jsonctx->dynamic);
85 lyjson_ctx_free(jsonctx);
86
87 /* fraction number */
88 str = "37.7668";
89 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +020090 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +020091 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
92 assert_string_equal("37.7668", jsonctx->value);
93 assert_int_equal(7, jsonctx->value_len);
94 assert_int_equal(0, jsonctx->dynamic);
95 lyjson_ctx_free(jsonctx);
96
97 /* negative number */
98 str = "-122.3959";
99 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200100 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200101 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
102 assert_string_equal("-122.3959", jsonctx->value);
103 assert_int_equal(9, jsonctx->value_len);
104 assert_int_equal(0, jsonctx->dynamic);
105 lyjson_ctx_free(jsonctx);
106
aPieceka40b4662021-05-13 15:47:03 +0200107 str = "-0";
108 assert_non_null(ly_in_memory(in, str));
109 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
110 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
111 assert_string_equal("-0", jsonctx->value);
112 assert_int_equal(2, jsonctx->value_len);
113 assert_int_equal(0, jsonctx->dynamic);
114 lyjson_ctx_free(jsonctx);
115
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200116 /* exp number */
117 str = "1E10";
118 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200119 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200120 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
121 assert_string_equal("10000000000", jsonctx->value);
122 assert_int_equal(11, jsonctx->value_len);
123 assert_int_equal(1, jsonctx->dynamic);
124 lyjson_ctx_free(jsonctx);
125
126 str = "15E-1";
127 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200128 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200129 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
130 assert_string_equal("1.5", jsonctx->value);
131 assert_int_equal(3, jsonctx->value_len);
132 assert_int_equal(1, jsonctx->dynamic);
133 lyjson_ctx_free(jsonctx);
134
135 str = "15E-3";
136 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200137 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200138 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
139 assert_string_equal("0.015", jsonctx->value);
140 assert_int_equal(5, jsonctx->value_len);
141 assert_int_equal(1, jsonctx->dynamic);
142 lyjson_ctx_free(jsonctx);
143
aPiecek94927eb2021-05-05 12:36:50 +0200144 str = "1E1000";
145 assert_non_null(ly_in_memory(in, str));
146 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
147
aPieceka40b4662021-05-13 15:47:03 +0200148 str = "0E0";
149 assert_non_null(ly_in_memory(in, str));
150 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
151 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
152 assert_string_equal("0", jsonctx->value);
153 assert_int_equal(1, jsonctx->value_len);
154 assert_int_equal(1, jsonctx->dynamic);
155 lyjson_ctx_free(jsonctx);
156
157 str = "0E-0";
158 assert_non_null(ly_in_memory(in, str));
159 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
160 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
161 assert_string_equal("0", jsonctx->value);
162 assert_int_equal(1, jsonctx->value_len);
163 assert_int_equal(1, jsonctx->dynamic);
164 lyjson_ctx_free(jsonctx);
165
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200166 /* exp fraction number */
167 str = "1.1e3";
168 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200169 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200170 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
171 assert_string_equal("1100", jsonctx->value);
172 assert_int_equal(4, jsonctx->value_len);
173 assert_int_equal(1, jsonctx->dynamic);
174 lyjson_ctx_free(jsonctx);
175
aPiecek58e46a52021-05-05 10:04:47 +0200176 str = "12.1e3";
177 assert_non_null(ly_in_memory(in, str));
178 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
179 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
180 assert_string_equal("12100", jsonctx->value);
181 assert_int_equal(5, jsonctx->value_len);
182 assert_int_equal(1, jsonctx->dynamic);
183 lyjson_ctx_free(jsonctx);
184
aPieceka40b4662021-05-13 15:47:03 +0200185 str = "0.0e0";
186 assert_non_null(ly_in_memory(in, str));
187 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
188 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
189 assert_string_equal("0.0", jsonctx->value);
190 assert_int_equal(3, jsonctx->value_len);
191 assert_int_equal(1, jsonctx->dynamic);
192 lyjson_ctx_free(jsonctx);
193
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200194 /* negative exp fraction number */
195 str = "1.1e-3";
196 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200197 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200198 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
199 assert_string_equal("0.0011", jsonctx->value);
200 assert_int_equal(6, jsonctx->value_len);
201 assert_int_equal(1, jsonctx->dynamic);
202 lyjson_ctx_free(jsonctx);
203
aPiecek58e46a52021-05-05 10:04:47 +0200204 str = "12.4e-3";
205 assert_non_null(ly_in_memory(in, str));
206 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
207 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
208 assert_string_equal("0.0124", jsonctx->value);
209 assert_int_equal(6, jsonctx->value_len);
210 assert_int_equal(1, jsonctx->dynamic);
211 lyjson_ctx_free(jsonctx);
212
213 str = "12.4e-2";
214 assert_non_null(ly_in_memory(in, str));
215 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
216 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
217 assert_string_equal("0.124", jsonctx->value);
218 assert_int_equal(5, jsonctx->value_len);
219 assert_int_equal(1, jsonctx->dynamic);
220 lyjson_ctx_free(jsonctx);
221
aPieceka40b4662021-05-13 15:47:03 +0200222 str = "0.0e-0";
223 assert_non_null(ly_in_memory(in, str));
224 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
225 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
226 assert_string_equal("0.0", jsonctx->value);
227 assert_int_equal(3, jsonctx->value_len);
228 assert_int_equal(1, jsonctx->dynamic);
229 lyjson_ctx_free(jsonctx);
230
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200231 /* exp negative fraction number */
232 str = "-0.11e3";
233 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200234 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200235 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
236 assert_string_equal("-110", jsonctx->value);
237 assert_int_equal(4, jsonctx->value_len);
238 assert_int_equal(1, jsonctx->dynamic);
239 lyjson_ctx_free(jsonctx);
240
aPiecek58e46a52021-05-05 10:04:47 +0200241 str = "-44.11e3";
242 assert_non_null(ly_in_memory(in, str));
243 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
244 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
245 assert_string_equal("-44110", jsonctx->value);
246 assert_int_equal(6, jsonctx->value_len);
247 assert_int_equal(1, jsonctx->dynamic);
248 lyjson_ctx_free(jsonctx);
249
aPieceka40b4662021-05-13 15:47:03 +0200250 str = "-0.0e0";
251 assert_non_null(ly_in_memory(in, str));
252 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
253 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
254 assert_string_equal("-0.0", jsonctx->value);
255 assert_int_equal(4, jsonctx->value_len);
256 assert_int_equal(1, jsonctx->dynamic);
257 lyjson_ctx_free(jsonctx);
258
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200259 /* negative exp negative fraction number */
260 str = "-3.14e-3";
261 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200262 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200263 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
264 assert_string_equal("-0.00314", jsonctx->value);
265 assert_int_equal(8, jsonctx->value_len);
266 assert_int_equal(1, jsonctx->dynamic);
267 lyjson_ctx_free(jsonctx);
268
aPiecek58e46a52021-05-05 10:04:47 +0200269 str = "-98.7e-3";
270 assert_non_null(ly_in_memory(in, str));
271 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
272 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
273 assert_string_equal("-0.0987", jsonctx->value);
274 assert_int_equal(7, jsonctx->value_len);
275 assert_int_equal(1, jsonctx->dynamic);
276 lyjson_ctx_free(jsonctx);
277
278 str = "-98.7e-2";
279 assert_non_null(ly_in_memory(in, str));
280 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
281 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
282 assert_string_equal("-0.987", jsonctx->value);
283 assert_int_equal(6, jsonctx->value_len);
284 assert_int_equal(1, jsonctx->dynamic);
285 lyjson_ctx_free(jsonctx);
286
aPieceka40b4662021-05-13 15:47:03 +0200287 str = "-0.0e-0";
288 assert_non_null(ly_in_memory(in, str));
289 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
290 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
291 assert_string_equal("-0.0", jsonctx->value);
292 assert_int_equal(4, jsonctx->value_len);
293 assert_int_equal(1, jsonctx->dynamic);
294 lyjson_ctx_free(jsonctx);
295
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200296 /* various invalid inputs */
297 str = "-x";
298 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200299 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
300 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200301
302 str = " -";
303 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200304 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
305 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200306
307 str = "--1";
308 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200309 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
310 CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200311
312 str = "+1";
313 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200314 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
315 CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200316
317 str = " 1.x ";
318 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200319 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
320 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200321
322 str = "1.";
323 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200324 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
325 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200326
327 str = " 1eo ";
328 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200329 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
330 CHECK_LOG_CTX("Invalid character in JSON Number value (\"o\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200331
332 str = "1e";
333 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200334 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
335 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200336
337 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200338}
339
Radek Iša447abb82021-03-04 14:08:56 +0100340/* now string is tested in file ./tests/utests/types/string.c */
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200341static void
342test_string(void **state)
343{
344 struct lyjson_ctx *jsonctx;
Radek Iša447abb82021-03-04 14:08:56 +0100345 struct ly_in *in = NULL;
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200346 const char *str;
347
Radek Iša447abb82021-03-04 14:08:56 +0100348 str = "";
349 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
350
351#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200352 /* simple string */
353 str = "\"hello\"";
Radek Iša56ca9e42020-09-08 18:42:00 +0200354 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200355 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
356 assert_ptr_equal(&str[1], jsonctx->value);
357 assert_int_equal(5, jsonctx->value_len);
358 assert_int_equal(0, jsonctx->dynamic);
359 lyjson_ctx_free(jsonctx);
360
361 /* 4-byte utf8 character */
362 str = "\"\\t𠜎\"";
363 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200364 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200365 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
366 assert_string_equal("\t𠜎", jsonctx->value);
367 assert_int_equal(5, jsonctx->value_len);
368 assert_int_equal(1, jsonctx->dynamic);
369 lyjson_ctx_free(jsonctx);
370
371 /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and
372 * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string,
373 * the YANG string type's restrictions apply to the JSON escape sequences */
374 str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\"";
375 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200376 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200377 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
378 assert_string_equal("\" \\ \r / \n \t €", jsonctx->value);
379 assert_int_equal(15, jsonctx->value_len);
380 assert_int_equal(1, jsonctx->dynamic);
381 lyjson_ctx_free(jsonctx);
382
383 /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
384 str = "\"\\b\"";
385 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200386 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
387 CHECK_LOG_CTX("Invalid character reference \"\\b\" (0x00000008).", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200388
389 str = "\"\\f\"";
390 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200391 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
392 CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100393#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200394
395 /* unterminated string */
396 str = "\"unterminated string";
397 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200398 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
399 CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100400#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200401 /* invalid escape sequence */
402 str = "\"char \\x \"";
403 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200404 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
405 CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200406
407 /* new line is allowed only as escaped character in JSON */
408 str = "\"\n\"";
409 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200410 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
411 CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100412#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200413
414 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200415}
416
417static void
418test_object(void **state)
419{
420 struct lyjson_ctx *jsonctx;
421 struct ly_in *in;
422 const char *str;
423
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200424 /* empty */
425 str = " { } ";
426 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200427 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200428 assert_int_equal(LYJSON_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0));
429 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
430 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
431 lyjson_ctx_free(jsonctx);
432
433 /* simple value */
434 str = "{\"name\" : \"Radek\"}";
435 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200436 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200437 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
438 assert_ptr_equal(&str[2], jsonctx->value);
439 assert_int_equal(4, jsonctx->value_len);
440 assert_int_equal(0, jsonctx->dynamic);
441 assert_string_equal("\"Radek\"}", jsonctx->in->current);
442 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
443 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
444 assert_string_equal("Radek\"}", jsonctx->value);
445 assert_int_equal(5, jsonctx->value_len);
446 assert_int_equal(0, jsonctx->dynamic);
447 assert_string_equal("}", jsonctx->in->current);
448 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
449 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
450 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
451 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
452 lyjson_ctx_free(jsonctx);
453
454 /* two values */
455 str = "{\"smart\" : true,\"handsom\":false}";
456 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200457 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200458 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
459 assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value);
460 assert_int_equal(5, jsonctx->value_len);
461 assert_int_equal(0, jsonctx->dynamic);
462 assert_string_equal("true,\"handsom\":false}", jsonctx->in->current);
463 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
464 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
465 assert_string_equal(",\"handsom\":false}", jsonctx->in->current);
466 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
467 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
468 assert_string_equal("handsom\":false}", jsonctx->value);
469 assert_int_equal(7, jsonctx->value_len);
470 assert_int_equal(0, jsonctx->dynamic);
471 assert_string_equal("false}", jsonctx->in->current);
472 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
473 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
474 assert_string_equal("}", jsonctx->in->current);
475 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
476 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
477 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
478 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
479 lyjson_ctx_free(jsonctx);
480
481 /* inherited objects */
482 str = "{\"person\" : {\"name\":\"Radek\"}}";
483 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200484 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200485 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
486 assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value);
487 assert_int_equal(6, jsonctx->value_len);
488 assert_int_equal(0, jsonctx->dynamic);
489 assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current);
490 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
491 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
492 assert_string_equal("name\":\"Radek\"}}", jsonctx->value);
493 assert_int_equal(4, jsonctx->value_len);
494 assert_int_equal(0, jsonctx->dynamic);
495 assert_string_equal("\"Radek\"}}", jsonctx->in->current);
496 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
497 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
498 assert_string_equal("Radek\"}}", jsonctx->value);
499 assert_int_equal(5, jsonctx->value_len);
500 assert_int_equal(0, jsonctx->dynamic);
501 assert_string_equal("}}", jsonctx->in->current);
502 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
503 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
504 assert_string_equal("}", jsonctx->in->current);
505 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
506 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
507 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
508 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
509 lyjson_ctx_free(jsonctx);
510
511 /* new line is allowed only as escaped character in JSON */
512 str = "{ unquoted : \"data\"}";
513 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200514 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
515 CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200516
517 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200518}
519
520static void
521test_array(void **state)
522{
523 struct lyjson_ctx *jsonctx;
524 struct ly_in *in;
525 const char *str;
526
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200527 /* empty */
528 str = " [ ] ";
529 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200530 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200531 assert_int_equal(LYJSON_ARRAY_EMPTY, lyjson_ctx_status(jsonctx, 0));
532 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
533 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
534 lyjson_ctx_free(jsonctx);
535
536 /* simple value */
537 str = "[ null]";
538 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200539 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200540 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
541 assert_null(jsonctx->value);
542 assert_int_equal(0, jsonctx->value_len);
543 assert_int_equal(0, jsonctx->dynamic);
544 assert_string_equal("null]", jsonctx->in->current);
545 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
546 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
547 assert_string_equal("]", jsonctx->in->current);
548 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
549 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
550 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
551 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
552 lyjson_ctx_free(jsonctx);
553
554 /* two values */
555 str = "[{\"a\":null},\"x\"]";
556 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200557 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200558 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
559 assert_null(jsonctx->value);
560 assert_int_equal(0, jsonctx->value_len);
561 assert_int_equal(0, jsonctx->dynamic);
562 assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current);
563 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
564 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
565 assert_string_equal("a\":null},\"x\"]", jsonctx->value);
566 assert_int_equal(1, jsonctx->value_len);
567 assert_int_equal(0, jsonctx->dynamic);
568 assert_string_equal("null},\"x\"]", jsonctx->in->current);
569 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
570 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
571 assert_string_equal("},\"x\"]", jsonctx->in->current);
572 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
573 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
574 assert_string_equal(",\"x\"]", jsonctx->in->current);
575 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
576 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
577 assert_string_equal("x\"]", jsonctx->value);
578 assert_int_equal(1, jsonctx->value_len);
579 assert_int_equal(0, jsonctx->dynamic);
580 assert_string_equal("]", jsonctx->in->current);
581 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
582 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
583 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
584 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
585 lyjson_ctx_free(jsonctx);
586
587 /* new line is allowed only as escaped character in JSON */
588 str = "[ , null]";
589 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200590 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200591 assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200592 CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200593 lyjson_ctx_free(jsonctx);
594
595 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200596}
597
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100598int
599main(void)
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200600{
601 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200602 UTEST(test_general),
603 UTEST(test_number),
604 UTEST(test_string),
605 UTEST(test_object),
606 UTEST(test_array),
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200607 };
608
Radek Iša56ca9e42020-09-08 18:42:00 +0200609 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200610}