blob: d9f182515eea1fd7d1abbd13f0ab77aaf390ad89 [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
145 /* negative exp fraction number */
146 str = "1.1e-3";
147 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200148 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200149 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
150 assert_string_equal("0.0011", jsonctx->value);
151 assert_int_equal(6, jsonctx->value_len);
152 assert_int_equal(1, jsonctx->dynamic);
153 lyjson_ctx_free(jsonctx);
154
155 /* exp negative fraction number */
156 str = "-0.11e3";
157 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200159 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
160 assert_string_equal("-110", jsonctx->value);
161 assert_int_equal(4, jsonctx->value_len);
162 assert_int_equal(1, jsonctx->dynamic);
163 lyjson_ctx_free(jsonctx);
164
165 /* negative exp negative fraction number */
166 str = "-3.14e-3";
167 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200168 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200169 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
170 assert_string_equal("-0.00314", jsonctx->value);
171 assert_int_equal(8, jsonctx->value_len);
172 assert_int_equal(1, jsonctx->dynamic);
173 lyjson_ctx_free(jsonctx);
174
175 /* various invalid inputs */
176 str = "-x";
177 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200178 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
179 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200180
181 str = " -";
182 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200183 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
184 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200185
186 str = "--1";
187 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200188 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
189 CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200190
191 str = "+1";
192 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
194 CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200195
196 str = " 1.x ";
197 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200198 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
199 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200200
201 str = "1.";
202 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200203 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
204 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200205
206 str = " 1eo ";
207 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200208 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
209 CHECK_LOG_CTX("Invalid character in JSON Number value (\"o\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200210
211 str = "1e";
212 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200213 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
214 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200215
216 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200217}
218
Radek Iša447abb82021-03-04 14:08:56 +0100219/* now string is tested in file ./tests/utests/types/string.c */
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200220static void
221test_string(void **state)
222{
223 struct lyjson_ctx *jsonctx;
Radek Iša447abb82021-03-04 14:08:56 +0100224 struct ly_in *in = NULL;
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200225 const char *str;
226
Radek Iša447abb82021-03-04 14:08:56 +0100227 str = "";
228 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
229
230#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200231 /* simple string */
232 str = "\"hello\"";
Radek Iša56ca9e42020-09-08 18:42:00 +0200233 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200234 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
235 assert_ptr_equal(&str[1], jsonctx->value);
236 assert_int_equal(5, jsonctx->value_len);
237 assert_int_equal(0, jsonctx->dynamic);
238 lyjson_ctx_free(jsonctx);
239
240 /* 4-byte utf8 character */
241 str = "\"\\t𠜎\"";
242 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200243 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200244 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
245 assert_string_equal("\t𠜎", jsonctx->value);
246 assert_int_equal(5, jsonctx->value_len);
247 assert_int_equal(1, jsonctx->dynamic);
248 lyjson_ctx_free(jsonctx);
249
250 /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and
251 * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string,
252 * the YANG string type's restrictions apply to the JSON escape sequences */
253 str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\"";
254 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200255 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200256 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
257 assert_string_equal("\" \\ \r / \n \t €", jsonctx->value);
258 assert_int_equal(15, jsonctx->value_len);
259 assert_int_equal(1, jsonctx->dynamic);
260 lyjson_ctx_free(jsonctx);
261
262 /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
263 str = "\"\\b\"";
264 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200265 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
266 CHECK_LOG_CTX("Invalid character reference \"\\b\" (0x00000008).", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200267
268 str = "\"\\f\"";
269 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
271 CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100272#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200273
274 /* unterminated string */
275 str = "\"unterminated string";
276 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200277 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
278 CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100279#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200280 /* invalid escape sequence */
281 str = "\"char \\x \"";
282 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200283 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
284 CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200285
286 /* new line is allowed only as escaped character in JSON */
287 str = "\"\n\"";
288 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200289 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
290 CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100291#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200292
293 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200294}
295
296static void
297test_object(void **state)
298{
299 struct lyjson_ctx *jsonctx;
300 struct ly_in *in;
301 const char *str;
302
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200303 /* empty */
304 str = " { } ";
305 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200307 assert_int_equal(LYJSON_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0));
308 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
309 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
310 lyjson_ctx_free(jsonctx);
311
312 /* simple value */
313 str = "{\"name\" : \"Radek\"}";
314 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200315 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200316 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
317 assert_ptr_equal(&str[2], jsonctx->value);
318 assert_int_equal(4, jsonctx->value_len);
319 assert_int_equal(0, jsonctx->dynamic);
320 assert_string_equal("\"Radek\"}", jsonctx->in->current);
321 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
322 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
323 assert_string_equal("Radek\"}", jsonctx->value);
324 assert_int_equal(5, jsonctx->value_len);
325 assert_int_equal(0, jsonctx->dynamic);
326 assert_string_equal("}", jsonctx->in->current);
327 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
328 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
329 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
330 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
331 lyjson_ctx_free(jsonctx);
332
333 /* two values */
334 str = "{\"smart\" : true,\"handsom\":false}";
335 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200336 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200337 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
338 assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value);
339 assert_int_equal(5, jsonctx->value_len);
340 assert_int_equal(0, jsonctx->dynamic);
341 assert_string_equal("true,\"handsom\":false}", jsonctx->in->current);
342 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
343 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
344 assert_string_equal(",\"handsom\":false}", jsonctx->in->current);
345 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
346 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
347 assert_string_equal("handsom\":false}", jsonctx->value);
348 assert_int_equal(7, jsonctx->value_len);
349 assert_int_equal(0, jsonctx->dynamic);
350 assert_string_equal("false}", jsonctx->in->current);
351 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
352 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
353 assert_string_equal("}", jsonctx->in->current);
354 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
355 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
356 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
357 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
358 lyjson_ctx_free(jsonctx);
359
360 /* inherited objects */
361 str = "{\"person\" : {\"name\":\"Radek\"}}";
362 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200363 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200364 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
365 assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value);
366 assert_int_equal(6, jsonctx->value_len);
367 assert_int_equal(0, jsonctx->dynamic);
368 assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current);
369 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
370 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
371 assert_string_equal("name\":\"Radek\"}}", 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_string_equal("}", jsonctx->in->current);
384 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
385 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
386 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
387 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
388 lyjson_ctx_free(jsonctx);
389
390 /* new line is allowed only as escaped character in JSON */
391 str = "{ unquoted : \"data\"}";
392 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200393 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
394 CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200395
396 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200397}
398
399static void
400test_array(void **state)
401{
402 struct lyjson_ctx *jsonctx;
403 struct ly_in *in;
404 const char *str;
405
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200406 /* empty */
407 str = " [ ] ";
408 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200409 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200410 assert_int_equal(LYJSON_ARRAY_EMPTY, lyjson_ctx_status(jsonctx, 0));
411 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
412 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
413 lyjson_ctx_free(jsonctx);
414
415 /* simple value */
416 str = "[ null]";
417 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200418 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200419 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
420 assert_null(jsonctx->value);
421 assert_int_equal(0, jsonctx->value_len);
422 assert_int_equal(0, jsonctx->dynamic);
423 assert_string_equal("null]", jsonctx->in->current);
424 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
425 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
426 assert_string_equal("]", jsonctx->in->current);
427 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
428 assert_int_equal(LYJSON_ARRAY_CLOSED, 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 /* two values */
434 str = "[{\"a\":null},\"x\"]";
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_ARRAY, lyjson_ctx_status(jsonctx, 0));
438 assert_null(jsonctx->value);
439 assert_int_equal(0, jsonctx->value_len);
440 assert_int_equal(0, jsonctx->dynamic);
441 assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current);
442 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
443 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
444 assert_string_equal("a\":null},\"x\"]", jsonctx->value);
445 assert_int_equal(1, jsonctx->value_len);
446 assert_int_equal(0, jsonctx->dynamic);
447 assert_string_equal("null},\"x\"]", jsonctx->in->current);
448 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
449 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
450 assert_string_equal("},\"x\"]", jsonctx->in->current);
451 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
452 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
453 assert_string_equal(",\"x\"]", jsonctx->in->current);
454 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
455 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
456 assert_string_equal("x\"]", jsonctx->value);
457 assert_int_equal(1, jsonctx->value_len);
458 assert_int_equal(0, jsonctx->dynamic);
459 assert_string_equal("]", jsonctx->in->current);
460 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
461 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
462 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
463 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
464 lyjson_ctx_free(jsonctx);
465
466 /* new line is allowed only as escaped character in JSON */
467 str = "[ , null]";
468 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200469 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200470 assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200471 CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200472 lyjson_ctx_free(jsonctx);
473
474 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200475}
476
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100477int
478main(void)
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200479{
480 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200481 UTEST(test_general),
482 UTEST(test_number),
483 UTEST(test_string),
484 UTEST(test_object),
485 UTEST(test_array),
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200486 };
487
Radek Iša56ca9e42020-09-08 18:42:00 +0200488 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200489}