blob: f17ea2ed6615e956dd288a091aacf391205adcc5 [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
135 /* exp fraction number */
136 str = "1.1e3";
137 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200138 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200139 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
140 assert_string_equal("1100", jsonctx->value);
141 assert_int_equal(4, jsonctx->value_len);
142 assert_int_equal(1, jsonctx->dynamic);
143 lyjson_ctx_free(jsonctx);
144
aPiecek58e46a52021-05-05 10:04:47 +0200145 str = "12.1e3";
146 assert_non_null(ly_in_memory(in, str));
147 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
148 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
149 assert_string_equal("12100", jsonctx->value);
150 assert_int_equal(5, jsonctx->value_len);
151 assert_int_equal(1, jsonctx->dynamic);
152 lyjson_ctx_free(jsonctx);
153
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200154 /* negative exp fraction number */
155 str = "1.1e-3";
156 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200157 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200158 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
159 assert_string_equal("0.0011", jsonctx->value);
160 assert_int_equal(6, jsonctx->value_len);
161 assert_int_equal(1, jsonctx->dynamic);
162 lyjson_ctx_free(jsonctx);
163
aPiecek58e46a52021-05-05 10:04:47 +0200164 str = "12.4e-3";
165 assert_non_null(ly_in_memory(in, str));
166 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
167 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
168 assert_string_equal("0.0124", jsonctx->value);
169 assert_int_equal(6, jsonctx->value_len);
170 assert_int_equal(1, jsonctx->dynamic);
171 lyjson_ctx_free(jsonctx);
172
173 str = "12.4e-2";
174 assert_non_null(ly_in_memory(in, str));
175 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
176 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
177 assert_string_equal("0.124", jsonctx->value);
178 assert_int_equal(5, jsonctx->value_len);
179 assert_int_equal(1, jsonctx->dynamic);
180 lyjson_ctx_free(jsonctx);
181
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200182 /* exp negative fraction number */
183 str = "-0.11e3";
184 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200185 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200186 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
187 assert_string_equal("-110", jsonctx->value);
188 assert_int_equal(4, jsonctx->value_len);
189 assert_int_equal(1, jsonctx->dynamic);
190 lyjson_ctx_free(jsonctx);
191
aPiecek58e46a52021-05-05 10:04:47 +0200192 str = "-44.11e3";
193 assert_non_null(ly_in_memory(in, str));
194 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
195 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
196 assert_string_equal("-44110", jsonctx->value);
197 assert_int_equal(6, jsonctx->value_len);
198 assert_int_equal(1, jsonctx->dynamic);
199 lyjson_ctx_free(jsonctx);
200
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200201 /* negative exp negative fraction number */
202 str = "-3.14e-3";
203 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200204 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200205 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
206 assert_string_equal("-0.00314", jsonctx->value);
207 assert_int_equal(8, jsonctx->value_len);
208 assert_int_equal(1, jsonctx->dynamic);
209 lyjson_ctx_free(jsonctx);
210
aPiecek58e46a52021-05-05 10:04:47 +0200211 str = "-98.7e-3";
212 assert_non_null(ly_in_memory(in, str));
213 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
214 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
215 assert_string_equal("-0.0987", jsonctx->value);
216 assert_int_equal(7, jsonctx->value_len);
217 assert_int_equal(1, jsonctx->dynamic);
218 lyjson_ctx_free(jsonctx);
219
220 str = "-98.7e-2";
221 assert_non_null(ly_in_memory(in, str));
222 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
223 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
224 assert_string_equal("-0.987", jsonctx->value);
225 assert_int_equal(6, jsonctx->value_len);
226 assert_int_equal(1, jsonctx->dynamic);
227 lyjson_ctx_free(jsonctx);
228
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200229 /* various invalid inputs */
230 str = "-x";
231 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200232 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
233 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200234
235 str = " -";
236 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200237 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
238 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200239
240 str = "--1";
241 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200242 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
243 CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200244
245 str = "+1";
246 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200247 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
248 CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200249
250 str = " 1.x ";
251 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200252 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
253 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200254
255 str = "1.";
256 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200257 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
258 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200259
260 str = " 1eo ";
261 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200262 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
263 CHECK_LOG_CTX("Invalid character in JSON Number value (\"o\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200264
265 str = "1e";
266 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200267 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
268 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200269
270 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200271}
272
Radek Iša447abb82021-03-04 14:08:56 +0100273/* now string is tested in file ./tests/utests/types/string.c */
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200274static void
275test_string(void **state)
276{
277 struct lyjson_ctx *jsonctx;
Radek Iša447abb82021-03-04 14:08:56 +0100278 struct ly_in *in = NULL;
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200279 const char *str;
280
Radek Iša447abb82021-03-04 14:08:56 +0100281 str = "";
282 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
283
284#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200285 /* simple string */
286 str = "\"hello\"";
Radek Iša56ca9e42020-09-08 18:42:00 +0200287 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200288 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
289 assert_ptr_equal(&str[1], jsonctx->value);
290 assert_int_equal(5, jsonctx->value_len);
291 assert_int_equal(0, jsonctx->dynamic);
292 lyjson_ctx_free(jsonctx);
293
294 /* 4-byte utf8 character */
295 str = "\"\\t𠜎\"";
296 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200297 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200298 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
299 assert_string_equal("\t𠜎", jsonctx->value);
300 assert_int_equal(5, jsonctx->value_len);
301 assert_int_equal(1, jsonctx->dynamic);
302 lyjson_ctx_free(jsonctx);
303
304 /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and
305 * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string,
306 * the YANG string type's restrictions apply to the JSON escape sequences */
307 str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\"";
308 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200309 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200310 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
311 assert_string_equal("\" \\ \r / \n \t €", jsonctx->value);
312 assert_int_equal(15, jsonctx->value_len);
313 assert_int_equal(1, jsonctx->dynamic);
314 lyjson_ctx_free(jsonctx);
315
316 /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
317 str = "\"\\b\"";
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 reference \"\\b\" (0x00000008).", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200321
322 str = "\"\\f\"";
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("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100326#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200327
328 /* unterminated string */
329 str = "\"unterminated string";
330 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200331 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
332 CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100333#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200334 /* invalid escape sequence */
335 str = "\"char \\x \"";
336 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200337 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
338 CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200339
340 /* new line is allowed only as escaped character in JSON */
341 str = "\"\n\"";
342 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200343 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
344 CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100345#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200346
347 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200348}
349
350static void
351test_object(void **state)
352{
353 struct lyjson_ctx *jsonctx;
354 struct ly_in *in;
355 const char *str;
356
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200357 /* empty */
358 str = " { } ";
359 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200360 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200361 assert_int_equal(LYJSON_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0));
362 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
363 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
364 lyjson_ctx_free(jsonctx);
365
366 /* simple value */
367 str = "{\"name\" : \"Radek\"}";
368 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200369 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200370 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
371 assert_ptr_equal(&str[2], jsonctx->value);
372 assert_int_equal(4, jsonctx->value_len);
373 assert_int_equal(0, jsonctx->dynamic);
374 assert_string_equal("\"Radek\"}", jsonctx->in->current);
375 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
376 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
377 assert_string_equal("Radek\"}", jsonctx->value);
378 assert_int_equal(5, jsonctx->value_len);
379 assert_int_equal(0, jsonctx->dynamic);
380 assert_string_equal("}", jsonctx->in->current);
381 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
382 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
383 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
384 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
385 lyjson_ctx_free(jsonctx);
386
387 /* two values */
388 str = "{\"smart\" : true,\"handsom\":false}";
389 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200390 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200391 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
392 assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value);
393 assert_int_equal(5, jsonctx->value_len);
394 assert_int_equal(0, jsonctx->dynamic);
395 assert_string_equal("true,\"handsom\":false}", jsonctx->in->current);
396 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
397 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
398 assert_string_equal(",\"handsom\":false}", jsonctx->in->current);
399 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
400 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
401 assert_string_equal("handsom\":false}", jsonctx->value);
402 assert_int_equal(7, jsonctx->value_len);
403 assert_int_equal(0, jsonctx->dynamic);
404 assert_string_equal("false}", jsonctx->in->current);
405 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
406 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
407 assert_string_equal("}", jsonctx->in->current);
408 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
409 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
410 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
411 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
412 lyjson_ctx_free(jsonctx);
413
414 /* inherited objects */
415 str = "{\"person\" : {\"name\":\"Radek\"}}";
416 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200417 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200418 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
419 assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value);
420 assert_int_equal(6, jsonctx->value_len);
421 assert_int_equal(0, jsonctx->dynamic);
422 assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current);
423 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
424 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
425 assert_string_equal("name\":\"Radek\"}}", jsonctx->value);
426 assert_int_equal(4, jsonctx->value_len);
427 assert_int_equal(0, jsonctx->dynamic);
428 assert_string_equal("\"Radek\"}}", jsonctx->in->current);
429 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
430 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
431 assert_string_equal("Radek\"}}", jsonctx->value);
432 assert_int_equal(5, jsonctx->value_len);
433 assert_int_equal(0, jsonctx->dynamic);
434 assert_string_equal("}}", jsonctx->in->current);
435 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
436 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
437 assert_string_equal("}", jsonctx->in->current);
438 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
439 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
440 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
441 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
442 lyjson_ctx_free(jsonctx);
443
444 /* new line is allowed only as escaped character in JSON */
445 str = "{ unquoted : \"data\"}";
446 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200447 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
448 CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200449
450 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200451}
452
453static void
454test_array(void **state)
455{
456 struct lyjson_ctx *jsonctx;
457 struct ly_in *in;
458 const char *str;
459
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200460 /* empty */
461 str = " [ ] ";
462 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200463 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200464 assert_int_equal(LYJSON_ARRAY_EMPTY, lyjson_ctx_status(jsonctx, 0));
465 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
466 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
467 lyjson_ctx_free(jsonctx);
468
469 /* simple value */
470 str = "[ null]";
471 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200472 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200473 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
474 assert_null(jsonctx->value);
475 assert_int_equal(0, jsonctx->value_len);
476 assert_int_equal(0, jsonctx->dynamic);
477 assert_string_equal("null]", jsonctx->in->current);
478 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
479 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
480 assert_string_equal("]", jsonctx->in->current);
481 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
482 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
483 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
484 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
485 lyjson_ctx_free(jsonctx);
486
487 /* two values */
488 str = "[{\"a\":null},\"x\"]";
489 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200490 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200491 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
492 assert_null(jsonctx->value);
493 assert_int_equal(0, jsonctx->value_len);
494 assert_int_equal(0, jsonctx->dynamic);
495 assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current);
496 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
497 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
498 assert_string_equal("a\":null},\"x\"]", jsonctx->value);
499 assert_int_equal(1, jsonctx->value_len);
500 assert_int_equal(0, jsonctx->dynamic);
501 assert_string_equal("null},\"x\"]", jsonctx->in->current);
502 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
503 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
504 assert_string_equal("},\"x\"]", 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_string_equal(",\"x\"]", jsonctx->in->current);
508 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
509 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
510 assert_string_equal("x\"]", jsonctx->value);
511 assert_int_equal(1, jsonctx->value_len);
512 assert_int_equal(0, jsonctx->dynamic);
513 assert_string_equal("]", jsonctx->in->current);
514 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
515 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
516 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
517 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
518 lyjson_ctx_free(jsonctx);
519
520 /* new line is allowed only as escaped character in JSON */
521 str = "[ , null]";
522 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200523 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200524 assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200525 CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200526 lyjson_ctx_free(jsonctx);
527
528 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200529}
530
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100531int
532main(void)
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200533{
534 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200535 UTEST(test_general),
536 UTEST(test_number),
537 UTEST(test_string),
538 UTEST(test_object),
539 UTEST(test_array),
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200540 };
541
Radek Iša56ca9e42020-09-08 18:42:00 +0200542 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200543}