9 JSON::errorcode expect
;
13 {"Default constructor", []() {
15 return (x
.type() == JSON::null
);
16 }},{"Explicit null constructor", []() {
17 JSON::node
x(JSON::null
);
18 return (x
.type() == JSON::null
);
19 }},{"Explicit boolean constructor #1", []() {
20 JSON::node
x(JSON::boolean
, false);
21 return (x
.type() == JSON::boolean
);
22 }},{"Explicit boolean constructor #2", []() {
23 JSON::node
x(JSON::boolean
, true);
24 return (x
.type() == JSON::boolean
);
25 }},{"Explicit boolean constructor #3", []() {
26 JSON::node
x(JSON::boolean
, false);
28 }},{"Explicit boolean constructor #4", []() {
29 JSON::node
x(JSON::boolean
, true);
31 }},{"Explicit string constructor #1", []() {
32 JSON::node
x(JSON::string
, U
"foo");
33 return (x
.type() == JSON::string
);
34 }},{"Explicit string constructor #2", []() {
35 JSON::node
x(JSON::string
, U
"bar");
36 return x
.as_string() == U
"bar";
37 }},{"Numeric types #1", []() {
38 JSON::node
x(JSON::number
, (double)0.0);
39 return (x
.type() == JSON::number
);
40 }},{"Numeric types #2", []() {
41 JSON::node
x(JSON::number
, (uint64_t)0);
42 return (x
.type() == JSON::number
);
43 }},{"Numeric types #3", []() {
44 JSON::node
x(JSON::number
, (int64_t)0);
45 return (x
.type() == JSON::number
);
46 }},{"Numeric conversions #1", []() {
47 JSON::node
x(JSON::number
, (double)123.45);
48 return x
.as_double() == 123.45;
49 }},{"Numeric conversions #2", []() {
50 JSON::node
x(JSON::number
, (uint64_t)9223372036854775809ULL);
51 return x
.as_uint() == 9223372036854775809ULL;
52 }},{"Numeric conversions #3", []() {
53 JSON::node
x(JSON::number
, (int64_t)-36028797018963969LL);
54 return x
.as_int() == -36028797018963969LL;
55 }},{"Numeric conversions #4", []() {
56 JSON::node
x(JSON::number
, (double)123.0);
57 return x
.as_uint() == 123;
58 }},{"Numeric conversions #5", []() {
59 JSON::node
x(JSON::number
, (uint64_t)12345);
60 return x
.as_int() == 12345;
61 }},{"Numeric conversions #6", []() {
62 JSON::node
x(JSON::number
, (int64_t)-456);
63 return x
.as_double() == -456;
64 }},{"Numeric conversions #7", []() {
65 JSON::node
x(JSON::number
, (double)-1234.0);
66 return x
.as_int() == -1234;
67 }},{"Numeric conversions #8", []() {
68 JSON::node
x(JSON::number
, (uint64_t)12345);
69 return x
.as_double() == 12345.0;
70 }},{"Numeric conversions #9", []() {
71 JSON::node
x(JSON::number
, (int64_t)456);
72 return x
.as_uint() == 456;
73 }},{"Explicit array constructor", []() {
74 JSON::node
x(JSON::array
);
75 return (x
.type() == JSON::array
);
76 }},{"Explicit object constructor", []() {
77 JSON::node
x(JSON::object
);
78 return (x
.type() == JSON::object
);
79 }},{"Explicit set null", []() {
80 JSON::node
x(JSON::object
);
82 return (x
.type() == JSON::null
);
83 }},{"Explicit set boolean #1", []() {
84 JSON::node
x(JSON::object
);
85 x
.set(JSON::boolean
, false);
86 return (x
.type() == JSON::boolean
);
87 }},{"Explicit set boolean #2", []() {
88 JSON::node
x(JSON::object
);
89 x
.set(JSON::boolean
, true);
90 return (x
.type() == JSON::boolean
);
91 }},{"Explicit set boolean #3", []() {
92 JSON::node
x(JSON::object
);
93 x
.set(JSON::boolean
, false);
95 }},{"Explicit set boolean #4", []() {
96 JSON::node
x(JSON::object
);
97 x
.set(JSON::boolean
, true);
99 }},{"Explicit set number #1", []() {
100 JSON::node
x(JSON::object
);
101 x
.set(JSON::number
, (double)123.45);
102 return (x
.type() == JSON::number
);
103 }},{"Explicit set number #2", []() {
104 JSON::node
x(JSON::object
);
105 x
.set(JSON::number
, (uint64_t)9223372036854775809ULL);
106 return (x
.type() == JSON::number
);
107 }},{"Explicit set number #3", []() {
108 JSON::node
x(JSON::object
);
109 x
.set(JSON::number
, (int64_t)-123);
110 return (x
.type() == JSON::number
);
111 }},{"Explicit set number #4", []() {
112 JSON::node
x(JSON::object
);
113 x
.set(JSON::number
, (double)123.45);
114 return (x
.as_double() == 123.45);
115 }},{"Explicit set number #5", []() {
116 JSON::node
x(JSON::object
);
117 x
.set(JSON::number
, (uint64_t)9223372036854775809ULL);
118 return (x
.as_uint() == 9223372036854775809ULL);
119 }},{"Explicit set number #6", []() {
120 JSON::node
x(JSON::object
);
121 x
.set(JSON::number
, (int64_t)-36028797018963969LL);
122 return (x
.as_int() == -36028797018963969LL);
123 }},{"Explicit set string #1", []() {
124 JSON::node
x(JSON::object
);
125 x
.set(JSON::string
, U
"qux");
126 return (x
.type() == JSON::string
);
127 }},{"Explicit set string #2", []() {
128 JSON::node
x(JSON::object
);
129 x
.set(JSON::string
, U
"zot");
130 return (x
.as_string() == U
"zot");
131 }},{"Non-string as string", []() {
132 JSON::node
x(JSON::object
);
135 }, JSON::ERR_NOT_A_STRING
},{"Non-boolean as boolean", []() {
136 JSON::node
x(JSON::object
);
139 }, JSON::ERR_NOT_A_BOOLEAN
},{"Non-number as number #1", []() {
140 JSON::node
x(JSON::object
);
143 }, JSON::ERR_NOT_A_NUMBER
},{"Non-number as number #2", []() {
144 JSON::node
x(JSON::object
);
147 }, JSON::ERR_NOT_A_NUMBER
},{"Non-number as number #3", []() {
148 JSON::node
x(JSON::object
);
151 }, JSON::ERR_NOT_A_NUMBER
},{"Index count of non-array", []() {
152 JSON::node
x(JSON::object
);
155 }, JSON::ERR_NOT_AN_ARRAY
},{"Index of non-array", []() {
156 JSON::node
x(JSON::object
);
159 }, JSON::ERR_NOT_AN_ARRAY
},{"Index of non-array (const)", []() {
160 JSON::node
x(JSON::object
);
161 const JSON::node
& y
= x
;
164 }, JSON::ERR_NOT_AN_ARRAY
},{"Index count of array #1", []() {
166 return (x
.index_count() == 0);
167 }},{"Index count of array #2", []() {
168 JSON::node
x("[null]");
169 return (x
.index_count() == 1);
170 }},{"Index count of array #3", []() {
171 JSON::node
x("[null,false,true]");
172 return (x
.index_count() == 3);
173 }},{"Index count of array #4", []() {
174 JSON::node
x("[null,[false,true]]");
175 return (x
.index_count() == 2);
176 }},{"Indexing array #1", []() {
177 JSON::node
x("[null,false,true]");
178 return (x
.index(0).type() == JSON::null
);
179 }},{"Indexing array #2", []() {
180 JSON::node
x("[null,false,true]");
181 return !x
.index(1).as_bool();
182 }},{"Indexing array #3", []() {
183 JSON::node
x("[null,false,true]");
184 return x
.index(2).as_bool();
185 }},{"Indexing array out-of-bounds #1", []() {
186 JSON::node
x("[null,false,true]");
189 }, JSON::ERR_INDEX_INVALID
},{"Indexing array out-of-bounds #2", []() {
190 JSON::node
x("[null,false,true]");
193 }, JSON::ERR_INDEX_INVALID
},{"Indexing array out-of-bounds #3", []() {
197 }, JSON::ERR_INDEX_INVALID
},{"Indexing array #1 (const)", []() {
198 JSON::node
x("[null,false,true]");
199 const JSON::node
& y
= x
;
200 return (y
.index(0).type() == JSON::null
);
201 }},{"Indexing array #2 (const)", []() {
202 JSON::node
x("[null,false,true]");
203 const JSON::node
& y
= x
;
204 return !y
.index(1).as_bool();
205 }},{"Indexing array #3 (const)", []() {
206 JSON::node
x("[null,false,true]");
207 const JSON::node
& y
= x
;
208 return y
.index(2).as_bool();
209 }},{"Indexing array out-of-bounds #1 (const)", []() {
210 JSON::node
x("[null,false,true]");
211 const JSON::node
& y
= x
;
214 }, JSON::ERR_INDEX_INVALID
},{"Indexing array out-of-bounds #2 (const)", []() {
215 JSON::node
x("[null,false,true]");
216 const JSON::node
& y
= x
;
219 }, JSON::ERR_INDEX_INVALID
},{"Indexing array out-of-bounds #3 (const)", []() {
221 const JSON::node
& y
= x
;
224 }, JSON::ERR_INDEX_INVALID
},{"Field count of non-object", []() {
225 JSON::node
x("[null,false,true]");
226 x
.field_count(U
"foo");
228 }, JSON::ERR_NOT_AN_OBJECT
},{"Field exists of non-object", []() {
229 JSON::node
x("[null,false,true]");
230 x
.field_exists(U
"foo");
232 }, JSON::ERR_NOT_AN_OBJECT
},{"Field count of found object", []() {
233 JSON::node
x(JSON::object
);
234 x
.insert(U
"foo", JSON::node(JSON::null
));
235 return (x
.field_count(U
"foo") == 1);
236 }},{"Field count of non-found object #1", []() {
237 JSON::node
x(JSON::object
);
238 x
.insert(U
"foo", JSON::node(JSON::null
));
239 return (x
.field_count(U
"bar") == 0);
240 }},{"Field count of non-found object #2", []() {
241 JSON::node
x(JSON::object
);
242 x
.insert(U
"foo", JSON::node(JSON::null
));
243 return (x
.field_count(U
"qux") == 0);
244 }},{"Field exists of found object", []() {
245 JSON::node
x(JSON::object
);
246 x
.insert(U
"foo", JSON::node(JSON::null
));
247 return x
.field_exists(U
"foo");
248 }},{"Field exists of non-found object #1", []() {
249 JSON::node
x(JSON::object
);
250 x
.insert(U
"foo", JSON::node(JSON::null
));
251 return !x
.field_exists(U
"bar");
252 }},{"Field exists of non-found object #2", []() {
253 JSON::node
x(JSON::object
);
254 x
.insert(U
"foo", JSON::node(JSON::null
));
255 return !x
.field_exists(U
"qux");
256 }},{"Field count of duplicate object #1", []() {
257 JSON::node
x(JSON::object
);
258 x
.insert(U
"foo", JSON::node(JSON::null
));
259 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
260 return (x
.field_count(U
"foo") == 2);
261 }},{"Field count of duplicate object #2", []() {
262 JSON::node
x(JSON::object
);
263 x
.insert(U
"foo", JSON::node(JSON::null
));
264 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
265 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
266 return (x
.field_count(U
"foo") == 3);
267 }},{"Field exists of duplicate object #1", []() {
268 JSON::node
x(JSON::object
);
269 x
.insert(U
"foo", JSON::node(JSON::null
));
270 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
271 return x
.field_exists(U
"foo");
272 }},{"Field exists of duplicate object #2", []() {
273 JSON::node
x(JSON::object
);
274 x
.insert(U
"foo", JSON::node(JSON::null
));
275 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
276 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
277 return x
.field_exists(U
"foo");
278 }},{"Field access of non-object", []() {
279 JSON::node
x("[null,false,true]");
282 }, JSON::ERR_NOT_AN_OBJECT
},{"Field access #1", []() {
283 JSON::node
x(JSON::object
);
284 x
.insert(U
"foo", JSON::node(JSON::null
));
285 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
286 return (x
.field(U
"foo").type() == JSON::null
);
287 }},{"Field access #2", []() {
288 JSON::node
x(JSON::object
);
289 x
.insert(U
"foo", JSON::node(JSON::null
));
290 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
291 return !x
.field(U
"bar").as_bool();
292 }},{"Field access #3", []() {
293 JSON::node
x(JSON::object
);
294 x
.insert(U
"foo", JSON::node(JSON::null
));
295 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
296 return (x
.field(U
"foo").type() == JSON::null
);
297 }},{"Field access #4", []() {
298 JSON::node
x(JSON::object
);
299 x
.insert(U
"foo", JSON::node(JSON::null
));
300 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
301 return !x
.field(U
"foo", 1).as_bool();
302 }},{"Field access to invalid key", []() {
303 JSON::node
x(JSON::object
);
304 x
.insert(U
"foo", JSON::node(JSON::null
));
305 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
308 }, JSON::ERR_KEY_INVALID
},{"Field access to invalid index #1", []() {
309 JSON::node
x(JSON::object
);
310 x
.insert(U
"foo", JSON::node(JSON::null
));
311 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
314 }, JSON::ERR_INSTANCE_INVALID
},{"Field access to invalid index #2", []() {
315 JSON::node
x(JSON::object
);
316 x
.insert(U
"foo", JSON::node(JSON::null
));
317 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
320 }, JSON::ERR_INSTANCE_INVALID
},{"Field access of non-object (const)", []() {
321 JSON::node
x("[null,false,true]");
322 const JSON::node
& y
= x
;
325 }, JSON::ERR_NOT_AN_OBJECT
},{"Field access #1 (const)", []() {
326 JSON::node
x(JSON::object
);
327 x
.insert(U
"foo", JSON::node(JSON::null
));
328 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
329 const JSON::node
& y
= x
;
330 return (y
.field(U
"foo").type() == JSON::null
);
331 }},{"Field access #2 (const)", []() {
332 JSON::node
x(JSON::object
);
333 x
.insert(U
"foo", JSON::node(JSON::null
));
334 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
335 const JSON::node
& y
= x
;
336 return !y
.field(U
"bar").as_bool();
337 }},{"Field access #3 (const)", []() {
338 JSON::node
x(JSON::object
);
339 x
.insert(U
"foo", JSON::node(JSON::null
));
340 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
341 const JSON::node
& y
= x
;
342 return (y
.field(U
"foo").type() == JSON::null
);
343 }},{"Field access #4 (const)", []() {
344 JSON::node
x(JSON::object
);
345 x
.insert(U
"foo", JSON::node(JSON::null
));
346 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
347 const JSON::node
& y
= x
;
348 return !y
.field(U
"foo", 1).as_bool();
349 }},{"Field access to invalid key (const)", []() {
350 JSON::node
x(JSON::object
);
351 x
.insert(U
"foo", JSON::node(JSON::null
));
352 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
353 const JSON::node
& y
= x
;
356 }, JSON::ERR_KEY_INVALID
},{"Field access to invalid index #1 (const)", []() {
357 JSON::node
x(JSON::object
);
358 x
.insert(U
"foo", JSON::node(JSON::null
));
359 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
360 const JSON::node
& y
= x
;
363 }, JSON::ERR_INSTANCE_INVALID
},{"Field access to invalid index #2 (const)", []() {
364 JSON::node
x(JSON::object
);
365 x
.insert(U
"foo", JSON::node(JSON::null
));
366 x
.insert(U
"foo", JSON::node(JSON::boolean
, false));
367 const JSON::node
& y
= x
;
370 }, JSON::ERR_INSTANCE_INVALID
},{"Append of non-array", []() {
371 JSON::node
x(JSON::object
);
372 x
.append(JSON::node(JSON::null
));
374 }, JSON::ERR_NOT_AN_ARRAY
},{"Insert of non-object", []() {
375 JSON::node
x("[null,false,true]");
376 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
378 }, JSON::ERR_NOT_AN_OBJECT
},{"Follow #1", []() {
379 JSON::node
x("[null,[false,true]]");
380 return (x
.follow(U
"0").type() == JSON::null
);
381 }},{"Follow #2", []() {
382 JSON::node
x("[null,[false,true]]");
383 return (x
.follow(U
"1").type() == JSON::array
);
384 }},{"Follow #3", []() {
385 JSON::node
x("[null,[false,true]]");
386 return !x
.follow(U
"1/0").as_bool();
387 }},{"Follow #4", []() {
388 JSON::node
x("[null,[false,true]]");
389 return x
.follow(U
"1/1").as_bool();
390 }},{"Follow invalid pointer #1", []() {
391 JSON::node
x("[null,[false,true]]");
394 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #2", []() {
395 JSON::node
x("[null,[false,true]]");
398 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Follow invalid pointer #3", []() {
399 JSON::node
x("[null,[false,true]]");
402 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #4", []() {
403 JSON::node
x("[null,[false,true]]");
406 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #5", []() {
407 JSON::node
x("[null,[false,true]]");
410 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #6", []() {
411 JSON::node
x("[null,[false,true]]");
414 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Follow invalid pointer #7", []() {
415 JSON::node
x("[null,[false,true]]");
418 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #8", []() {
419 JSON::node
x("[null,[false,true]]");
422 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #9", []() {
423 JSON::node
x("[null,[false,true]]");
426 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #10", []() {
427 JSON::node
x("[null,[false,true]]");
430 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #11", []() {
431 JSON::node
x("[null,[false,true]]");
434 }, JSON::ERR_POINTER_INVALID_ESCAPE
},{"Follow invalid pointer #12", []() {
435 JSON::node
x("[null,[false,true]]");
438 }, JSON::ERR_POINTER_TRAILING_ESCAPE
},{"Follow invalid pointer #13", []() {
439 JSON::node
x("[null,[false,true]]");
442 }, JSON::ERR_POINTER_BAD_APPEND
},{"Follow #1 (const)", []() {
443 JSON::node
x("[null,[false,true]]");
444 const JSON::node
& y
= x
;
445 return (y
.follow(U
"0").type() == JSON::null
);
446 }},{"Follow #2 (const)", []() {
447 JSON::node
x("[null,[false,true]]");
448 const JSON::node
& y
= x
;
449 return (y
.follow(U
"1").type() == JSON::array
);
450 }},{"Follow #3 (const)", []() {
451 JSON::node
x("[null,[false,true]]");
452 const JSON::node
& y
= x
;
453 return !y
.follow(U
"1/0").as_bool();
454 }},{"Follow #4 (const)", []() {
455 JSON::node
x("[null,[false,true]]");
456 const JSON::node
& y
= x
;
457 return y
.follow(U
"1/1").as_bool();
458 }},{"Follow invalid pointer #1 (const)", []() {
459 JSON::node
x("[null,[false,true]]");
460 const JSON::node
& y
= x
;
463 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #2 (const)", []() {
464 JSON::node
x("[null,[false,true]]");
465 const JSON::node
& y
= x
;
468 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Follow invalid pointer #3 (const)", []() {
469 JSON::node
x("[null,[false,true]]");
470 const JSON::node
& y
= x
;
473 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #4 (const)", []() {
474 JSON::node
x("[null,[false,true]]");
475 const JSON::node
& y
= x
;
478 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #5 (const)", []() {
479 JSON::node
x("[null,[false,true]]");
480 const JSON::node
& y
= x
;
483 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #6 (const)", []() {
484 JSON::node
x("[null,[false,true]]");
485 const JSON::node
& y
= x
;
488 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Follow invalid pointer #7 (const)", []() {
489 JSON::node
x("[null,[false,true]]");
490 const JSON::node
& y
= x
;
493 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #8 (const)", []() {
494 JSON::node
x("[null,[false,true]]");
495 const JSON::node
& y
= x
;
498 }, JSON::ERR_INDEX_INVALID
},{"Follow invalid pointer #9 (const)", []() {
499 JSON::node
x("[null,[false,true]]");
500 const JSON::node
& y
= x
;
503 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #10 (const)", []() {
504 JSON::node
x("[null,[false,true]]");
505 const JSON::node
& y
= x
;
508 }, JSON::ERR_POINTER_BAD_INDEX
},{"Follow invalid pointer #11 (const)", []() {
509 JSON::node
x("[null,[false,true]]");
510 const JSON::node
& y
= x
;
513 }, JSON::ERR_POINTER_INVALID_ESCAPE
},{"Follow invalid pointer #12 (const)", []() {
514 JSON::node
x("[null,[false,true]]");
515 const JSON::node
& y
= x
;
518 }, JSON::ERR_POINTER_TRAILING_ESCAPE
},{"Follow invalid pointer #13 (const)", []() {
519 JSON::node
x("[null,[false,true]]");
520 const JSON::node
& y
= x
;
523 }, JSON::ERR_POINTER_BAD_APPEND
},{"Follow ~", []() {
524 JSON::node
x(JSON::object
);
525 x
.insert(U
"~", JSON::node(JSON::boolean
, true));
526 return x
.follow(U
"~0").as_bool();
527 }},{"Follow ~ (const)", []() {
528 JSON::node
x(JSON::object
);
529 x
.insert(U
"~", JSON::node(JSON::boolean
, true));
530 const JSON::node
& y
= x
;
531 return y
.follow(U
"~0").as_bool();
532 }},{"Follow nonexistent", []() {
533 JSON::node
x(JSON::object
);
534 x
.insert(U
"~x", JSON::node(JSON::boolean
, true));
535 x
.follow(U
"~0").as_bool();
537 }, JSON::ERR_KEY_INVALID
},{"Follow nonexistent (const)", []() {
538 JSON::node
x(JSON::object
);
539 x
.insert(U
"~x", JSON::node(JSON::boolean
, true));
540 const JSON::node
& y
= x
;
541 y
.follow(U
"~0").as_bool();
543 }, JSON::ERR_KEY_INVALID
},{"Empty string token", []() {
544 JSON::node
x("\"\"");
545 return (x
.as_string() == U
"");
546 }},{"Simple string token", []() {
547 JSON::node
x("\"hello\"");
548 std::cout
<< to_u8string(x
.as_string()) << "..." << std::flush
;
549 return (x
.as_string() == U
"hello");
550 }},{"Simple number token #1", []() {
552 return (x
.as_int() == 123);
553 }},{"Simple number token #2", []() {
554 JSON::node
x("-123");
555 return (x
.as_int() == -123);
556 }},{"Simple number token #3", []() {
557 JSON::node
x("-123.45e2");
558 return (x
.as_int() == -12345);
559 }},{"Simple number token #4", []() {
560 JSON::node
x("-123e2");
561 return (x
.as_int() == -12300);
562 }},{"Bad number token #1", []() {
563 JSON::node
x("123f3");
565 }, JSON::ERR_GARBAGE_AFTER_END
},{"Bad number token #2", []() {
566 JSON::node
x("123e3e3");
568 }, JSON::ERR_GARBAGE_AFTER_END
},{"Bad number token #3", []() {
569 JSON::node
x("123e3.3");
571 }, JSON::ERR_GARBAGE_AFTER_END
},{"Bad number token #4", []() {
572 JSON::node
x("123.3.3");
574 }, JSON::ERR_GARBAGE_AFTER_END
},{"Bad number token #5", []() {
577 }, JSON::ERR_INVALID_NUMBER
},{"Bad number token #6", []() {
580 }, JSON::ERR_INVALID_NUMBER
},{"Bad number token #7", []() {
581 JSON::node
x("-e+6");
583 }, JSON::ERR_INVALID_NUMBER
},{"Bad number token #8", []() {
584 JSON::node
x("-0.5e+");
586 }, JSON::ERR_INVALID_NUMBER
},{"Bad number token #9", []() {
587 JSON::node
x("-0.5e-");
589 }, JSON::ERR_INVALID_NUMBER
},{"Bad number token #10", []() {
592 }, JSON::ERR_GARBAGE_AFTER_END
},{"Hex string escapes", []() {
593 JSON::node
x("\"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef00\"");
594 return (x
.as_string() == U
"\U00000123\U00004567\U000089ab\U0000cdef\U0000abcd\U0000ef00");
595 }},{"Surrogate escape #1", []() {
596 JSON::node
x("\"\\uD800\\uDC00\"");
597 return (x
.as_string() == U
"\U00010000");
598 }},{"Surrogate escape #2", []() {
599 JSON::node
x("\"\\uD800\\uDC01\"");
600 return (x
.as_string() == U
"\U00010001");
601 }},{"Surrogate escape #3", []() {
602 JSON::node
x("\"\\uD801\\uDC02\"");
603 return (x
.as_string() == U
"\U00010402");
604 }},{"Bad hex character", []() {
605 JSON::node
x("\"\\u01g5\"");
607 }, JSON::ERR_BAD_HEX
},{"Bad surrogate escape #1", []() {
608 JSON::node
x("\"\\uD800\"");
610 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #2", []() {
611 JSON::node
x("\"\\uD800\\n\"");
613 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #3", []() {
614 JSON::node
x("\"\\uD800\\u0000\"");
616 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #4", []() {
617 JSON::node
x("\"\\uDC00\\uD800\"");
619 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #5", []() {
620 JSON::node
x("\"\\uDC00\"");
622 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #6", []() {
623 JSON::node
x("\"\\uDC00\\uDC00\"");
625 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #7", []() {
626 JSON::node
x("\"\\uD800Hi\"");
628 }, JSON::ERR_INVALID_SURROGATE
},{"Bad surrogate escape #8", []() {
629 JSON::node
x("\"\\uDC800\"");
631 }, JSON::ERR_INVALID_SURROGATE
},{"Bad string expression #1", []() {
632 JSON::node
x("\"Hi");
634 }, JSON::ERR_TRUNCATED_STRING
},{"Bad string expression #2", []() {
635 JSON::node
x("\"\\n");
637 }, JSON::ERR_TRUNCATED_STRING
},{"Bad escape", []() {
638 JSON::node
x("\"\\e\"");
640 }, JSON::ERR_INVALID_ESCAPE
},{"Escapes", []() {
641 JSON::node
x("\"\\\"\\\\\\/\\b\\f\\r\\n\\t\"");
642 return (x
.as_string() == U
"\"\\/\b\f\r\n\t");
643 }},{"Whitespace", []() {
644 JSON::node
x(" [\t123,\n456,\r789]");
645 return (x
.follow(U
"2").as_int() == 789);
646 }},{"Trailing whitespace", []() {
647 JSON::node
x("123 ");
648 return (x
.as_int() == 123);
649 }},{"Bad string character", []() {
650 JSON::node
x("\"\n\"]");
652 }, JSON::ERR_CONTROL_CHARACTER
},{"Incomplete array #1", []() {
655 }, JSON::ERR_TRUNCATED_JSON
},{"Incomplete array #2", []() {
656 JSON::node
x("[123");
658 }, JSON::ERR_TRUNCATED_JSON
},{"Incomplete array #3", []() {
659 JSON::node
x("[123,");
661 }, JSON::ERR_TRUNCATED_JSON
},{"Incomplete array #4", []() {
662 JSON::node
x("[123,456");
664 }, JSON::ERR_TRUNCATED_JSON
},{"Incomplete object", []() {
667 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #1", []() {
668 JSON::node
x("{\"hi\"");
670 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #2", []() {
671 JSON::node
x("{\"hi\"}");
673 }, JSON::ERR_EXPECTED_COLON
},{"Bad object #3", []() {
674 JSON::node
x("{\"hi\":");
676 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #4", []() {
677 JSON::node
x("{\"hi\"}");
679 }, JSON::ERR_EXPECTED_COLON
},{"Bad object #5", []() {
680 JSON::node
x("{\"hi\":123");
682 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #6", []() {
683 JSON::node
x("{\"hi\":123,");
685 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #7", []() {
686 JSON::node
x("{\"hi\":123,}");
688 }, JSON::ERR_EXPECTED_STRING_KEY
},{"Bad object #8", []() {
689 JSON::node
x("{\"hi\":123,\"fu\"");
691 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #9", []() {
692 JSON::node
x("{\"hi\":123,\"fu\"}");
694 }, JSON::ERR_EXPECTED_COLON
},{"Bad object #10", []() {
695 JSON::node
x("{\"hi\":123,\"fu\":");
697 }, JSON::ERR_TRUNCATED_JSON
},{"Bad object #11", []() {
698 JSON::node
x("{\"hi\":123,\"fu\":}");
700 }, JSON::ERR_UNEXPECTED_RIGHT_BRACE
},{"Bad object #12", []() {
701 JSON::node
x("{\"hi\",123}");
703 }, JSON::ERR_EXPECTED_COLON
},{"Bad object #13", []() {
704 JSON::node
x("{\"hi\"123}");
706 }, JSON::ERR_EXPECTED_COLON
},{"Bad object #14", []() {
707 JSON::node
x("{\"hi\":123:\"fu\":null}");
709 }, JSON::ERR_EXPECTED_COMMA
},{"Bad array", []() {
710 JSON::node
x("[1\"hi\"]");
712 }, JSON::ERR_EXPECTED_COMMA
},{"Bad array #2", []() {
713 JSON::node
x("[123,]");
715 }, JSON::ERR_UNEXPECTED_RIGHT_BRACKET
},{"Bad token #1", []() {
716 JSON::node
x("+123");
718 }, JSON::ERR_UNKNOWN_CHARACTER
},{"Bad token #2", []() {
721 }, JSON::ERR_UNEXPECTED_COMMA
},{"Bad token #3", []() {
724 }, JSON::ERR_UNEXPECTED_RIGHT_BRACE
},{"Bad token #4", []() {
727 }, JSON::ERR_UNEXPECTED_RIGHT_BRACKET
},{"Bad token #5", []() {
730 }, JSON::ERR_UNEXPECTED_COLON
},{"Bad token #6", []() {
733 }, JSON::ERR_UNEXPECTED_RIGHT_BRACE
},{"Bad token #7", []() {
736 }, JSON::ERR_EXPECTED_STRING_KEY
},{"Empty object", []() {
738 return (x
.type() == JSON::object
);
739 }},{"Simple object", []() {
740 JSON::node
x("{\"foo\":\"bar\"}");
741 return (x
.follow(U
"foo").as_string() == U
"bar");
742 }},{"Nested object", []() {
743 JSON::node
x("{\"foo\":{\"bar\":\"baz\"}}");
744 return (x
.follow(U
"foo/bar").as_string() == U
"baz");
745 }},{"Simple object follow escape #1", []() {
746 JSON::node
x("{\"foo~\":\"bar\"}");
747 return (x
.follow(U
"foo~0").as_string() == U
"bar");
748 }},{"Simple object follow escape #2", []() {
749 JSON::node
x("{\"foo/\":\"bar\"}");
750 return (x
.follow(U
"foo~1").as_string() == U
"bar");
751 }},{"Simple object follow escape #3", []() {
752 JSON::node
x("{\"foo~1\":\"bar\"}");
753 return (x
.follow(U
"foo~01").as_string() == U
"bar");
754 }},{"Negative number", []() {
755 JSON::node
x("-123");
756 return (x
.as_int() == -123);
757 }},{"Serialize null", []() {
758 JSON::node
x(JSON::null
);
759 return (x
.serialize() == "null");
760 }},{"Serialize true", []() {
761 JSON::node
x(JSON::boolean
, true);
762 return (x
.serialize() == "true");
763 }},{"Serialize false", []() {
764 JSON::node
x(JSON::boolean
, false);
765 return (x
.serialize() == "false");
766 }},{"Serialize number #1", []() {
767 JSON::node
x(JSON::number
, (int64_t)-123);
768 return (x
.serialize() == "-123");
769 }},{"Serialize number #2", []() {
770 JSON::node
x(JSON::number
, (uint64_t)456);
771 return (x
.serialize() == "456");
772 }},{"Serialize number #3", []() {
773 JSON::node
x(JSON::number
, (double)-12345.7);
774 return (x
.serialize() == "-12345.7");
775 }},{"Serialize simple string", []() {
776 JSON::node
x(JSON::string
, U
"Hello");
777 return (x
.serialize() == "\"Hello\"");
778 }},{"Serialize control characters", []() {
779 JSON::node
x(JSON::string
, U
"\n");
780 return (x
.serialize() == "\"\\n\"");
781 }},{"Serialize backslash", []() {
782 JSON::node
x(JSON::string
, U
"hello\\world");
783 return (x
.serialize() == "\"hello\\\\world\"");
784 }},{"Serialize doublequote", []() {
785 JSON::node
x(JSON::string
, U
"hello\"world");
786 return (x
.serialize() == "\"hello\\\"world\"");
787 }},{"String with 2-byte character", []() {
788 JSON::node
x("\"hello\\u00a4\"");
789 return (x
.serialize() == "\"hello\302\244\"");
790 }},{"String with 3-byte character", []() {
791 JSON::node
x("\"hello\\u1234\"");
792 return (x
.serialize() == "\"hello\341\210\264\"");
793 }},{"String with 4-byte character", []() {
794 JSON::node
x(JSON::string
, U
"hello\U00045678");
795 return (x
.serialize() == "\"hello\361\205\231\270\"");
796 }},{"Serialize empty array", []() {
797 JSON::node
x(JSON::array
);
798 return (x
.serialize() == "[]");
799 }},{"Serialize one-element array", []() {
800 JSON::node
x(JSON::array
);
801 x
.append(JSON::node(JSON::boolean
, true));
802 return (x
.serialize() == "[true]");
803 }},{"Serialize two-element array", []() {
804 JSON::node
x(JSON::array
);
805 x
.append(JSON::node(JSON::boolean
, true));
806 x
.append(JSON::node(JSON::boolean
, false));
807 return (x
.serialize() == "[true,false]");
808 }},{"Serialize three-element array", []() {
809 JSON::node
x(JSON::array
);
810 x
.append(JSON::node(JSON::boolean
, true));
811 x
.append(JSON::node(JSON::boolean
, false));
812 x
.append(JSON::node(JSON::null
));
813 return (x
.serialize() == "[true,false,null]");
814 }},{"Serialize empty object", []() {
815 JSON::node
x(JSON::object
);
816 return (x
.serialize() == "{}");
817 }},{"Serialize one-element object", []() {
818 JSON::node
x(JSON::object
);
819 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
820 return (x
.serialize() == "{\"foo\":true}");
821 }},{"Serialize two-element object", []() {
822 JSON::node
x(JSON::object
);
823 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
824 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
825 return (x
.serialize() == "{\"bar\":false,\"foo\":true}");
826 }},{"Serialize three-element object", []() {
827 JSON::node
x(JSON::object
);
828 x
.insert(U
"foo", JSON::node(JSON::boolean
, true));
829 x
.insert(U
"bar", JSON::node(JSON::boolean
, false));
830 x
.insert(U
"baz", JSON::node(JSON::null
));
831 return (x
.serialize() == "{\"bar\":false,\"baz\":null,\"foo\":true}");
832 }},{"Self-Assignment", []() {
833 JSON::node
x("true");
836 }},{"Create node #1", []() {
838 x
["foo"] = JSON::node(JSON::string
, U
"bar");
839 return (x
["foo"].as_string() == U
"bar");
840 }},{"Create node #2", []() {
842 x
["0"] = JSON::node(JSON::string
, U
"bar");
843 return (x
["0"].as_string() == U
"bar");
844 }},{"Create node #3", []() {
846 x
["-"] = JSON::node(JSON::string
, U
"bar");
847 return (x
["0"].as_string() == U
"bar");
848 }},{"Create node error #1", []() {
850 x
["-/0"] = JSON::node(JSON::string
, U
"bar");
852 }, JSON::ERR_POINTER_BAD_APPEND
},{"Create node error #2", []() {
854 x
["1"] = JSON::node(JSON::string
, U
"bar");
856 }, JSON::ERR_POINTER_BAD_APPEND
},{"Create node error #3", []() {
857 JSON::node
x("false");
858 x
["0"] = JSON::node(JSON::string
, U
"bar");
860 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Parsing one null", []() {
861 JSON::node
x("null");
862 return (x
.type() == JSON::null
);
863 }},{"Type of false", []() {
864 JSON::node
x("false");
865 return (x
.type() == JSON::boolean
);
866 }},{"Type of true", []() {
867 JSON::node
x("true");
868 return (x
.type() == JSON::boolean
);
869 }},{"Value of false", []() {
870 JSON::node
x("false");
872 }},{"Value of true", []() {
873 JSON::node
x("true");
876 JSON::node x
= JSON::n();
877 return (x
.type() == JSON::null
);
878 }},{"_bool()", []() {
879 JSON::node x
= JSON::b(true);
881 }},{"_double()", []() {
882 JSON::node x
= JSON::f(123.45);
883 return (x
.as_double() == 123.45);
885 JSON::node x
= JSON::i(-36028797018963969LL);
886 return (x
.as_int() == -36028797018963969LL);
887 }},{"_uint()", []() {
888 JSON::node x
= JSON::u(9223372036854775809ULL);
889 return (x
.as_uint() == 9223372036854775809ULL);
890 }},{"_string()", []() {
891 JSON::node x
= JSON::s(U
"foo");
892 return (x
.as_string() == U
"foo");
893 }},{"array()", []() {
894 JSON::node x
= JSON::array();
895 return (x
.type() == JSON::array
);
896 }},{"object()", []() {
897 JSON::node x
= JSON::object();
898 return (x
.type() == JSON::object
);
899 }},{"Array iteration", []() {
900 JSON::node
x("[\"ABC\",\"DEF\",\"GHI\"]");
905 return (y
== U
"ABCDEFGHI");
906 }},{"Object iteration", []() {
907 JSON::node
x("{\"2\":\"ABC\",\"1\":\"DEF\",\"0\":\"GHI\"}");
912 return (y
== U
"GHIDEFABC");
913 }},{"Empty Array iteration", []() {
920 }},{"Empty Object iteration", []() {
927 }},{"Boolean iteration", []() {
928 JSON::node
x("false");
931 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Array iteration (const)", []() {
932 JSON::node
_x("[\"ABC\",\"DEF\",\"GHI\"]");
933 const JSON::node
& x
= _x
;
938 return (y
== U
"ABCDEFGHI");
939 }},{"Object iteration (const)", []() {
940 JSON::node
_x("{\"2\":\"ABC\",\"1\":\"DEF\",\"0\":\"GHI\"}");
941 const JSON::node
& x
= _x
;
946 return (y
== U
"GHIDEFABC");
947 }},{"Empty Array iteration (const)", []() {
949 const JSON::node
& x
= _x
;
955 }},{"Empty Object iteration (const)", []() {
957 const JSON::node
& x
= _x
;
963 }},{"Boolean iteration (const)", []() {
964 JSON::node
_x("false");
965 const JSON::node
& x
= _x
;
968 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Keyed array iteration", []() {
969 JSON::node
x("[\"ABC\",\"DEF\",\"GHI\"]");
970 const char32_t
* str
[] = {U
"ABC", U
"DEF", U
"GHI"};
971 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
974 if(i
->as_string() != str
[i
.index()])
978 }},{"Keyed array iteration (const)", []() {
979 JSON::node
_x("[\"ABC\",\"DEF\",\"GHI\"]");
980 const JSON::node
& x
= _x
;
981 const char32_t
* str
[] = {U
"ABC", U
"DEF", U
"GHI"};
982 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
985 if(i
->as_string() != str
[i
.index()])
989 }},{"Keyed object iteration (key)", []() {
990 JSON::node
x("{\"ABC\":\"DEF\"}");
991 for(auto i
= x
.begin(); i
!= x
.end(); i
++)
992 return (i
.key() == U
"ABC");
994 }},{"Keyed object iteration (key, const)", []() {
995 JSON::node
_x("{\"ABC\":\"DEF\"}");
996 const JSON::node
& x
= _x
;
997 for(auto i
= x
.begin(); i
!= x
.end(); i
++)
998 return (i
.key() == U
"ABC");
1000 }},{"Keyed array iteration (key)", []() {
1001 JSON::node
x("[\"ABC\",\"DEF\"]");
1002 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
1007 }},{"Keyed array iteration (key, const)", []() {
1008 JSON::node
_x("[\"ABC\",\"DEF\"]");
1009 const JSON::node
& x
= _x
;
1010 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
1015 }},{"Keyed object iteration", []() {
1016 JSON::node
x("{\"2\":\"ABC\",\"1\":\"DEF\",\"0\":\"GHI\"}");
1017 const char32_t
* str
[] = {U
"GHI", U
"DEF", U
"ABC"};
1018 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
1019 size_t idx
= parse_value
<size_t>(to_u8string(i
.key()));
1020 if(i
->as_string() != str
[idx
])
1024 }},{"Keyed object iteration (Const)", []() {
1025 JSON::node
_x("{\"2\":\"ABC\",\"1\":\"DEF\",\"0\":\"GHI\"}");
1026 const JSON::node
& x
= _x
;
1027 const char32_t
* str
[] = {U
"GHI", U
"DEF", U
"ABC"};
1028 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
1029 size_t idx
= parse_value
<size_t>(to_u8string(i
.key()));
1030 if(i
->as_string() != str
[idx
])
1034 }},{"End-of-object iterator (array)", []() {
1037 try { i
.key(); return false; } catch(...) {}
1038 try { i
.index(); return false; } catch(...) {}
1039 try { *i
; return false; } catch(...) {}
1040 try { i
->type(); return false; } catch(...) {}
1041 try { i
++; return false; } catch(...) {}
1042 try { ++i
; return false; } catch(...) {}
1043 return (i
== x
.end()) && !(i
!= x
.end());
1044 }},{"End-of-object iterator (object)", []() {
1047 try { i
.key(); return false; } catch(...) {}
1048 try { i
.index(); return false; } catch(...) {}
1049 try { *i
; return false; } catch(...) {}
1050 try { i
->type(); return false; } catch(...) {}
1051 try { i
++; return false; } catch(...) {}
1052 try { ++i
; return false; } catch(...) {}
1053 return (i
== x
.end()) && !(i
!= x
.end());
1054 }},{"End-of-object iterator (array, const)", []() {
1055 JSON::node
_x("[]");
1056 const JSON::node
& x
= _x
;
1058 try { i
.key(); return false; } catch(...) {}
1059 try { i
.index(); return false; } catch(...) {}
1060 try { *i
; return false; } catch(...) {}
1061 try { i
->type(); return false; } catch(...) {}
1062 try { i
++; return false; } catch(...) {}
1063 try { ++i
; return false; } catch(...) {}
1064 return (i
== x
.end()) && !(i
!= x
.end());
1065 }},{"End-of-object iterator (object, const)", []() {
1066 JSON::node
_x("{}");
1067 const JSON::node
& x
= _x
;
1069 try { i
.key(); return false; } catch(...) {}
1070 try { i
.index(); return false; } catch(...) {}
1071 try { *i
; return false; } catch(...) {}
1072 try { i
->type(); return false; } catch(...) {}
1073 try { i
++; return false; } catch(...) {}
1074 try { ++i
; return false; } catch(...) {}
1075 return (i
== x
.end()) && !(i
!= x
.end());
1076 }},{"Iterators to different objects are not equal", []() {
1077 JSON::node
x("[1234]");
1078 JSON::node
y("[1234]");
1079 return (x
.begin() != y
.begin());
1080 }},{"Iterators to different objects are not equal (const)", []() {
1081 JSON::node
_x("[1234]");
1082 JSON::node
_y("[1234]");
1083 const JSON::node
& x
= _x
;
1084 const JSON::node
& y
= _y
;
1085 return (x
.begin() != y
.begin());
1086 }},{"Iterators to the same object are equal", []() {
1087 JSON::node
x("[1234]");
1088 return (x
.begin() == x
.begin());
1089 }},{"Iterators to the same object are equal (const)", []() {
1090 JSON::node
_x("[1234]");
1091 const JSON::node
& x
= _x
;
1092 return (x
.begin() == x
.begin());
1093 }},{"Iterators to different elements are not equal", []() {
1094 JSON::node
x("[1, 2]");
1107 }},{"Iterators to different elements are not equal (const)", []() {
1108 JSON::node
_x("[1, 2]");
1109 const JSON::node
& x
= _x
;
1122 }},{"Iterators to different instances of key are not equal", []() {
1123 JSON::node
x("{\"foo\":1,\"foo\":2}");
1127 if(i
.key() != U
"foo")
1129 if(j
.key() != U
"foo")
1136 }},{"Iterators to different instances of key are not equal (const)", []() {
1137 JSON::node
_x("{\"foo\":1,\"foo\":2}");
1138 const JSON::node
& x
= _x
;
1142 if(i
.key() != U
"foo")
1144 if(j
.key() != U
"foo")
1151 }},{"Iterators to different keys are not equal", []() {
1152 JSON::node
x("{\"foo\":1,\"foz\":2}");
1156 if(i
.key() != U
"foo")
1158 if(j
.key() != U
"foz")
1165 }},{"Iterators to different keys are not equal (const)", []() {
1166 JSON::node
_x("{\"foo\":1,\"foz\":2}");
1167 const JSON::node
& x
= _x
;
1171 if(i
.key() != U
"foo")
1173 if(j
.key() != U
"foz")
1180 }},{"Serialize multiple", []() {
1181 JSON::node
x("{\"foo\":1,\"foo\":2}");
1182 return (x
.serialize() == "{\"foo\":1,\"foo\":2}");
1183 }},{"Serialize multiple #2", []() {
1184 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1185 return (x
.serialize() == "{\"foo\":1,\"foo\":2,\"foz\":3}");
1186 }},{"erase index from end", []() {
1187 JSON::node
x("[1,2,3]");
1192 return (x
.serialize() == "[1,2]");
1193 }},{"erase index from middle", []() {
1194 JSON::node
x("[1,2,3]");
1198 return (x
.serialize() == "[1,3]");
1199 }},{"erase index from start", []() {
1200 JSON::node
x("[1,2,3]");
1203 return (x
.serialize() == "[2,3]");
1204 }},{"erase index from middle and iterate", []() {
1205 JSON::node
x("[1,2,3]");
1209 return (i
->as_int() == 3);
1210 }},{"erase index from end and iterate", []() {
1211 JSON::node
x("[1,2,3]");
1216 return (i
== x
.end());
1217 }},{"erase_index past end", []() {
1218 JSON::node
x("[1,2,3]");
1220 return (x
.serialize() == "[1,2,3]");
1221 }},{"erase_index on object", []() {
1225 }, JSON::ERR_NOT_AN_ARRAY
},{"erase index on boolean", []() {
1226 JSON::node
x("[3]");
1228 x
.set(JSON::boolean
, false);
1231 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"erase index from wrong thing", []() {
1232 JSON::node
x("[1,2,3]");
1233 JSON::node
y("[1,2,3]");
1237 }, JSON::ERR_WRONG_OBJECT
},{"erase field on boolean", []() {
1238 JSON::node
x("false");
1239 x
.erase_field(U
"foo");
1241 }, JSON::ERR_NOT_AN_OBJECT
},{"erase field all on boolean", []() {
1242 JSON::node
x("false");
1243 x
.erase_field_all(U
"foo");
1245 }, JSON::ERR_NOT_AN_OBJECT
},{"erase key", []() {
1246 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1250 return (x
.serialize() == "{\"foo\":1,\"foz\":3}");
1251 }},{"erase_field_all", []() {
1252 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1253 x
.erase_field_all(U
"foo");
1254 return (x
.serialize() == "{\"foz\":3}");
1255 }},{"erase_field_all (does not exist)", []() {
1256 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1257 x
.erase_field_all(U
"fou");
1258 return (x
.serialize() == "{\"foo\":1,\"foo\":2,\"foz\":3}");
1259 }},{"erase_field (does not exist)", []() {
1260 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1261 x
.erase_field(U
"fou");
1262 return (x
.serialize() == "{\"foo\":1,\"foo\":2,\"foz\":3}");
1263 }},{"erase_field (first)", []() {
1264 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1265 x
.erase_field(U
"foo");
1266 return (x
.serialize() == "{\"foo\":2,\"foz\":3}");
1267 }},{"erase_field (second)", []() {
1268 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1269 x
.erase_field(U
"foo", 1);
1270 return (x
.serialize() == "{\"foo\":1,\"foz\":3}");
1271 }},{"erase_field (subsequent)", []() {
1272 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1273 x
.erase_field(U
"foo", 2);
1274 return (x
.serialize() == "{\"foo\":1,\"foo\":2,\"foz\":3}");
1275 }},{"erase key and iterate", []() {
1276 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1280 return (i
.key() == U
"foz" && i
->as_int() == 3);
1281 }},{"erase key (disappears)", []() {
1282 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1287 return (x
.serialize() == "{\"foo\":1,\"foo\":2}");
1288 }},{"clear object", []() {
1289 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1291 return (x
.serialize() == "{}");
1292 }},{"clear array", []() {
1293 JSON::node
x("[1,2,3]");
1295 return (x
.serialize() == "[]");
1296 }},{"clear boolean", []() {
1297 JSON::node
x("false");
1300 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"iterator on deleted index", []() {
1301 JSON::node
x("[1,2,3]");
1308 }, JSON::ERR_ITERATOR_DELETED
},{"iterator on deleted index (const)", []() {
1309 JSON::node
_x("[1,2,3]");
1310 const JSON::node
& x
= _x
;
1317 }, JSON::ERR_ITERATOR_DELETED
},{"iterator on deleted key", []() {
1318 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1322 x
.erase_field(U
"foz");
1325 }, JSON::ERR_ITERATOR_DELETED
},{"iterator on deleted key (const)", []() {
1326 JSON::node
_x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1327 const JSON::node
& x
= _x
;
1331 _x
.erase_field(U
"foz");
1334 }, JSON::ERR_ITERATOR_DELETED
},{"iterator on deleted key-instance", []() {
1335 JSON::node
x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1338 x
.erase_field(U
"foo",0);
1341 }, JSON::ERR_ITERATOR_DELETED
},{"iterator on deleted key-instance (const)", []() {
1342 JSON::node
_x("{\"foo\":1,\"foo\":2,\"foz\":3}");
1343 const JSON::node
& x
= _x
;
1346 _x
.erase_field(U
"foo",0);
1349 }, JSON::ERR_ITERATOR_DELETED
},{"Illegal character #1", []() {
1350 JSON::node
x("\"\\uFFFE\"");
1352 }, JSON::ERR_ILLEGAL_CHARACTER
},{"Illegal character #2", []() {
1353 JSON::node
x("\"\\uFFFF\"");
1355 }, JSON::ERR_ILLEGAL_CHARACTER
},{"Illegal character #3", []() {
1356 JSON::node
x("\"\\uD87F\\uDFFE\"");
1358 }, JSON::ERR_ILLEGAL_CHARACTER
},{"U+F800", []() {
1359 JSON::node
x("\"\\uF800\"");
1361 }},{"Special escapes", []() {
1362 JSON::node
x("\"\\b\\f\\n\\r\\t\\\"\\\\\\u007F\u0080\"");
1363 return (x
.serialize() == "\"\\b\\f\\n\\r\\t\\\"\\\\\x7F\xc2\x80\"");
1364 }},{"\\v is not whitespace", []() {
1365 JSON::node
x(" [\v123]");
1367 }, JSON::ERR_UNKNOWN_CHARACTER
},{"null==null", []() -> bool {
1368 return JSON::n() == JSON::n();
1369 }},{"false==false", []() -> bool {
1370 return JSON::b(false) == JSON::b(false);
1371 }},{"true==true", []() -> bool {
1372 return JSON::b(true) == JSON::b(true);
1373 }},{"null!=false", []() -> bool {
1374 return JSON::b(false) != JSON::n();
1375 }},{"\"foo\"==\"foo\"", []() -> bool {
1376 return JSON::s("foo") == JSON::s("foo");
1377 }},{"\"foo\"==U\"foo\"", []() -> bool {
1378 return JSON::s("foo") == JSON::s(U
"foo");
1379 }},{"\"foo\"!=\"bar\"", []() -> bool {
1380 return JSON::s("foo") != JSON::s("bar");
1381 }},{"1==1", []() -> bool {
1382 return JSON::i(1) == JSON::i(1);
1383 }},{"1==(uint)1", []() -> bool {
1384 return JSON::i(1) == JSON::u(1U);
1385 }},{"1==1.0", []() -> bool {
1386 return JSON::i(1) == JSON::f(1.0);
1387 }},{"-1.25!=-1", []() -> bool {
1388 return JSON::f(-1.25) != JSON::i(-1);
1389 }},{"1.25!=1U", []() -> bool {
1390 return JSON::f(1.25) != JSON::u(1);
1391 }},{"1.25!=1.5", []() -> bool {
1392 return JSON::f(1.25) != JSON::f(1.5);
1393 }},{"(uint)1==1.0", []() -> bool {
1394 return JSON::u(1) == JSON::f(1.0);
1395 }},{"1!=2", []() -> bool {
1396 return JSON::i(1) != JSON::i(2);
1397 }},{"-1!=0xFFFFFFFFFFFFFFFFULL", []() -> bool {
1398 return JSON::i(-1) != JSON::u(0xFFFFFFFFFFFFFFFFULL
);
1399 }},{"0xFFFFFFFFFFFFFFFFULL!=-1", []() -> bool {
1400 return JSON::u(0xFFFFFFFFFFFFFFFFULL
) != JSON::i(-1);
1401 }},{"1!=\1\1", []() -> bool {
1402 return JSON::i(1) != JSON::s("1");
1403 }},{"false!=0", []() -> bool {
1404 return JSON::b(false) != JSON::i(0);
1405 }},{"true!=1", []() -> bool {
1406 return JSON::b(true) != JSON::i(1);
1407 }},{"{}!=[]", []() -> bool {
1408 return JSON::node("{}") != JSON::node("[]");
1409 }},{"{}=={}", []() -> bool {
1410 return JSON::node("{}") == JSON::node("{}");
1411 }},{"[]==[]", []() -> bool {
1412 return JSON::node("[]") == JSON::node("[]");
1413 }},{"[1,2,3]==[1,2,3]", []() -> bool {
1414 return JSON::node("[1,2,3]") == JSON::node("[1,2,3]");
1415 }},{"[1,2,3]!=[1,2,4]", []() -> bool {
1416 return JSON::node("[1,2,3]") != JSON::node("[1,2,4]");
1417 }},{"[1,2,\"hi\"]==[1,2,\"hi\"]", []() -> bool {
1418 return JSON::node("[1,2,\"hi\"]") == JSON::node("[1,2,\"hi\"]");
1419 }},{"[1,2,[4,5]]==[1,2,[4,5]]", []() -> bool {
1420 return JSON::node("[1,2,[4,5]]") == JSON::node("[1,2,[4,5]]");
1421 }},{"[1,2,[4,6]]!=[1,2,[4,5]]", []() -> bool {
1422 return JSON::node("[1,2,[4,6]]") != JSON::node("[1,2,[4,5]]");
1423 }},{"[1,2,3]!=[1,2]", []() -> bool {
1424 return JSON::node("[1,2,3]") != JSON::node("[1,2]");
1425 }},{"[1,2]!=[1,2,3]", []() -> bool {
1426 return JSON::node("[1,2]") != JSON::node("[1,2,3]");
1427 }},{"{\"foo\": 1}=={\"foo\": 1}", []() -> bool {
1428 return JSON::node("{\"foo\": 1}") == JSON::node("{\"foo\": 1}");
1429 }},{"{\"foo\": [1,2]}=={\"foo\": [1,2]}", []() -> bool {
1430 return JSON::node("{\"foo\": [1,2]}") == JSON::node("{\"foo\": [1,2]}");
1431 }},{"{\"foo\": [1,2]}!={\"foo\": [1,3]}", []() -> bool {
1432 return JSON::node("{\"foo\": [1,2]}") != JSON::node("{\"foo\": [1,3]}");
1433 }},{"{\"foo\": 1}!={\"bar\": 1}", []() -> bool {
1434 return JSON::node("{\"foo\": 1}") != JSON::node("{\"bar\": 1}");
1435 }},{"{\"foo\": 1}!={\"foo\": 1, \"x\": 2}", []() -> bool {
1436 return JSON::node("{\"foo\": 1}") != JSON::node("{\"foo\": 1, \"x\": 2}");
1437 }},{"{\"foo\": 1, \"x\": 2}!={\"foo\": 1}", []() -> bool {
1438 return JSON::node("{\"foo\": 1, \"x\": 2}") != JSON::node("{\"foo\": 1}");
1439 }},{"{\"foo\": 1}!={\"foo\": 2}", []() -> bool {
1440 return JSON::node("{\"foo\": 1}") != JSON::node("{\"foo\": 2}");
1441 }},{"{\"foo\": 1,\"foo\": 2}=={\"foo\": 1,\"foo\": 2}", []() -> bool {
1442 return JSON::node("{\"foo\": 1,\"foo\": 2}") == JSON::node("{\"foo\": 1,\"foo\": 2}");
1443 }},{"{\"foo\": 1,\"foo\": 2}!={\"foo\": 2,\"foo\": 1}", []() -> bool {
1444 return JSON::node("{\"foo\": 1,\"foo\": 2}") != JSON::node("{\"foo\": 2,\"foo\": 1}");
1445 }},{"{\"foo\": 1,\"foo\": 2}!={\"foo\": 1}", []() -> bool {
1446 return JSON::node("{\"foo\": 1,\"foo\": 2}") != JSON::node("{\"foo\": 1}");
1447 }},{"{\"foo\": 1}!={\"foo\": 1,\"foo\": 2}", []() -> bool {
1448 return JSON::node("{\"foo\": 1}") != JSON::node("{\"foo\": 1,\"foo\": 2}");
1449 }},{"Escape U+0012", []() {
1450 JSON::node
x("\"\\u0012\"");
1451 return (x
.serialize() == "\"\\u0012\"");
1452 }},{"Escape U+001F", []() {
1453 JSON::node
x("\"\\u001F\"");
1454 return (x
.serialize() == "\"\\u001f\"");
1455 }},{"Compare itself", []() {
1456 JSON::node
x("\"\\u001F\"");
1458 }},{"Boolean not null", []() {
1459 JSON::node
x("false");
1460 return x
.type() != JSON::null
;
1461 }},{"Insert_node to empty array with -", []() {
1463 x
.insert_node("-", JSON::i(1));
1464 return x
.serialize() == "[1]";
1465 }},{"Insert_node to empty array with 0", []() {
1467 x
.insert_node("0", JSON::i(1));
1468 return x
.serialize() == "[1]";
1469 }},{"Insert_node to end of non-empty array with -", []() {
1470 JSON::node
x("[1,2,3]");
1471 x
.insert_node("-", JSON::i(4));
1472 return x
.serialize() == "[1,2,3,4]";
1473 }},{"Insert_node to end of non-empty array with index", []() {
1474 JSON::node
x("[1,2,3]");
1475 x
.insert_node("3", JSON::i(4));
1476 return x
.serialize() == "[1,2,3,4]";
1477 }},{"Insert_node to middle of non-empty array", []() {
1478 JSON::node
x("[1,2,4]");
1479 x
.insert_node("2", JSON::i(3));
1480 return x
.serialize() == "[1,2,3,4]";
1481 }},{"Insert_node to middle of nested array", []() {
1482 JSON::node
x("[[1,2,4]]");
1483 x
.insert_node("0/2", JSON::i(3));
1484 return x
.serialize() == "[[1,2,3,4]]";
1485 }},{"Insert_node to invalid array", []() {
1486 JSON::node
x("[[1,2,4]]");
1487 x
.insert_node("1/2", JSON::i(3));
1489 }, JSON::ERR_INDEX_INVALID
},{"Insert_node to boolean", []() {
1490 JSON::node
x("false");
1491 x
.insert_node("0", JSON::i(4));
1493 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Insert_node to empty object", []() {
1495 x
.insert_node("foo",JSON::i(1));
1496 return x
.serialize() == "{\"foo\":1}";
1497 }},{"Insert_node to non-empty object", []() {
1498 JSON::node
x("{\"bar\":2}");
1499 x
.insert_node("foo", JSON::i(1));
1500 return x
.serialize() == "{\"bar\":2,\"foo\":1}";
1501 }},{"Insert_node to replacing entry in object", []() {
1502 JSON::node
x("{\"foo\":2}");
1503 x
.insert_node("foo", JSON::i(1));
1504 return x
.serialize() == "{\"foo\":1}";
1505 }},{"Insert_node to replacing entries in object", []() {
1506 JSON::node
x("{\"foo\":1,\"foo\":2}");
1507 x
.insert_node("foo", JSON::i(3));
1508 return x
.serialize() == "{\"foo\":3,\"foo\":2}";
1509 }},{"Insert_node returns object #1", []() {
1510 JSON::node
x("{\"bar\":2}");
1511 JSON::node
& y
= x
.insert_node("foo", JSON::s("TEST"));
1512 return y
.serialize() == "\"TEST\"";
1513 }},{"Insert_node returns object #2", []() {
1515 JSON::node
& y
= x
.insert_node("0", JSON::s("TEST"));
1516 return y
.serialize() == "\"TEST\"";
1517 }},{"Insert_node returns object #3", []() {
1519 JSON::node
& y
= x
.insert_node("-", JSON::s("TEST"));
1520 return y
.serialize() == "\"TEST\"";
1521 }},{"Insert_node returns object #4", []() {
1522 JSON::node
x("[1]");
1523 JSON::node
& y
= x
.insert_node("-", JSON::s("TEST"));
1524 return y
.serialize() == "\"TEST\"";
1525 }},{"Insert_node to index too large", []() {
1526 JSON::node
x("[[1,2,4]]");
1527 x
.insert_node("0/5", JSON::i(5));
1529 }, JSON::ERR_POINTER_BAD_APPEND
},{"delete_node to boolean", []() {
1530 JSON::node
x("false");
1533 }, JSON::ERR_NOT_ARRAY_NOR_OBJECT
},{"Delete_node to middle of non-empty array", []() {
1534 JSON::node
x("[1,2,3,4]");
1536 return x
.serialize() == "[1,2,4]";
1537 }},{"Delete_node to middle of nested array", []() {
1538 JSON::node
x("[[1,2,3,4]]");
1539 x
.delete_node("0/2");
1540 return x
.serialize() == "[[1,2,4]]";
1541 }},{"Delete_node to invalid array", []() {
1542 JSON::node
x("[[1,2,3,4]]");
1543 x
.delete_node("1/2");
1545 }, JSON::ERR_INDEX_INVALID
},{"Delete_node returns object", []() {
1546 JSON::node
x("{\"bar\":\"test!\"}");
1547 JSON::node y
= x
.delete_node("bar");
1548 return y
.serialize() == "\"test!\"";
1549 }},{"Delete_node returns object #2", []() {
1550 JSON::node
x("[1,\"test!\"]");
1551 JSON::node y
= x
.delete_node("1");
1552 return y
.serialize() == "\"test!\"";
1553 }},{"Delete_node to deleting entry in object", []() {
1554 JSON::node
x("{\"bar\":1,\"foo\":2}");
1555 x
.delete_node("foo");
1556 return x
.serialize() == "{\"bar\":1}";
1557 }},{"Delete_node to deleting entries in object", []() {
1558 JSON::node
x("{\"bar\":1,\"foo\":2,\"foo\":3}");
1559 x
.delete_node("foo");
1560 return x
.serialize() == "{\"bar\":1}";
1561 }},{"Delete_node to invalid key in object", []() {
1562 JSON::node
x("{\"bar\":1,\"foo\":2}");
1563 x
.delete_node("foz");
1565 }, JSON::ERR_KEY_INVALID
},{"Delete_node to invalid index", []() {
1566 JSON::node
x("[1,2,3,4]");
1569 }, JSON::ERR_INDEX_INVALID
},{"Delete_node to index -", []() {
1570 JSON::node
x("[1,2,3,4]");
1573 }, JSON::ERR_POINTER_BAD_APPEND
},{"operator[] on bad index", []() {
1574 JSON::node
x("[1,2,3,4]");
1577 }, JSON::ERR_POINTER_BAD_INDEX
},{"insert_node on bad index", []() {
1578 JSON::node
x("[1,2,3,4]");
1579 x
.insert_node("f", JSON::b(false));
1581 }, JSON::ERR_POINTER_BAD_INDEX
},{"delete_node on bad index", []() {
1582 JSON::node
x("[1,2,3,4]");
1585 }, JSON::ERR_POINTER_BAD_INDEX
},{"patching with an object", []() {
1586 JSON::node
x("[1,2,3,4]");
1590 }, JSON::ERR_PATCH_BAD
},{"Duplicate op", []() {
1591 JSON::node
x("[1,2,3,4]");
1592 JSON::node
y("[{\"op\":\"test\",\"path\":\"3\",\"value\":4,\"op\":\"add\"}]");
1595 }, JSON::ERR_PATCH_BAD
},{"simple test", []() {
1596 JSON::node
x("[1,2,3,4]");
1597 JSON::node
y("[{\"op\":\"test\",\"path\":\"3\",\"value\":4}]");
1598 JSON::node z
= x
.patch(y
);
1600 }},{"simple failed test", []() {
1601 JSON::node
x("[1,2,3,4]");
1602 JSON::node
y("[{\"op\":\"test\",\"path\":\"3\",\"value\":3}]");
1605 }, JSON::ERR_PATCH_TEST_FAILED
},{"test dupe path", []() {
1606 JSON::node
x("[1,2,3,4]");
1607 JSON::node
y("[{\"op\":\"test\",\"path\":\"3\",\"path\":\"2\",\"value\":3}]");
1610 }, JSON::ERR_PATCH_BAD
},{"test number path", []() {
1611 JSON::node
x("[1,2,3,4]");
1612 JSON::node
y("[{\"op\":\"test\",\"path\":3,\"value\":4}]");
1615 }, JSON::ERR_PATCH_BAD
},{"test dupe value", []() {
1616 JSON::node
x("[1,2,3,4]");
1617 JSON::node
y("[{\"op\":\"test\",\"path\":\"3\",\"value\":\"2\",\"value\":3}]");
1620 }, JSON::ERR_PATCH_BAD
},{"simple remove", []() {
1621 JSON::node
x("[1,2,3,4]");
1622 JSON::node
y("[{\"op\":\"remove\",\"path\":\"2\"}]");
1623 JSON::node z
= x
.patch(y
);
1624 return z
.serialize() == "[1,2,4]";
1625 }},{"remove dupe path", []() {
1626 JSON::node
x("[1,2,3,4]");
1627 JSON::node
y("[{\"op\":\"remove\",\"path\":\"2\",\"path\":\"3\"}]");
1628 JSON::node z
= x
.patch(y
);
1630 }, JSON::ERR_PATCH_BAD
},{"remove numeric path", []() {
1631 JSON::node
x("[1,2,3,4]");
1632 JSON::node
y("[{\"op\":\"remove\",\"path\":2}]");
1633 JSON::node z
= x
.patch(y
);
1635 }, JSON::ERR_PATCH_BAD
},{"simple add", []() {
1636 JSON::node
x("[1,2,3,4]");
1637 JSON::node
y("[{\"op\":\"add\",\"path\":\"-\",\"value\":5}]");
1638 JSON::node z
= x
.patch(y
);
1639 return z
.serialize() == "[1,2,3,4,5]";
1640 }},{"add dupe path", []() {
1641 JSON::node
x("[1,2,3,4]");
1642 JSON::node
y("[{\"op\":\"add\",\"path\":\"3\",\"path\":\"2\",\"value\":3}]");
1645 }, JSON::ERR_PATCH_BAD
},{"add number path", []() {
1646 JSON::node
x("[1,2,3,4]");
1647 JSON::node
y("[{\"op\":\"add\",\"path\":3,\"value\":4}]");
1650 }, JSON::ERR_PATCH_BAD
},{"add dupe value", []() {
1651 JSON::node
x("[1,2,3,4]");
1652 JSON::node
y("[{\"op\":\"add\",\"path\":\"3\",\"value\":\"2\",\"value\":3}]");
1655 }, JSON::ERR_PATCH_BAD
},{"simple replace", []() {
1656 JSON::node
x("[1,2,3,4]");
1657 JSON::node
y("[{\"op\":\"replace\",\"path\":\"3\",\"value\":5}]");
1658 JSON::node z
= x
.patch(y
);
1659 return z
.serialize() == "[1,2,3,5]";
1660 }},{"Replace nonexistent", []() {
1661 JSON::node
x("{\"foo\":5}");
1662 JSON::node
y("[{\"op\":\"replace\",\"path\":\"foz\",\"value\":5}]");
1663 JSON::node z
= x
.patch(y
);
1665 }, JSON::ERR_KEY_INVALID
},{"replace dupe path", []() {
1666 JSON::node
x("[1,2,3,4]");
1667 JSON::node
y("[{\"op\":\"replace\",\"path\":\"3\",\"path\":\"2\",\"value\":3}]");
1670 }, JSON::ERR_PATCH_BAD
},{"replace number path", []() {
1671 JSON::node
x("[1,2,3,4]");
1672 JSON::node
y("[{\"op\":\"replace\",\"path\":3,\"value\":4}]");
1675 }, JSON::ERR_PATCH_BAD
},{"replace dupe value", []() {
1676 JSON::node
x("[1,2,3,4]");
1677 JSON::node
y("[{\"op\":\"replace\",\"path\":\"3\",\"value\":\"2\",\"value\":3}]");
1680 }, JSON::ERR_PATCH_BAD
},{"simple move", []() {
1681 JSON::node
x("[[1,2,3,4],[]]");
1682 JSON::node
y("[{\"op\":\"move\",\"from\":\"0/1\",\"path\":\"1/-\"}]");
1683 JSON::node z
= x
.patch(y
);
1684 return z
.serialize() == "[[1,3,4],[2]]";
1685 }},{"move within array", []() {
1686 JSON::node
x("[1,2,3,4]");
1687 JSON::node
y("[{\"op\":\"move\",\"from\":\"1\",\"path\":\"3\"}]");
1688 JSON::node z
= x
.patch(y
);
1689 return z
.serialize() == "[1,3,4,2]";
1690 }},{"move nonexistent", []() {
1691 JSON::node
x("{\"foo\":5}");
1692 JSON::node
y("[{\"op\":\"move\",\"path\":\"for\",\"from\":\"foz\"}]");
1693 JSON::node z
= x
.patch(y
);
1695 }, JSON::ERR_KEY_INVALID
},{"move dupe path", []() {
1696 JSON::node
x("[1,2,3,4]");
1697 JSON::node
y("[{\"op\":\"move\",\"path\":\"3\",\"path\":\"2\",\"from\":\"3\"}]");
1700 }, JSON::ERR_PATCH_BAD
},{"move number path", []() {
1701 JSON::node
x("[1,2,3,4]");
1702 JSON::node
y("[{\"op\":\"move\",\"path\":3,\"from\":\"4\"}]");
1705 }, JSON::ERR_PATCH_BAD
},{"move dupe from", []() {
1706 JSON::node
x("[1,2,3,4]");
1707 JSON::node
y("[{\"op\":\"move\",\"path\":\"3\",\"from\":\"2\",\"from\":\"3\"}]");
1710 }, JSON::ERR_PATCH_BAD
},{"move number from", []() {
1711 JSON::node
x("[1,2,3,4]");
1712 JSON::node
y("[{\"op\":\"move\",\"path\":\"3\",\"from\":4}]");
1715 }, JSON::ERR_PATCH_BAD
},{"move illegal", []() {
1716 JSON::node
x("{\"foo\":{}}");
1717 JSON::node
y("[{\"op\":\"move\",\"path\":\"foo/bar\",\"from\":\"foo\"}]");
1718 JSON::node z
= x
.patch(y
);
1720 }, JSON::ERR_PATCH_ILLEGAL_MOVE
},{"move self", []() {
1721 JSON::node
x("{\"foo\":{}}");
1722 JSON::node
y("[{\"op\":\"move\",\"path\":\"foo\",\"from\":\"foo\"}]");
1723 JSON::node z
= x
.patch(y
);
1725 }},{"simple copy", []() {
1726 JSON::node
x("[[1,2,3,4],[]]");
1727 JSON::node
y("[{\"op\":\"copy\",\"from\":\"0/1\",\"path\":\"1/-\"}]");
1728 JSON::node z
= x
.patch(y
);
1729 return z
.serialize() == "[[1,2,3,4],[2]]";
1730 }},{"copy within array", []() {
1731 JSON::node
x("[1,2,3,4]");
1732 JSON::node
y("[{\"op\":\"copy\",\"from\":\"1\",\"path\":\"3\"}]");
1733 JSON::node z
= x
.patch(y
);
1734 return z
.serialize() == "[1,2,3,2,4]";
1735 }},{"copy nonexistent", []() {
1736 JSON::node
x("{\"foo\":5}");
1737 JSON::node
y("[{\"op\":\"copy\",\"path\":\"for\",\"from\":\"foz\"}]");
1738 JSON::node z
= x
.patch(y
);
1740 }, JSON::ERR_KEY_INVALID
},{"copy dupe path", []() {
1741 JSON::node
x("[1,2,3,4]");
1742 JSON::node
y("[{\"op\":\"copy\",\"path\":\"3\",\"path\":\"2\",\"from\":\"3\"}]");
1745 }, JSON::ERR_PATCH_BAD
},{"copy number path", []() {
1746 JSON::node
x("[1,2,3,4]");
1747 JSON::node
y("[{\"op\":\"copy\",\"path\":3,\"from\":\"4\"}]");
1750 }, JSON::ERR_PATCH_BAD
},{"copy dupe from", []() {
1751 JSON::node
x("[1,2,3,4]");
1752 JSON::node
y("[{\"op\":\"copy\",\"path\":\"3\",\"from\":\"2\",\"from\":\"3\"}]");
1755 }, JSON::ERR_PATCH_BAD
},{"copy number from", []() {
1756 JSON::node
x("[1,2,3,4]");
1757 JSON::node
y("[{\"op\":\"copy\",\"path\":\"3\",\"from\":4}]");
1760 }, JSON::ERR_PATCH_BAD
},{"copy self", []() {
1761 JSON::node
x("{\"foo\":{}}");
1762 JSON::node
y("[{\"op\":\"copy\",\"path\":\"foo\",\"from\":\"foo\"}]");
1763 JSON::node z
= x
.patch(y
);
1765 }},{"copy idential path", []() {
1766 JSON::node
x("[1]");
1767 JSON::node
y("[{\"op\":\"copy\",\"path\":\"0\",\"from\":\"0\"}]");
1768 JSON::node z
= x
.patch(y
);
1769 return z
.serialize() == "[1,1]";
1770 }},{"unknown patch op", []() {
1771 JSON::node
x("[1,2,3,4]");
1772 JSON::node
y("[{\"op\":\"foo\",\"path\":\"3\",\"from\":\"4\",\"value\":6}]");
1775 }, JSON::ERR_PATCH_BAD
},
1778 void run_test(unsigned i
, size_t& total
, size_t& pass
, size_t& fail
)
1781 std::cout
<< "#" << (i
+ 1) << ": " << tests
[i
].title
<< "..." << std::flush
;
1782 if(tests
[i
].dotest() && !tests
[i
].expect
) {
1783 std::cout
<< "\e[32mPASS\e[0m" << std::endl
;
1786 std::cout
<< "\e[31mFAIL\e[0m" << std::endl
;
1789 } catch(JSON::error
& e
) {
1790 if(e
.get_code() == tests
[i
].expect
) {
1791 std::cout
<< "\e[32mPASS\e[0m" << std::endl
;
1794 std::cout
<< "\e[31mERR: " << e
.what() << "\e[0m" << std::endl
;
1797 } catch(std::exception
& e
) {
1798 std::cout
<< "\e[31mERR: " << e
.what() << "\e[0m" << std::endl
;
1804 int main(int argc
, char** argv
)
1810 for(size_t i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
1811 run_test(i
, total
, pass
, fail
);
1813 for(int i
= 1; i
< argc
; i
++)
1814 run_test(parse_value
<unsigned>(argv
[i
]) - 1, total
, pass
, fail
);
1815 std::cout
<< "Total: " << total
<< " Pass: " << pass
<< " Fail: " << fail
<< std::endl
;