blob: 211e50696c29cf8db156820d1e972b164f3223ad [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
aPiecek350a6bf2021-05-25 07:59:10 +0200135 str = "15E-2";
136 assert_non_null(ly_in_memory(in, str));
137 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
138 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
139 assert_string_equal("0.15", jsonctx->value);
140 assert_int_equal(4, jsonctx->value_len);
141 assert_int_equal(1, jsonctx->dynamic);
142 lyjson_ctx_free(jsonctx);
143
144 str = "-15E-2";
145 assert_non_null(ly_in_memory(in, str));
146 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
147 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
148 assert_string_equal("-0.15", jsonctx->value);
149 assert_int_equal(5, jsonctx->value_len);
150 assert_int_equal(1, jsonctx->dynamic);
151 lyjson_ctx_free(jsonctx);
152
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200153 str = "15E-3";
154 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200155 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200156 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
157 assert_string_equal("0.015", jsonctx->value);
158 assert_int_equal(5, jsonctx->value_len);
159 assert_int_equal(1, jsonctx->dynamic);
160 lyjson_ctx_free(jsonctx);
161
aPiecek94927eb2021-05-05 12:36:50 +0200162 str = "1E1000";
163 assert_non_null(ly_in_memory(in, str));
164 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
165
aPieceka40b4662021-05-13 15:47:03 +0200166 str = "0E0";
167 assert_non_null(ly_in_memory(in, str));
168 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
169 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
170 assert_string_equal("0", jsonctx->value);
171 assert_int_equal(1, jsonctx->value_len);
172 assert_int_equal(1, jsonctx->dynamic);
173 lyjson_ctx_free(jsonctx);
174
175 str = "0E-0";
176 assert_non_null(ly_in_memory(in, str));
177 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
178 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
179 assert_string_equal("0", jsonctx->value);
180 assert_int_equal(1, jsonctx->value_len);
181 assert_int_equal(1, jsonctx->dynamic);
182 lyjson_ctx_free(jsonctx);
183
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200184 /* exp fraction number */
185 str = "1.1e3";
186 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200187 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200188 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
189 assert_string_equal("1100", jsonctx->value);
190 assert_int_equal(4, jsonctx->value_len);
191 assert_int_equal(1, jsonctx->dynamic);
192 lyjson_ctx_free(jsonctx);
193
aPiecek58e46a52021-05-05 10:04:47 +0200194 str = "12.1e3";
195 assert_non_null(ly_in_memory(in, str));
196 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
197 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
198 assert_string_equal("12100", jsonctx->value);
199 assert_int_equal(5, jsonctx->value_len);
200 assert_int_equal(1, jsonctx->dynamic);
201 lyjson_ctx_free(jsonctx);
202
aPieceka40b4662021-05-13 15:47:03 +0200203 str = "0.0e0";
204 assert_non_null(ly_in_memory(in, str));
205 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
206 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
207 assert_string_equal("0.0", jsonctx->value);
208 assert_int_equal(3, jsonctx->value_len);
209 assert_int_equal(1, jsonctx->dynamic);
210 lyjson_ctx_free(jsonctx);
211
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200212 /* negative exp fraction number */
213 str = "1.1e-3";
214 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200215 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200216 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
217 assert_string_equal("0.0011", jsonctx->value);
218 assert_int_equal(6, jsonctx->value_len);
219 assert_int_equal(1, jsonctx->dynamic);
220 lyjson_ctx_free(jsonctx);
221
aPiecek58e46a52021-05-05 10:04:47 +0200222 str = "12.4e-3";
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.0124", jsonctx->value);
227 assert_int_equal(6, jsonctx->value_len);
228 assert_int_equal(1, jsonctx->dynamic);
229 lyjson_ctx_free(jsonctx);
230
231 str = "12.4e-2";
232 assert_non_null(ly_in_memory(in, str));
233 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
234 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
235 assert_string_equal("0.124", jsonctx->value);
236 assert_int_equal(5, jsonctx->value_len);
237 assert_int_equal(1, jsonctx->dynamic);
238 lyjson_ctx_free(jsonctx);
239
aPieceka40b4662021-05-13 15:47:03 +0200240 str = "0.0e-0";
241 assert_non_null(ly_in_memory(in, str));
242 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
243 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
244 assert_string_equal("0.0", jsonctx->value);
245 assert_int_equal(3, jsonctx->value_len);
246 assert_int_equal(1, jsonctx->dynamic);
247 lyjson_ctx_free(jsonctx);
248
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200249 /* exp negative fraction number */
250 str = "-0.11e3";
251 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200252 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200253 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
254 assert_string_equal("-110", jsonctx->value);
255 assert_int_equal(4, jsonctx->value_len);
256 assert_int_equal(1, jsonctx->dynamic);
257 lyjson_ctx_free(jsonctx);
258
aPiecek58e46a52021-05-05 10:04:47 +0200259 str = "-44.11e3";
260 assert_non_null(ly_in_memory(in, str));
261 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
262 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
263 assert_string_equal("-44110", jsonctx->value);
264 assert_int_equal(6, jsonctx->value_len);
265 assert_int_equal(1, jsonctx->dynamic);
266 lyjson_ctx_free(jsonctx);
267
aPieceka40b4662021-05-13 15:47:03 +0200268 str = "-0.0e0";
269 assert_non_null(ly_in_memory(in, str));
270 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
271 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
272 assert_string_equal("-0.0", jsonctx->value);
273 assert_int_equal(4, jsonctx->value_len);
274 assert_int_equal(1, jsonctx->dynamic);
275 lyjson_ctx_free(jsonctx);
276
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200277 /* negative exp negative fraction number */
278 str = "-3.14e-3";
279 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200280 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200281 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
282 assert_string_equal("-0.00314", jsonctx->value);
283 assert_int_equal(8, jsonctx->value_len);
284 assert_int_equal(1, jsonctx->dynamic);
285 lyjson_ctx_free(jsonctx);
286
aPiecek58e46a52021-05-05 10:04:47 +0200287 str = "-98.7e-3";
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.0987", jsonctx->value);
292 assert_int_equal(7, jsonctx->value_len);
293 assert_int_equal(1, jsonctx->dynamic);
294 lyjson_ctx_free(jsonctx);
295
296 str = "-98.7e-2";
297 assert_non_null(ly_in_memory(in, str));
298 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
299 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
300 assert_string_equal("-0.987", jsonctx->value);
301 assert_int_equal(6, jsonctx->value_len);
302 assert_int_equal(1, jsonctx->dynamic);
303 lyjson_ctx_free(jsonctx);
304
aPieceka40b4662021-05-13 15:47:03 +0200305 str = "-0.0e-0";
306 assert_non_null(ly_in_memory(in, str));
307 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
308 assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0));
309 assert_string_equal("-0.0", jsonctx->value);
310 assert_int_equal(4, jsonctx->value_len);
311 assert_int_equal(1, jsonctx->dynamic);
312 lyjson_ctx_free(jsonctx);
313
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200314 /* various invalid inputs */
315 str = "-x";
316 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
318 CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200319
320 str = " -";
321 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200322 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
323 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200324
325 str = "--1";
326 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200327 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
328 CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200329
330 str = "+1";
331 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200332 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
333 CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200334
335 str = " 1.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 in JSON Number value (\"x\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200339
340 str = "1.";
341 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200342 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
343 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200344
345 str = " 1eo ";
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 Number value (\"o\").", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200349
350 str = "1e";
351 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200352 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
353 CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200354
355 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200356}
357
Radek Iša447abb82021-03-04 14:08:56 +0100358/* now string is tested in file ./tests/utests/types/string.c */
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200359static void
360test_string(void **state)
361{
362 struct lyjson_ctx *jsonctx;
Radek Iša447abb82021-03-04 14:08:56 +0100363 struct ly_in *in = NULL;
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200364 const char *str;
365
Radek Iša447abb82021-03-04 14:08:56 +0100366 str = "";
367 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
368
369#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200370 /* simple string */
371 str = "\"hello\"";
Radek Iša56ca9e42020-09-08 18:42:00 +0200372 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200373 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
374 assert_ptr_equal(&str[1], jsonctx->value);
375 assert_int_equal(5, jsonctx->value_len);
376 assert_int_equal(0, jsonctx->dynamic);
377 lyjson_ctx_free(jsonctx);
378
379 /* 4-byte utf8 character */
380 str = "\"\\t𠜎\"";
381 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200382 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200383 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
384 assert_string_equal("\t𠜎", jsonctx->value);
385 assert_int_equal(5, jsonctx->value_len);
386 assert_int_equal(1, jsonctx->dynamic);
387 lyjson_ctx_free(jsonctx);
388
389 /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and
390 * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string,
391 * the YANG string type's restrictions apply to the JSON escape sequences */
392 str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\"";
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_STRING, lyjson_ctx_status(jsonctx, 0));
396 assert_string_equal("\" \\ \r / \n \t €", jsonctx->value);
397 assert_int_equal(15, jsonctx->value_len);
398 assert_int_equal(1, jsonctx->dynamic);
399 lyjson_ctx_free(jsonctx);
400
401 /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
402 str = "\"\\b\"";
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 reference \"\\b\" (0x00000008).", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200406
407 str = "\"\\f\"";
408 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200409 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
410 CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100411#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200412
413 /* unterminated string */
414 str = "\"unterminated string";
415 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200416 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
417 CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100418#if 0
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200419 /* invalid escape sequence */
420 str = "\"char \\x \"";
421 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200422 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
423 CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200424
425 /* new line is allowed only as escaped character in JSON */
426 str = "\"\n\"";
427 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200428 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
429 CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1.");
Radek Iša447abb82021-03-04 14:08:56 +0100430#endif
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200431
432 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200433}
434
435static void
436test_object(void **state)
437{
438 struct lyjson_ctx *jsonctx;
439 struct ly_in *in;
440 const char *str;
441
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200442 /* empty */
443 str = " { } ";
444 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200445 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200446 assert_int_equal(LYJSON_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0));
447 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
448 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
449 lyjson_ctx_free(jsonctx);
450
451 /* simple value */
452 str = "{\"name\" : \"Radek\"}";
453 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200454 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200455 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
456 assert_ptr_equal(&str[2], jsonctx->value);
457 assert_int_equal(4, jsonctx->value_len);
458 assert_int_equal(0, jsonctx->dynamic);
459 assert_string_equal("\"Radek\"}", jsonctx->in->current);
460 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
461 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
462 assert_string_equal("Radek\"}", jsonctx->value);
463 assert_int_equal(5, jsonctx->value_len);
464 assert_int_equal(0, jsonctx->dynamic);
465 assert_string_equal("}", jsonctx->in->current);
466 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
467 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
468 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
469 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
470 lyjson_ctx_free(jsonctx);
471
472 /* two values */
473 str = "{\"smart\" : true,\"handsom\":false}";
474 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200475 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200476 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
477 assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value);
478 assert_int_equal(5, jsonctx->value_len);
479 assert_int_equal(0, jsonctx->dynamic);
480 assert_string_equal("true,\"handsom\":false}", jsonctx->in->current);
481 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
482 assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0));
483 assert_string_equal(",\"handsom\":false}", jsonctx->in->current);
484 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
485 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
486 assert_string_equal("handsom\":false}", jsonctx->value);
487 assert_int_equal(7, jsonctx->value_len);
488 assert_int_equal(0, jsonctx->dynamic);
489 assert_string_equal("false}", jsonctx->in->current);
490 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
491 assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0));
492 assert_string_equal("}", jsonctx->in->current);
493 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
494 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
495 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
496 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
497 lyjson_ctx_free(jsonctx);
498
499 /* inherited objects */
500 str = "{\"person\" : {\"name\":\"Radek\"}}";
501 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200502 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200503 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
504 assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value);
505 assert_int_equal(6, jsonctx->value_len);
506 assert_int_equal(0, jsonctx->dynamic);
507 assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current);
508 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
509 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
510 assert_string_equal("name\":\"Radek\"}}", jsonctx->value);
511 assert_int_equal(4, jsonctx->value_len);
512 assert_int_equal(0, jsonctx->dynamic);
513 assert_string_equal("\"Radek\"}}", jsonctx->in->current);
514 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
515 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
516 assert_string_equal("Radek\"}}", jsonctx->value);
517 assert_int_equal(5, jsonctx->value_len);
518 assert_int_equal(0, jsonctx->dynamic);
519 assert_string_equal("}}", jsonctx->in->current);
520 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
521 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
522 assert_string_equal("}", jsonctx->in->current);
523 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
524 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
525 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
526 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
527 lyjson_ctx_free(jsonctx);
528
529 /* new line is allowed only as escaped character in JSON */
530 str = "{ unquoted : \"data\"}";
531 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200532 assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
533 CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200534
535 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200536}
537
538static void
539test_array(void **state)
540{
541 struct lyjson_ctx *jsonctx;
542 struct ly_in *in;
543 const char *str;
544
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200545 /* empty */
546 str = " [ ] ";
547 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200548 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200549 assert_int_equal(LYJSON_ARRAY_EMPTY, 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 /* simple value */
555 str = "[ null]";
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("null]", jsonctx->in->current);
563 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
564 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
565 assert_string_equal("]", jsonctx->in->current);
566 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
567 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
568 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
569 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
570 lyjson_ctx_free(jsonctx);
571
572 /* two values */
573 str = "[{\"a\":null},\"x\"]";
574 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200575 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200576 assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0));
577 assert_null(jsonctx->value);
578 assert_int_equal(0, jsonctx->value_len);
579 assert_int_equal(0, jsonctx->dynamic);
580 assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current);
581 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
582 assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0));
583 assert_string_equal("a\":null},\"x\"]", jsonctx->value);
584 assert_int_equal(1, jsonctx->value_len);
585 assert_int_equal(0, jsonctx->dynamic);
586 assert_string_equal("null},\"x\"]", jsonctx->in->current);
587 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
588 assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0));
589 assert_string_equal("},\"x\"]", jsonctx->in->current);
590 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
591 assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0));
592 assert_string_equal(",\"x\"]", jsonctx->in->current);
593 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
594 assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0));
595 assert_string_equal("x\"]", jsonctx->value);
596 assert_int_equal(1, jsonctx->value_len);
597 assert_int_equal(0, jsonctx->dynamic);
598 assert_string_equal("]", jsonctx->in->current);
599 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
600 assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0));
601 assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL));
602 assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0));
603 lyjson_ctx_free(jsonctx);
604
605 /* new line is allowed only as escaped character in JSON */
606 str = "[ , null]";
607 assert_non_null(ly_in_memory(in, str));
Radek Iša56ca9e42020-09-08 18:42:00 +0200608 assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx));
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200609 assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200610 CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1.");
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200611 lyjson_ctx_free(jsonctx);
612
613 ly_in_free(in, 0);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200614}
615
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100616int
617main(void)
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200618{
619 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200620 UTEST(test_general),
621 UTEST(test_number),
622 UTEST(test_string),
623 UTEST(test_object),
624 UTEST(test_array),
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200625 };
626
Radek Iša56ca9e42020-09-08 18:42:00 +0200627 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejci50f0c6b2020-06-18 16:31:48 +0200628}