1 #include "simdjson.h"
2 #include "test_ondemand.h"
3
4 using namespace simdjson;
5
6 namespace array_tests {
7 using namespace std;
8 using simdjson::ondemand::json_type;
issue1588()9 bool issue1588() {
10 TEST_START();
11 const auto json = R"({
12 "nodes" : [
13 {
14 "rotation" : [
15 0.16907575726509094,
16 0.7558803558349609,
17 -0.27217137813568115,
18 0.570947527885437
19 ],
20 "translation" : [
21 4.076245307922363,
22 5.903861999511719,
23 -1.0054539442062378
24 ]
25 },
26 {
27 "camera" : 0,
28 "rotation" : [
29 -0.7071067690849304,
30 0,
31 0,
32 0.7071067690849304
33 ]
34 },
35 {
36 "children" : [
37 1
38 ],
39 "translation" : [
40 7.358891487121582,
41 4.958309173583984,
42 6.925790786743164
43 ]
44 },
45 {
46 "mesh" : 1,
47 "scale" : [
48 4.7498908042907715,
49 4.7498908042907715,
50 4.7498908042907715
51 ]
52 }
53 ]
54 })"_padded;
55 // we query 'rotation', 'scale', 'translation' in sequence
56 const bool expected_value[][3] = { {true, false, true},
57 {true, false, false}, {false, false, true}, {false, true, false} };
58
59 SUBTEST("ondemand::issue1588::sequence", test_ondemand_doc(json, [&](auto doc_result) {
60 ondemand::array array;
61 ASSERT_SUCCESS( doc_result["nodes"].get(array) );
62
63 size_t i=0;
64 for (auto value : array) {
65 ondemand::object current_object;
66 ASSERT_SUCCESS( value.get_object().get(current_object) );
67 simdjson::ondemand::array rotation;
68 if(expected_value[i][0]) {
69 ASSERT_SUCCESS( current_object["rotation"].get(rotation) );
70 } else {
71 ASSERT_ERROR( current_object["rotation"].get(rotation), NO_SUCH_FIELD );
72 }
73 simdjson::ondemand::array scale;
74 if(expected_value[i][1]) {
75 ASSERT_SUCCESS( current_object["scale"].get(scale) );
76 } else {
77 ASSERT_ERROR( current_object["scale"].get(scale), NO_SUCH_FIELD );
78 }
79 simdjson::ondemand::array translation;
80 if(expected_value[i][2]) {
81 ASSERT_SUCCESS( current_object["translation"].get(translation) );
82 } else {
83 ASSERT_ERROR( current_object["translation"].get(translation), NO_SUCH_FIELD );
84 }
85 i++;
86 }
87 ASSERT_EQUAL(i, 4);
88 return true;
89 }));
90 SUBTEST("ondemand::issue1588::originalcode", test_ondemand_doc(json, [&](auto doc_result) {
91 int count_nodes = 0;
92 simdjson::ondemand::array doc_nodes;
93 auto error = doc_result["nodes"].get(doc_nodes);
94 ASSERT_SUCCESS( error );
95 for (auto node_iterator : doc_nodes) {
96 ondemand::object node_obj;
97 ASSERT_SUCCESS( node_iterator.get_object().get(node_obj) );
98 simdjson::ondemand::array rotation;
99 std::cout << "checking rotation" << std::endl;
100 if(expected_value[count_nodes][0]) {
101 ASSERT_SUCCESS( node_obj["rotation"].get(rotation) );
102 } else {
103 ASSERT_ERROR( node_obj["rotation"].get(rotation), NO_SUCH_FIELD );
104 }
105
106 simdjson::ondemand::array scale;
107 std::cout << "checking scale" << std::endl;
108 if(expected_value[count_nodes][1]) {
109 ASSERT_SUCCESS( node_obj["scale"].get(scale) );
110 } else {
111 ASSERT_ERROR( node_obj["scale"].get(scale), NO_SUCH_FIELD );
112 }
113
114 simdjson::ondemand::array translation;
115 std::cout << "checking translation" << std::endl;
116 if (!error) { std::cout << "translation!\n"; }
117 if(expected_value[count_nodes][2]) {
118 ASSERT_SUCCESS( node_obj["translation"].get(translation) );
119 } else {
120 ASSERT_ERROR( node_obj["translation"].get(translation), NO_SUCH_FIELD );
121 }
122
123 ++count_nodes;
124 }
125 ASSERT_EQUAL(count_nodes, 4);
126 return true;
127 }));
128 TEST_SUCCEED();
129 }
130
iterate_complex_array_count()131 bool iterate_complex_array_count() {
132 TEST_START();
133 ondemand::parser parser;
134 auto cars_json = R"( { "zero":[], "test":[ { "val1":1, "val2":2 }, { "val1":1, "val2":2 } ] } )"_padded;
135 ondemand::document doc;
136 ASSERT_SUCCESS(parser.iterate(cars_json).get(doc));
137 ondemand::array firstmyarray;
138 ondemand::array secondmyarray;
139 ASSERT_SUCCESS(doc.find_field("zero").get_array().get(firstmyarray));
140 size_t count{0};
141 ASSERT_SUCCESS(firstmyarray.count_elements().get(count));
142 ASSERT_EQUAL(count, 0);
143 size_t new_count{0};
144 for(simdjson_unused auto elem: firstmyarray) { new_count++; }
145 ASSERT_EQUAL(new_count, 0);
146 ASSERT_SUCCESS(doc.find_field("test").get_array().get(secondmyarray));
147 ASSERT_SUCCESS(secondmyarray.count_elements().get(count));
148 ASSERT_EQUAL(count, 2);
149 new_count = 0;
150 for(simdjson_unused auto elem: secondmyarray) { new_count++; }
151 ASSERT_EQUAL(count, new_count);
152 TEST_SUCCEED();
153 }
154
iterate_sub_array_count()155 bool iterate_sub_array_count() {
156 TEST_START();
157 ondemand::parser parser;
158 auto key_value_json = R"( { "test":[ 1,2,3], "joe": [1,2] } )"_padded;
159 ondemand::document doc;
160 ASSERT_SUCCESS(parser.iterate(key_value_json).get(doc));
161 ondemand::object obj;
162 ASSERT_SUCCESS(doc.get_object().get(obj));
163 ondemand::value v;
164 ASSERT_SUCCESS(doc.find_field("test").get(v));
165 size_t count;
166 ASSERT_SUCCESS(v.count_elements().get(count));
167 ASSERT_EQUAL(count, 3);
168 ASSERT_SUCCESS(doc.find_field("joe").get(v));
169 ASSERT_SUCCESS(v.count_elements().get(count));
170 ASSERT_EQUAL(count, 2);
171 TEST_SUCCEED();
172 }
173
iterate_array_count()174 bool iterate_array_count() {
175 TEST_START();
176 const auto json = R"([ 1, 10, 100 ])"_padded;
177 const vector<uint64_t> expected_value = { 1, 10, 100 };
178
179 SUBTEST("ondemand::count_elements", test_ondemand_doc(json, [&](auto doc_result) {
180 ondemand::array array;
181 ASSERT_RESULT( doc_result.type(), json_type::array );
182 ASSERT_SUCCESS( doc_result.get_array().get(array) );
183 size_t count;
184 ASSERT_SUCCESS( array.count_elements().get(count) );
185 ASSERT_EQUAL(count, expected_value.size());
186 return true;
187 }));
188 SUBTEST("ondemand::count_elements_and_decode", test_ondemand_doc(json, [&](auto doc_result) {
189 ondemand::array array;
190 ASSERT_RESULT( doc_result.type(), json_type::array );
191 ASSERT_SUCCESS( doc_result.get(array) );
192 size_t count;
193 ASSERT_SUCCESS( array.count_elements().get(count) );
194 ASSERT_EQUAL(count, expected_value.size());
195 size_t i = 0;
196 std::vector<uint64_t> receiver(count);
197 for (auto value : array) {
198 uint64_t actual;
199 ASSERT_SUCCESS( value.get(actual) );
200 ASSERT_EQUAL(actual, expected_value[i]);
201 receiver[i] = actual;
202 i++;
203 }
204 return true;
205 }));
206 TEST_SUCCEED();
207 }
208
209
iterate_empty_array_count()210 bool iterate_empty_array_count() {
211 TEST_START();
212 const auto json = R"([])"_padded;
213
214 SUBTEST("ondemand::count_elements", test_ondemand_doc(json, [&](auto doc_result) {
215 ondemand::array array;
216 ASSERT_RESULT( doc_result.type(), json_type::array );
217 ASSERT_SUCCESS( doc_result.get_array().get(array) );
218 size_t count;
219 ASSERT_SUCCESS( array.count_elements().get(count) );
220 ASSERT_EQUAL(count, 0);
221 return true;
222 }));
223 SUBTEST("ondemand::count_elements_and_decode", test_ondemand_doc(json, [&](auto doc_result) {
224 ondemand::array array;
225 ASSERT_RESULT( doc_result.type(), json_type::array );
226 ASSERT_SUCCESS( doc_result.get(array) );
227 size_t count;
228 ASSERT_SUCCESS( array.count_elements().get(count) );
229 ASSERT_EQUAL(count, 0);
230 size_t i = 0;
231 std::vector<uint64_t> receiver(count);
232 for (auto value : array) {
233 uint64_t actual;
234 ASSERT_SUCCESS( value.get(actual) );
235 i++;
236 }
237 ASSERT_EQUAL(i, 0);
238 return true;
239 }));
240 TEST_SUCCEED();
241 }
242
iterate_bad_array_count()243 bool iterate_bad_array_count() {
244 TEST_START();
245 const auto badjson = R"([ 1, 10 100 ])"_padded;
246
247
248 SUBTEST("ondemand::count_elements", test_ondemand_doc(badjson, [&](auto doc_result) {
249 ondemand::array array;
250 ASSERT_RESULT( doc_result.type(), json_type::array );
251 ASSERT_SUCCESS( doc_result.get(array) );
252 size_t count;
253 auto e = array.count_elements().get(count);
254 if( e != TAPE_ERROR) {
255 std::cout << e << "\n";
256 std::cout << "expected: " << TAPE_ERROR << "\n";
257 std::cout << "count = " << count << "\n";
258 return false;
259 }
260 return true;
261 }));
262 TEST_SUCCEED();
263 }
iterate_document_array_count()264 bool iterate_document_array_count() {
265 TEST_START();
266 auto empty = R"( [] )"_padded;
267 SUBTEST("ondemand::empty_doc_array", test_ondemand_doc(empty, [&](auto doc_result) {
268 size_t count;
269 ASSERT_RESULT( doc_result.type(), json_type::array );
270 ASSERT_SUCCESS( doc_result.count_elements().get(count) );
271 ASSERT_EQUAL( count, 0 );
272 return true;
273 }));
274 auto basic = R"( [-1.234, 100000000000000, null, [1,2,3], {"t":true, "f":false}] )"_padded;
275 SUBTEST("ondemand::basic_doc_array", test_ondemand_doc(basic, [&](auto doc_result) {
276 size_t count;
277 ASSERT_RESULT( doc_result.type(), json_type::array );
278 ASSERT_SUCCESS( doc_result.count_elements().get(count) );
279 ASSERT_EQUAL( count, 5 );
280 return true;
281 }));
282 TEST_SUCCEED();
283 }
iterate_bad_document_array_count()284 bool iterate_bad_document_array_count() {
285 TEST_START();
286 padded_string bad_jsons[2] = {R"( [1, 10 1000] )"_padded, R"( [1.23, 2.34 )"_padded};
287 std::string names[2] = {"missing_comma", "missing_bracket"};
288 simdjson::error_code errors[2] = {TAPE_ERROR, INCOMPLETE_ARRAY_OR_OBJECT};
289 size_t count{0};
290
291 for (auto name : names) {
292 SUBTEST("ondemand::" + name, test_ondemand_doc(bad_jsons[count], [&](auto doc_result) {
293 ASSERT_RESULT( doc_result.type(), json_type::array );
294 ASSERT_ERROR(doc_result.count_elements(), errors[count]);
295 return true;
296 }));
297 count++;
298 }
299 ASSERT_EQUAL(count, 2);
300 TEST_SUCCEED();
301 }
iterate_document_array()302 bool iterate_document_array() {
303 TEST_START();
304 const auto json = R"([ 1, 10, 100 ])"_padded;
305 const uint64_t expected_value[] = { 1, 10, 100 };
306
307 SUBTEST("ondemand::array", test_ondemand_doc(json, [&](auto doc_result) {
308 ondemand::array array;
309 ASSERT_RESULT( doc_result.type(), json_type::array );
310 ASSERT_SUCCESS( doc_result.get(array) );
311
312 size_t i = 0;
313 for (auto value : array) {
314 int64_t actual;
315 ASSERT_SUCCESS( value.get(actual) );
316 ASSERT_EQUAL(actual, expected_value[i]);
317 i++;
318 }
319 ASSERT_EQUAL(i*sizeof(int64_t), sizeof(expected_value));
320 return true;
321 }));
322
323 SUBTEST("ondemand::array-document-rewind", test_ondemand_doc(json, [&](auto doc_result) {
324 ondemand::array array;
325 ASSERT_RESULT( doc_result.type(), json_type::array );
326 ASSERT_SUCCESS( doc_result.get(array) );
327
328 size_t i = 0;
329 for (auto value : array) { (void)value; i++; }
330 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
331 std::vector<int64_t> container(i); // container of size 'i'.
332
333 doc_result.rewind();
334 ASSERT_RESULT( doc_result.type(), json_type::array );
335 ASSERT_SUCCESS( doc_result.get(array) );
336 i = 0;
337 for (auto value : array) {
338 int64_t actual;
339 ASSERT_SUCCESS( value.get(actual) );
340 container[i] = actual;
341 i++;
342 }
343 ASSERT_EQUAL(i * sizeof(int64_t), sizeof(expected_value));
344 for(size_t j = 0; j < sizeof(expected_value)/sizeof(int64_t); j++) {
345 ASSERT_EQUAL(container[j], expected_value[j]);
346 }
347 return true;
348 }));
349 SUBTEST("ondemand::array-rewind", test_ondemand_doc(json, [&](auto doc_result) {
350 ondemand::array array;
351 ASSERT_RESULT( doc_result.type(), json_type::array );
352 ASSERT_SUCCESS( doc_result.get(array) );
353
354 size_t i = 0;
355 for (auto value : array) { (void)value; i++; }
356 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
357 std::vector<int64_t> container(i); // container of size 'i'.
358
359 array.reset();
360 i = 0;
361 for (auto value : array) {
362 int64_t actual;
363 ASSERT_SUCCESS( value.get(actual) );
364 container[i] = actual;
365 i++;
366 }
367 ASSERT_EQUAL(i * sizeof(int64_t), sizeof(expected_value));
368 for(size_t j = 0; j < sizeof(expected_value)/sizeof(int64_t); j++) {
369 ASSERT_EQUAL(container[j], expected_value[j]);
370 }
371 return true;
372 }));
373 SUBTEST("simdjson_result<ondemand::array>", test_ondemand_doc(json, [&](auto doc_result) {
374 simdjson_result<ondemand::array> array = doc_result.get_array();
375 ASSERT_RESULT( doc_result.type(), json_type::array );
376 size_t i=0;
377 for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
378 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
379 return true;
380 }));
381
382 SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
383 ondemand::document doc;
384 ASSERT_SUCCESS( std::move(doc_result).get(doc) );
385 ASSERT_RESULT( doc.type(), json_type::array );
386 size_t i=0;
387 for (simdjson_unused auto value : doc) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
388 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
389 return true;
390 }));
391 SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
392 size_t i=0;
393 ASSERT_RESULT( doc_result.type(), json_type::array );
394 for (simdjson_unused auto value : doc_result) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
395 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
396 return true;
397 }));
398 TEST_SUCCEED();
399 }
empty_rewind()400 bool empty_rewind() {
401 TEST_START();
402 const auto json = R"( [] )"_padded;
403 ondemand::parser parser;
404 ondemand::document doc;
405 ASSERT_SUCCESS(parser.iterate(json).get(doc));
406 ondemand::array arr;
407 ASSERT_SUCCESS(doc.get_array().get(arr));
408 for(simdjson_unused auto i : arr) {
409 TEST_FAIL("should be empty?");
410 }
411 arr.reset();
412 for(simdjson_unused auto i : arr) {
413 TEST_FAIL("should be empty?");
414 }
415 TEST_SUCCEED();
416 }
count_empty(simdjson::ondemand::array arr)417 bool count_empty(simdjson::ondemand::array arr) {
418 size_t count;
419 ASSERT_SUCCESS(arr.count_elements().get(count));
420 ASSERT_EQUAL(count, 0);
421 bool is_empty;
422 ASSERT_SUCCESS(arr.is_empty().get(is_empty));
423 ASSERT_TRUE(is_empty);
424 return true;
425 }
value_to_array(simdjson::ondemand::value val)426 bool value_to_array(simdjson::ondemand::value val) {
427 ondemand::json_type t;
428 ASSERT_SUCCESS(val.type().get(t));
429 ASSERT_EQUAL(t, ondemand::json_type::array);
430 simdjson::ondemand::array arr;
431 ASSERT_SUCCESS(val.get_array().get(arr));
432 if(count_empty(arr) != true) { return false; }
433 return true;
434 }
empty_rewind_convoluted()435 bool empty_rewind_convoluted() {
436 TEST_START();
437 const auto json = R"( [] )"_padded;
438 ondemand::parser parser;
439 ondemand::document doc;
440 ASSERT_SUCCESS(parser.iterate(json).get(doc));
441 ondemand::value val;
442 ASSERT_SUCCESS(doc.get_value().get(val));
443 if(!value_to_array(val)) { return false; }
444 TEST_SUCCEED();
445 }
446 #if SIMDJSON_EXCEPTIONS
value_to_array_except(simdjson::ondemand::value val)447 bool value_to_array_except(simdjson::ondemand::value val) {
448 ondemand::json_type t = val.type();
449 ASSERT_EQUAL(t, ondemand::json_type::array);
450 if(count_empty(simdjson::ondemand::array(val)) != true) { return false; }
451 return true;
452 }
empty_rewind_convoluted_with_exceptions()453 bool empty_rewind_convoluted_with_exceptions() {
454 TEST_START();
455 const auto json = R"( [] )"_padded;
456 ondemand::parser parser;
457 ondemand::document doc;
458 ASSERT_SUCCESS(parser.iterate(json).get(doc));
459 ondemand::value val;
460 ASSERT_SUCCESS(doc.get_value().get(val));
461 if(value_to_array_except(val) != true) { return false; }
462 TEST_SUCCEED();
463 }
464 #endif
iterate_array()465 bool iterate_array() {
466 TEST_START();
467 const auto json = R"( [ [ 1, 10, 100 ] ] )"_padded;
468 const uint64_t expected_value[] = { 1, 10, 100 };
469
470 SUBTEST("ondemand::array", test_ondemand_doc(json, [&](auto doc_result) {
471 bool found = false;
472 for (simdjson_result<ondemand::value> array_result : doc_result) {
473 ASSERT_TRUE(!found); found = true;
474
475 ondemand::array array;
476 ASSERT_RESULT( array_result.type(), json_type::array );
477 ASSERT_SUCCESS( array_result.get(array) );
478
479 size_t i=0;
480 for (auto value : array) {
481 int64_t actual;
482 ASSERT_SUCCESS( value.get(actual) );
483 ASSERT_EQUAL(actual, expected_value[i]);
484 i++;
485 }
486 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
487 }
488 ASSERT_TRUE(found);
489 return true;
490 }));
491
492 SUBTEST("simdjson_result<ondemand::array>", test_ondemand_doc(json, [&](auto doc_result) {
493 bool found = false;
494 for (simdjson_result<ondemand::value> array_result : doc_result) {
495 ASSERT_TRUE(!found); found = true;
496
497 ondemand::array array;
498 ASSERT_RESULT( array_result.type(), json_type::array );
499 ASSERT_SUCCESS( array_result.get(array) );
500
501 size_t i=0;
502 for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
503 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
504 }
505 ASSERT_TRUE(found);
506 return true;
507 }));
508
509 SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
510 bool found = false;
511 for (simdjson_result<ondemand::value> array_result : doc_result) {
512 ASSERT_TRUE(!found); found = true;
513
514 ondemand::value array;
515 ASSERT_SUCCESS( std::move(array_result).get(array) );
516 ASSERT_RESULT( array.type(), json_type::array );
517 size_t i=0;
518 for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
519 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
520 }
521 ASSERT_TRUE(found);
522 return true;
523 }));
524 SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) {
525 bool found = false;
526 for (simdjson_result<ondemand::value> array_result : doc_result) {
527 ASSERT_TRUE(!found); found = true;
528
529 size_t i=0;
530 ASSERT_RESULT( array_result.type(), json_type::array );
531 for (simdjson_unused auto value : array_result) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
532 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
533 }
534 ASSERT_TRUE(found);
535 return true;
536 }));
537 TEST_SUCCEED();
538 }
539
iterate_array_partial_children()540 bool iterate_array_partial_children() {
541 TEST_START();
542 auto json = R"(
543 [
544 0,
545 [],
546 {},
547 { "x": 3, "y": 33 },
548 { "x": 4, "y": 44 },
549 { "x": 5, "y": 55 },
550 { "x": 6, "y": 66 },
551 [ 7, 77, 777 ],
552 [ 8, 88, 888 ],
553 { "a": [ { "b": [ 9, 99 ], "c": 999 }, 9999 ], "d": 99999 },
554 10
555 ]
556 )"_padded;
557 SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
558 size_t i = 0;
559 for (auto value : doc_result) {
560 ASSERT_SUCCESS(value);
561
562 switch (i) {
563 case 0: {
564 std::cout << " - After ignoring empty scalar ..." << std::endl;
565 break;
566 }
567 case 1: {
568 std::cout << " - After ignoring empty array ..." << std::endl;
569 break;
570 }
571 case 2: {
572 std::cout << " - After ignoring empty object ..." << std::endl;
573 break;
574 }
575 // Break after using first value in child object
576 case 3: {
577 for (auto child_field : value.get_object()) {
578 ondemand::raw_json_string k;
579 ASSERT_SUCCESS( child_field.key().get(k) );
580 ASSERT_EQUAL(k, "x");
581 uint64_t x;
582 ASSERT_SUCCESS( child_field.value().get(x) );
583 ASSERT_EQUAL(x, 3);
584 break; // Break after the first value
585 }
586 std::cout << " - After using first value in child object ..." << std::endl;
587 break;
588 }
589
590 // Break without using first value in child object
591 case 4: {
592 for (auto child_field : value.get_object()) {
593 ondemand::raw_json_string k;
594 ASSERT_SUCCESS( child_field.key().get(k) );
595 ASSERT_EQUAL(k, "x");
596 break;
597 }
598 std::cout << " - After reaching (but not using) first value in child object ..." << std::endl;
599 break;
600 }
601
602 // Only look up one field in child object
603 case 5: {
604 uint64_t x;
605 ASSERT_SUCCESS( value["x"].get(x) );
606 ASSERT_EQUAL( x, 5 );
607 std::cout << " - After looking up one field in child object ..." << std::endl;
608 break;
609 }
610
611 // Only look up one field in child object, but don't use it
612 case 6: {
613 ASSERT_SUCCESS( value["x"] );
614 std::cout << " - After looking up (but not using) one field in child object ..." << std::endl;
615 break;
616 }
617
618 // Break after first value in child array
619 case 7: {
620 for (auto child_value : value) {
621 uint64_t x;
622 ASSERT_SUCCESS( child_value.get(x) );
623 ASSERT_EQUAL( x, 7 );
624 break;
625 }
626 std::cout << " - After using first value in child array ..." << std::endl;
627 break;
628 }
629
630 // Break without using first value in child array
631 case 8: {
632 for (auto child_value : value) {
633 ASSERT_SUCCESS(child_value);
634 break;
635 }
636 std::cout << " - After reaching (but not using) first value in child array ..." << std::endl;
637 break;
638 }
639
640 // Break out of multiple child loops
641 case 9: {
642 for (auto child1 : value.get_object()) {
643 for (auto child2 : child1.value().get_array()) {
644 for (auto child3 : child2.get_object()) {
645 for (auto child4 : child3.value().get_array()) {
646 uint64_t x;
647 ASSERT_SUCCESS( child4.get(x) );
648 ASSERT_EQUAL( x, 9 );
649 break;
650 }
651 break;
652 }
653 break;
654 }
655 break;
656 }
657 std::cout << " - After breaking out of quadruply-nested arrays and objects ..." << std::endl;
658 break;
659 }
660
661 // Test the actual value
662 case 10: {
663 uint64_t actual_value;
664 ASSERT_SUCCESS( value.get(actual_value) );
665 ASSERT_EQUAL( actual_value, 10 );
666 break;
667 }
668 }
669
670 i++;
671 }
672 ASSERT_EQUAL( i, 11 ); // Make sure we found all the keys we expected
673 return true;
674 }));
675 return true;
676 }
677
iterate_empty_array()678 bool iterate_empty_array() {
679 TEST_START();
680 auto json = "[]"_padded;
681 SUBTEST("ondemand::array", test_ondemand_doc(json, [&](auto doc_result) {
682 ondemand::array array;
683 ASSERT_SUCCESS( doc_result.get(array) );
684 for (simdjson_unused auto value : array) { TEST_FAIL("Unexpected value"); }
685 return true;
686 }));
687 SUBTEST("simdjson_result<ondemand::array>", test_ondemand_doc(json, [&](auto doc_result) {
688 simdjson_result<ondemand::array> array_result = doc_result.get_array();
689 for (simdjson_unused auto value : array_result) { TEST_FAIL("Unexpected value"); }
690 return true;
691 }));
692 SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
693 ondemand::document doc;
694 ASSERT_SUCCESS( std::move(doc_result).get(doc) );
695 for (simdjson_unused auto value : doc) { TEST_FAIL("Unexpected value"); }
696 return true;
697 }));
698 SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
699 for (simdjson_unused auto value : doc_result) { TEST_FAIL("Unexpected value"); }
700 return true;
701 }));
702 SUBTEST("ondemand::array-document-rewind", test_ondemand_doc(json, [&](auto doc_result) {
703 ondemand::array array;
704 ASSERT_RESULT( doc_result.type(), json_type::array );
705 ASSERT_SUCCESS( doc_result.get(array) );
706
707 size_t i = 0;
708 for (auto value : array) { (void) value; i++; }
709 ASSERT_EQUAL(i, 0);
710
711 doc_result.rewind();
712 ASSERT_RESULT( doc_result.type(), json_type::array );
713 ASSERT_SUCCESS( doc_result.get(array) );
714 i = 0;
715 for (auto value : array) { (void) value; i++; }
716 ASSERT_EQUAL(i, 0);
717 return true;
718 }));
719 SUBTEST("ondemand::array-rewind", test_ondemand_doc(json, [&](auto doc_result) {
720 ondemand::array array;
721 ASSERT_RESULT( doc_result.type(), json_type::array );
722 ASSERT_SUCCESS( doc_result.get(array) );
723
724 size_t i = 0;
725 for (auto value : array) { (void) value; i++; }
726 ASSERT_EQUAL(i, 0);
727
728 array.reset();
729 i = 0;
730 for (auto value : array) { (void) value; i++; }
731 ASSERT_EQUAL(i, 0);
732 return true;
733 }));
734 TEST_SUCCEED();
735 }
736
737 #if SIMDJSON_EXCEPTIONS
738
iterate_array_exception()739 bool iterate_array_exception() {
740 TEST_START();
741 auto json = R"([ 1, 10, 100 ])"_padded;
742 const uint64_t expected_value[] = { 1, 10, 100 };
743
744 ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
745 size_t i=0;
746 for (int64_t actual : doc_result) { ASSERT_EQUAL(actual, expected_value[i]); i++; }
747 ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
748 return true;
749 }));
750 TEST_SUCCEED();
751 }
752
iterate_empty_object_exception()753 bool iterate_empty_object_exception() {
754 TEST_START();
755 auto json = R"({})"_padded;
756
757 ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
758 for (simdjson_unused ondemand::field field : doc_result.get_object()) {
759 TEST_FAIL("Unexpected field");
760 }
761 return true;
762 }));
763
764 TEST_SUCCEED();
765 }
766
iterate_empty_array_exception()767 bool iterate_empty_array_exception() {
768 TEST_START();
769 auto json = "[]"_padded;
770
771 ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
772 for (simdjson_unused ondemand::value value : doc_result) { TEST_FAIL("Unexpected value"); }
773 return true;
774 }));
775
776 TEST_SUCCEED();
777 }
778
779 #endif // SIMDJSON_EXCEPTIONS
780
run()781 bool run() {
782 return
783 empty_rewind_convoluted() &&
784 empty_rewind() &&
785 iterate_empty_array_count() &&
786 iterate_sub_array_count() &&
787 iterate_complex_array_count() &&
788 iterate_bad_array_count() &&
789 iterate_array_count() &&
790 issue1588() &&
791 iterate_array() &&
792 iterate_document_array_count() &&
793 iterate_bad_document_array_count() &&
794 iterate_document_array() &&
795 iterate_empty_array() &&
796 iterate_array_partial_children() &&
797 #if SIMDJSON_EXCEPTIONS
798 empty_rewind_convoluted_with_exceptions() &&
799 iterate_array_exception() &&
800 #endif // SIMDJSON_EXCEPTIONS
801 true;
802 }
803
804 } // namespace dom_api_tests
805
main(int argc,char * argv[])806 int main(int argc, char *argv[]) {
807 return test_main(argc, argv, array_tests::run);
808 }
809