blob: b6db947acba43f629d88db42095d9bc46ed0e057 [file] [log] [blame]
Radek Krejci50f0c6b2020-06-18 16:31:48 +02001/*
2 * @file json.c
3 * @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
107 /* exp number */
108 str = "1E10";
109 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200110 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200111 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
112 assert_string_equal("10000000000", jsonctx->value);
113 assert_int_equal(11, jsonctx->value_len);
114 assert_int_equal(1, jsonctx->dynamic);
115 lyjson_ctx_free(jsonctx);
116
117 str = "15E-1";
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("1.5", jsonctx->value);
122 assert_int_equal(3, jsonctx->value_len);
123 assert_int_equal(1, jsonctx->dynamic);
124 lyjson_ctx_free(jsonctx);
125
126 str = "15E-3";
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("0.015", jsonctx->value);
131 assert_int_equal(5, jsonctx->value_len);
132 assert_int_equal(1, jsonctx->dynamic);
133 lyjson_ctx_free(jsonctx);
134
aPiecek94927eb2021-05-05 12:36:50 +0200135 str = "1E1000";
136 assert_non_null(ly_in_memory(in, str));
137 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
138
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200139 /* exp fraction number */
140 str = "1.1e3";
141 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200142 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200143 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
144 assert_string_equal("1100", jsonctx->value);
145 assert_int_equal(4, jsonctx->value_len);
146 assert_int_equal(1, jsonctx->dynamic);
147 lyjson_ctx_free(jsonctx);
148
aPiecek58e46a52021-05-05 10:04:47 +0200149 str = "12.1e3";
150 assert_non_null(ly_in_memory(in, str));
151 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
152 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
153 assert_string_equal("12100", jsonctx->value);
154 assert_int_equal(5, jsonctx->value_len);
155 assert_int_equal(1, jsonctx->dynamic);
156 lyjson_ctx_free(jsonctx);
157
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200158 /* negative exp fraction number */
159 str = "1.1e-3";
160 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200161 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200162 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
163 assert_string_equal("0.0011", jsonctx->value);
164 assert_int_equal(6, jsonctx->value_len);
165 assert_int_equal(1, jsonctx->dynamic);
166 lyjson_ctx_free(jsonctx);
167
aPiecek58e46a52021-05-05 10:04:47 +0200168 str = "12.4e-3";
169 assert_non_null(ly_in_memory(in, str));
170 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
171 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
172 assert_string_equal("0.0124", jsonctx->value);
173 assert_int_equal(6, jsonctx->value_len);
174 assert_int_equal(1, jsonctx->dynamic);
175 lyjson_ctx_free(jsonctx);
176
177 str = "12.4e-2";
178 assert_non_null(ly_in_memory(in, str));
179 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
180 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
181 assert_string_equal("0.124", jsonctx->value);
182 assert_int_equal(5, jsonctx->value_len);
183 assert_int_equal(1, jsonctx->dynamic);
184 lyjson_ctx_free(jsonctx);
185
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200186 /* exp negative fraction number */
187 str = "-0.11e3";
188 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200189 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200190 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
191 assert_string_equal("-110", jsonctx->value);
192 assert_int_equal(4, jsonctx->value_len);
193 assert_int_equal(1, jsonctx->dynamic);
194 lyjson_ctx_free(jsonctx);
195
aPiecek58e46a52021-05-05 10:04:47 +0200196 str = "-44.11e3";
197 assert_non_null(ly_in_memory(in, str));
198 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
199 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
200 assert_string_equal("-44110", jsonctx->value);
201 assert_int_equal(6, jsonctx->value_len);
202 assert_int_equal(1, jsonctx->dynamic);
203 lyjson_ctx_free(jsonctx);
204
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200205 /* negative exp negative fraction number */
206 str = "-3.14e-3";
207 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200208 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200209 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
210 assert_string_equal("-0.00314", jsonctx->value);
211 assert_int_equal(8, jsonctx->value_len);
212 assert_int_equal(1, jsonctx->dynamic);
213 lyjson_ctx_free(jsonctx);
214
aPiecek58e46a52021-05-05 10:04:47 +0200215 str = "-98.7e-3";
216 assert_non_null(ly_in_memory(in, str));
217 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
218 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
219 assert_string_equal("-0.0987", jsonctx->value);
220 assert_int_equal(7, jsonctx->value_len);
221 assert_int_equal(1, jsonctx->dynamic);
222 lyjson_ctx_free(jsonctx);
223
224 str = "-98.7e-2";
225 assert_non_null(ly_in_memory(in, str));
226 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
227 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
228 assert_string_equal("-0.987", jsonctx->value);
229 assert_int_equal(6, jsonctx->value_len);
230 assert_int_equal(1, jsonctx->dynamic);
231 lyjson_ctx_free(jsonctx);
232
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200233 /* various invalid inputs */
234 str = "-x";
235 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200236 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
237 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200238
239 str = " -";
240 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200241 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
242 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200243
244 str = "--1";
245 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200246 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
247 CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200248
249 str = "+1";
250 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200251 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
252 CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200253
254 str = " 1.x ";
255 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200256 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
257 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200258
259 str = "1.";
260 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200261 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
262 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200263
264 str = " 1eo ";
265 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200266 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
267 CHECK_LOG_CTX("Invalid character in JSON Number value (\"o\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200268
269 str = "1e";
270 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200271 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
272 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200273
274 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200275}
276
Radek Iša447abb82021-03-04 14:08:56 +0100277/* now string is tested in file ./tests/utests/types/string.c */
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200278static void
279test_string(void **state)
280{
281 struct lyjson_ctx *jsonctx;
Radek Iša447abb82021-03-04 14:08:56 +0100282 struct ly_in *in = NULL;
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200283 const char *str;
284
Radek Iša447abb82021-03-04 14:08:56 +0100285 str = "";
286 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
287
288#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200289 /* simple string */
290 str = "\"hello\"";
Radek Iša56ca9e42020-09-08 18:42:00 +0200291 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200292 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
293 assert_ptr_equal(&str[1], jsonctx->value);
294 assert_int_equal(5, jsonctx->value_len);
295 assert_int_equal(0, jsonctx->dynamic);
296 lyjson_ctx_free(jsonctx);
297
298 /* 4-byte utf8 character */
299 str = "\"\\t𠜎\"";
300 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200301 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200302 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
303 assert_string_equal("\t𠜎", jsonctx->value);
304 assert_int_equal(5, jsonctx->value_len);
305 assert_int_equal(1, jsonctx->dynamic);
306 lyjson_ctx_free(jsonctx);
307
308 /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and
309 * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string,
310 * the YANG string type's restrictions apply to the JSON escape sequences */
311 str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\"";
312 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200313 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200314 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
315 assert_string_equal("\" \\ \r / \n \t €", jsonctx->value);
316 assert_int_equal(15, jsonctx->value_len);
317 assert_int_equal(1, jsonctx->dynamic);
318 lyjson_ctx_free(jsonctx);
319
320 /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
321 str = "\"\\b\"";
322 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200323 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
324 CHECK_LOG_CTX("Invalid character reference \"\\b\" (0x00000008).", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200325
326 str = "\"\\f\"";
327 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200328 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
329 CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100330#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200331
332 /* unterminated string */
333 str = "\"unterminated string";
334 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200335 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
336 CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100337#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200338 /* invalid escape sequence */
339 str = "\"char \\x \"";
340 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200341 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
342 CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200343
344 /* new line is allowed only as escaped character in JSON */
345 str = "\"\n\"";
346 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200347 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
348 CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100349#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200350
351 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200352}
353
354static void
355test_object(void **state)
356{
357 struct lyjson_ctx *jsonctx;
358 struct ly_in *in;
359 const char *str;
360
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200361 /* empty */
362 str = " { } ";
363 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
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_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0));
366 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
367 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
368 lyjson_ctx_free(jsonctx);
369
370 /* simple value */
371 str = "{\"name\" : \"Radek\"}";
372 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200373 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200374 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
375 assert_ptr_equal(&str[2], jsonctx->value);
376 assert_int_equal(4, jsonctx->value_len);
377 assert_int_equal(0, jsonctx->dynamic);
378 assert_string_equal("\"Radek\"}", jsonctx->in->current);
379 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
380 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
381 assert_string_equal("Radek\"}", jsonctx->value);
382 assert_int_equal(5, jsonctx->value_len);
383 assert_int_equal(0, jsonctx->dynamic);
384 assert_string_equal("}", jsonctx->in->current);
385 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
386 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
387 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
388 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
389 lyjson_ctx_free(jsonctx);
390
391 /* two values */
392 str = "{\"smart\" : true,\"handsom\":false}";
393 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200394 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200395 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
396 assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value);
397 assert_int_equal(5, jsonctx->value_len);
398 assert_int_equal(0, jsonctx->dynamic);
399 assert_string_equal("true,\"handsom\":false}", jsonctx->in->current);
400 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
401 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
402 assert_string_equal(",\"handsom\":false}", jsonctx->in->current);
403 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
404 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
405 assert_string_equal("handsom\":false}", jsonctx->value);
406 assert_int_equal(7, jsonctx->value_len);
407 assert_int_equal(0, jsonctx->dynamic);
408 assert_string_equal("false}", jsonctx->in->current);
409 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
410 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
411 assert_string_equal("}", jsonctx->in->current);
412 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
413 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
414 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
415 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
416 lyjson_ctx_free(jsonctx);
417
418 /* inherited objects */
419 str = "{\"person\" : {\"name\":\"Radek\"}}";
420 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200421 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200422 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
423 assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value);
424 assert_int_equal(6, jsonctx->value_len);
425 assert_int_equal(0, jsonctx->dynamic);
426 assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current);
427 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
428 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
429 assert_string_equal("name\":\"Radek\"}}", jsonctx->value);
430 assert_int_equal(4, jsonctx->value_len);
431 assert_int_equal(0, jsonctx->dynamic);
432 assert_string_equal("\"Radek\"}}", jsonctx->in->current);
433 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
434 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
435 assert_string_equal("Radek\"}}", jsonctx->value);
436 assert_int_equal(5, jsonctx->value_len);
437 assert_int_equal(0, jsonctx->dynamic);
438 assert_string_equal("}}", jsonctx->in->current);
439 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
440 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
441 assert_string_equal("}", jsonctx->in->current);
442 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
443 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
444 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
445 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
446 lyjson_ctx_free(jsonctx);
447
448 /* new line is allowed only as escaped character in JSON */
449 str = "{ unquoted : \"data\"}";
450 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200451 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
452 CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200453
454 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200455}
456
457static void
458test_array(void **state)
459{
460 struct lyjson_ctx *jsonctx;
461 struct ly_in *in;
462 const char *str;
463
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200464 /* empty */
465 str = " [ ] ";
466 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200467 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200468 assert_int_equal(LYJSON_ARRAY_EMPTY, lyjson_ctx_status(jsonctx, 0));
469 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
470 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
471 lyjson_ctx_free(jsonctx);
472
473 /* simple value */
474 str = "[ null]";
475 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200476 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200477 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
478 assert_null(jsonctx->value);
479 assert_int_equal(0, jsonctx->value_len);
480 assert_int_equal(0, jsonctx->dynamic);
481 assert_string_equal("null]", jsonctx->in->current);
482 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
483 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
484 assert_string_equal("]", jsonctx->in->current);
485 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
486 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
487 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
488 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
489 lyjson_ctx_free(jsonctx);
490
491 /* two values */
492 str = "[{\"a\":null},\"x\"]";
493 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200494 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200495 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
496 assert_null(jsonctx->value);
497 assert_int_equal(0, jsonctx->value_len);
498 assert_int_equal(0, jsonctx->dynamic);
499 assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current);
500 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
501 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
502 assert_string_equal("a\":null},\"x\"]", jsonctx->value);
503 assert_int_equal(1, jsonctx->value_len);
504 assert_int_equal(0, jsonctx->dynamic);
505 assert_string_equal("null},\"x\"]", jsonctx->in->current);
506 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
507 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
508 assert_string_equal("},\"x\"]", jsonctx->in->current);
509 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
510 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
511 assert_string_equal(",\"x\"]", jsonctx->in->current);
512 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
513 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
514 assert_string_equal("x\"]", jsonctx->value);
515 assert_int_equal(1, jsonctx->value_len);
516 assert_int_equal(0, jsonctx->dynamic);
517 assert_string_equal("]", jsonctx->in->current);
518 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
519 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
520 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
521 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
522 lyjson_ctx_free(jsonctx);
523
524 /* new line is allowed only as escaped character in JSON */
525 str = "[ , null]";
526 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200527 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200528 assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200529 CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200530 lyjson_ctx_free(jsonctx);
531
532 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200533}
534
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100535int
536main(void)
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200537{
538 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200539 UTEST(test_general),
540 UTEST(test_number),
541 UTEST(test_string),
542 UTEST(test_object),
543 UTEST(test_array),
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200544 };
545
Radek Iša56ca9e42020-09-08 18:42:00 +0200546 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200547}