• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #include "doctest_compatibility.h"
31 
32 #include <nlohmann/json.hpp>
33 using nlohmann::json;
34 
35 TEST_CASE("modifiers")
36 {
37     SECTION("clear()")
38     {
39         SECTION("boolean")
40         {
41             json j = true;
42             json k = j;
43 
44             j.clear();
45             CHECK(j == json(json::value_t::boolean));
46             CHECK(j == json(k.type()));
47         }
48 
49         SECTION("string")
50         {
51             json j = "hello world";
52             json k = j;
53 
54             j.clear();
55             CHECK(j == json(json::value_t::string));
56             CHECK(j == json(k.type()));
57         }
58 
59         SECTION("array")
60         {
61             SECTION("empty array")
62             {
63                 json j = json::array();
64                 json k = j;
65 
66                 j.clear();
67                 CHECK(j.empty());
68                 CHECK(j == json(json::value_t::array));
69                 CHECK(j == json(k.type()));
70             }
71 
72             SECTION("filled array")
73             {
74                 json j = {1, 2, 3};
75                 json k = j;
76 
77                 j.clear();
78                 CHECK(j.empty());
79                 CHECK(j == json(json::value_t::array));
80                 CHECK(j == json(k.type()));
81             }
82         }
83 
84         SECTION("object")
85         {
86             SECTION("empty object")
87             {
88                 json j = json::object();
89                 json k = j;
90 
91                 j.clear();
92                 CHECK(j.empty());
93                 CHECK(j == json(json::value_t::object));
94                 CHECK(j == json(k.type()));
95             }
96 
97             SECTION("filled object")
98             {
99                 json j = {{"one", 1}, {"two", 2}, {"three", 3}};
100                 json k = j;
101 
102                 j.clear();
103                 CHECK(j.empty());
104                 CHECK(j == json(json::value_t::object));
105                 CHECK(j == json(k.type()));
106             }
107         }
108 
109         SECTION("binary")
110         {
111             SECTION("empty binary")
112             {
113                 json j = json::binary({});
114                 json k = j;
115 
116                 j.clear();
117                 CHECK(!j.empty());
118                 CHECK(j == json(json::value_t::binary));
119                 CHECK(j == json(k.type()));
120             }
121 
122             SECTION("filled binary")
123             {
124                 json j = json::binary({1, 2, 3, 4, 5});
125                 json k = j;
126 
127                 j.clear();
128                 CHECK(!j.empty());
129                 CHECK(j == json(json::value_t::binary));
130                 CHECK(j == json(k.type()));
131             }
132         }
133 
134         SECTION("number (integer)")
135         {
136             json j = 23;
137             json k = j;
138 
139             j.clear();
140             CHECK(j == json(json::value_t::number_integer));
141             CHECK(j == json(k.type()));
142         }
143 
144         SECTION("number (unsigned)")
145         {
146             json j = 23u;
147             json k = j;
148 
149             j.clear();
150             CHECK(j == json(json::value_t::number_integer));
151             CHECK(j == json(k.type()));
152         }
153 
154         SECTION("number (float)")
155         {
156             json j = 23.42;
157             json k = j;
158 
159             j.clear();
160             CHECK(j == json(json::value_t::number_float));
161             CHECK(j == json(k.type()));
162         }
163 
164         SECTION("null")
165         {
166             json j = nullptr;
167             json k = j;
168 
169             j.clear();
170             CHECK(j == json(json::value_t::null));
171             CHECK(j == json(k.type()));
172         }
173     }
174 
175     SECTION("push_back()")
176     {
177         SECTION("to array")
178         {
179             SECTION("json&&")
180             {
181                 SECTION("null")
182                 {
183                     json j;
184                     j.push_back(1);
185                     j.push_back(2);
186                     CHECK(j.type() == json::value_t::array);
187                     CHECK(j == json({1, 2}));
188                 }
189 
190                 SECTION("array")
191                 {
192                     json j = {1, 2, 3};
193                     j.push_back("Hello");
194                     CHECK(j.type() == json::value_t::array);
195                     CHECK(j == json({1, 2, 3, "Hello"}));
196                 }
197 
198                 SECTION("other type")
199                 {
200                     json j = 1;
201                     CHECK_THROWS_AS(j.push_back("Hello"), json::type_error&);
202                     CHECK_THROWS_WITH(j.push_back("Hello"), "[json.exception.type_error.308] cannot use push_back() with number");
203                 }
204             }
205 
206             SECTION("const json&")
207             {
208                 SECTION("null")
209                 {
210                     json j;
211                     json k(1);
212                     j.push_back(k);
213                     j.push_back(k);
214                     CHECK(j.type() == json::value_t::array);
215                     CHECK(j == json({1, 1}));
216                 }
217 
218                 SECTION("array")
219                 {
220                     json j = {1, 2, 3};
221                     json k("Hello");
222                     j.push_back(k);
223                     CHECK(j.type() == json::value_t::array);
224                     CHECK(j == json({1, 2, 3, "Hello"}));
225                 }
226 
227                 SECTION("other type")
228                 {
229                     json j = 1;
230                     json k("Hello");
231                     CHECK_THROWS_AS(j.push_back(k), json::type_error&);
232                     CHECK_THROWS_WITH(j.push_back(k), "[json.exception.type_error.308] cannot use push_back() with number");
233                 }
234             }
235         }
236 
237         SECTION("to object")
238         {
239             SECTION("null")
240             {
241                 json j;
242                 j.push_back(json::object_t::value_type({"one", 1}));
243                 j.push_back(json::object_t::value_type({"two", 2}));
244                 CHECK(j.type() == json::value_t::object);
245                 CHECK(j.size() == 2);
246                 CHECK(j["one"] == json(1));
247                 CHECK(j["two"] == json(2));
248             }
249 
250             SECTION("object")
251             {
252                 json j(json::value_t::object);
253                 j.push_back(json::object_t::value_type({"one", 1}));
254                 j.push_back(json::object_t::value_type({"two", 2}));
255                 CHECK(j.size() == 2);
256                 CHECK(j["one"] == json(1));
257                 CHECK(j["two"] == json(2));
258             }
259 
260             SECTION("other type")
261             {
262                 json j = 1;
263                 json k("Hello");
264                 CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), json::type_error&);
265                 CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({"one", 1})),
266                                   "[json.exception.type_error.308] cannot use push_back() with number");
267             }
268         }
269 
270         SECTION("with initializer_list")
271         {
272             SECTION("null")
273             {
274                 json j;
275                 j.push_back({"foo", "bar"});
276                 CHECK(j == json::array({{"foo", "bar"}}));
277 
278                 json k;
279                 k.push_back({1, 2, 3});
280                 CHECK(k == json::array({{1, 2, 3}}));
281             }
282 
283             SECTION("array")
284             {
285                 json j = {1, 2, 3};
286                 j.push_back({"foo", "bar"});
287                 CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
288 
289                 json k = {1, 2, 3};
290                 k.push_back({1, 2, 3});
291                 CHECK(k == json({1, 2, 3, {1, 2, 3}}));
292             }
293 
294             SECTION("object")
295             {
296                 json j = {{"key1", 1}};
297                 j.push_back({"key2", "bar"});
298                 CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
299 
300                 // invalid values (no string/val pair)
301                 CHECK_THROWS_AS(j.push_back({1}), json::type_error&);
302                 CHECK_THROWS_WITH(j.push_back({1}), "[json.exception.type_error.308] cannot use push_back() with object");
303                 CHECK_THROWS_AS(j.push_back({1, 2}), json::type_error&);
304                 CHECK_THROWS_WITH(j.push_back({1, 2}), "[json.exception.type_error.308] cannot use push_back() with object");
305                 CHECK_THROWS_AS(j.push_back({1, 2, 3, 4}), json::type_error&);
306                 CHECK_THROWS_WITH(j.push_back({1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object");
307             }
308         }
309     }
310 
311     SECTION("emplace_back()")
312     {
313         SECTION("to array")
314         {
315             SECTION("null")
316             {
317                 json j;
318                 auto& x1 = j.emplace_back(1);
319                 CHECK(x1 == 1);
320                 auto& x2 = j.emplace_back(2);
321                 CHECK(x2 == 2);
322                 CHECK(j.type() == json::value_t::array);
323                 CHECK(j == json({1, 2}));
324             }
325 
326             SECTION("array")
327             {
328                 json j = {1, 2, 3};
329                 auto& x = j.emplace_back("Hello");
330                 CHECK(x == "Hello");
331                 CHECK(j.type() == json::value_t::array);
332                 CHECK(j == json({1, 2, 3, "Hello"}));
333             }
334 
335             SECTION("multiple values")
336             {
337                 json j;
338                 auto& x = j.emplace_back(3, "foo");
339                 CHECK(x == json({"foo", "foo", "foo"}));
340                 CHECK(j.type() == json::value_t::array);
341                 CHECK(j == json({{"foo", "foo", "foo"}}));
342             }
343         }
344 
345         SECTION("other type")
346         {
347             json j = 1;
348             CHECK_THROWS_AS(j.emplace_back("Hello"), json::type_error&);
349             CHECK_THROWS_WITH(j.emplace_back("Hello"),
350                               "[json.exception.type_error.311] cannot use emplace_back() with number");
351         }
352     }
353 
354     SECTION("emplace()")
355     {
356         SECTION("to object")
357         {
358             SECTION("null")
359             {
360                 // start with a null value
361                 json j;
362 
363                 // add a new key
364                 auto res1 = j.emplace("foo", "bar");
365                 CHECK(res1.second == true);
366                 CHECK(*res1.first == "bar");
367 
368                 // the null value is changed to an object
369                 CHECK(j.type() == json::value_t::object);
370 
371                 // add a new key
372                 auto res2 = j.emplace("baz", "bam");
373                 CHECK(res2.second == true);
374                 CHECK(*res2.first == "bam");
375 
376                 // we try to insert at given key - no change
377                 auto res3 = j.emplace("baz", "bad");
378                 CHECK(res3.second == false);
379                 CHECK(*res3.first == "bam");
380 
381                 // the final object
382                 CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
383             }
384 
385             SECTION("object")
386             {
387                 // start with an object
388                 json j = {{"foo", "bar"}};
389 
390                 // add a new key
391                 auto res1 = j.emplace("baz", "bam");
392                 CHECK(res1.second == true);
393                 CHECK(*res1.first == "bam");
394 
395                 // add an existing key
396                 auto res2 = j.emplace("foo", "bad");
397                 CHECK(res2.second == false);
398                 CHECK(*res2.first == "bar");
399 
400                 // check final object
401                 CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
402             }
403         }
404 
405         SECTION("other type")
406         {
407             json j = 1;
408             CHECK_THROWS_AS(j.emplace("foo", "bar"), json::type_error&);
409             CHECK_THROWS_WITH(j.emplace("foo", "bar"),
410                               "[json.exception.type_error.311] cannot use emplace() with number");
411         }
412     }
413 
414     SECTION("operator+=")
415     {
416         SECTION("to array")
417         {
418             SECTION("json&&")
419             {
420                 SECTION("null")
421                 {
422                     json j;
423                     j += 1;
424                     j += 2;
425                     CHECK(j.type() == json::value_t::array);
426                     CHECK(j == json({1, 2}));
427                 }
428 
429                 SECTION("array")
430                 {
431                     json j = {1, 2, 3};
432                     j += "Hello";
433                     CHECK(j.type() == json::value_t::array);
434                     CHECK(j == json({1, 2, 3, "Hello"}));
435                 }
436 
437                 SECTION("other type")
438                 {
439                     json j = 1;
440                     CHECK_THROWS_AS(j += "Hello", json::type_error&);
441                     CHECK_THROWS_WITH(j += "Hello", "[json.exception.type_error.308] cannot use push_back() with number");
442                 }
443             }
444 
445             SECTION("const json&")
446             {
447                 SECTION("null")
448                 {
449                     json j;
450                     json k(1);
451                     j += k;
452                     j += k;
453                     CHECK(j.type() == json::value_t::array);
454                     CHECK(j == json({1, 1}));
455                 }
456 
457                 SECTION("array")
458                 {
459                     json j = {1, 2, 3};
460                     json k("Hello");
461                     j += k;
462                     CHECK(j.type() == json::value_t::array);
463                     CHECK(j == json({1, 2, 3, "Hello"}));
464                 }
465 
466                 SECTION("other type")
467                 {
468                     json j = 1;
469                     json k("Hello");
470                     CHECK_THROWS_AS(j += k, json::type_error&);
471                     CHECK_THROWS_WITH(j += k, "[json.exception.type_error.308] cannot use push_back() with number");
472                 }
473             }
474         }
475 
476         SECTION("to object")
477         {
478             SECTION("null")
479             {
480                 json j;
481                 j += json::object_t::value_type({"one", 1});
482                 j += json::object_t::value_type({"two", 2});
483                 CHECK(j.type() == json::value_t::object);
484                 CHECK(j.size() == 2);
485                 CHECK(j["one"] == json(1));
486                 CHECK(j["two"] == json(2));
487             }
488 
489             SECTION("object")
490             {
491                 json j(json::value_t::object);
492                 j += json::object_t::value_type({"one", 1});
493                 j += json::object_t::value_type({"two", 2});
494                 CHECK(j.size() == 2);
495                 CHECK(j["one"] == json(1));
496                 CHECK(j["two"] == json(2));
497             }
498 
499             SECTION("other type")
500             {
501                 json j = 1;
502                 json k("Hello");
503                 CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), json::type_error&);
504                 CHECK_THROWS_WITH(j += json::object_t::value_type({"one", 1}),
505                                   "[json.exception.type_error.308] cannot use push_back() with number");
506             }
507         }
508 
509         SECTION("with initializer_list")
510         {
511             SECTION("null")
512             {
513                 json j;
514                 j += {"foo", "bar"};
515                 CHECK(j == json::array({{"foo", "bar"}}));
516 
517                 json k;
518                 k += {1, 2, 3};
519                 CHECK(k == json::array({{1, 2, 3}}));
520             }
521 
522             SECTION("array")
523             {
524                 json j = {1, 2, 3};
525                 j += {"foo", "bar"};
526                 CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
527 
528                 json k = {1, 2, 3};
529                 k += {1, 2, 3};
530                 CHECK(k == json({1, 2, 3, {1, 2, 3}}));
531             }
532 
533             SECTION("object")
534             {
535                 json j = {{"key1", 1}};
536                 j += {"key2", "bar"};
537                 CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
538 
539                 json k = {{"key1", 1}};
540                 CHECK_THROWS_AS((k += {1, 2, 3, 4}), json::type_error&);
541                 CHECK_THROWS_WITH((k += {1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object");
542             }
543         }
544     }
545 
546     SECTION("insert()")
547     {
548         json j_array = {1, 2, 3, 4};
549         json j_value = 5;
550 
551         SECTION("value at position")
552         {
553             SECTION("insert before begin()")
554             {
555                 auto it = j_array.insert(j_array.begin(), j_value);
556                 CHECK(j_array.size() == 5);
557                 CHECK(*it == j_value);
558                 CHECK(j_array.begin() == it);
559                 CHECK(j_array == json({5, 1, 2, 3, 4}));
560             }
561 
562             SECTION("insert in the middle")
563             {
564                 auto it = j_array.insert(j_array.begin() + 2, j_value);
565                 CHECK(j_array.size() == 5);
566                 CHECK(*it == j_value);
567                 CHECK((it - j_array.begin()) == 2);
568                 CHECK(j_array == json({1, 2, 5, 3, 4}));
569             }
570 
571             SECTION("insert before end()")
572             {
573                 auto it = j_array.insert(j_array.end(), j_value);
574                 CHECK(j_array.size() == 5);
575                 CHECK(*it == j_value);
576                 CHECK((j_array.end() - it) == 1);
577                 CHECK(j_array == json({1, 2, 3, 4, 5}));
578             }
579         }
580 
581         SECTION("rvalue at position")
582         {
583             SECTION("insert before begin()")
584             {
585                 auto it = j_array.insert(j_array.begin(), 5);
586                 CHECK(j_array.size() == 5);
587                 CHECK(*it == j_value);
588                 CHECK(j_array.begin() == it);
589                 CHECK(j_array == json({5, 1, 2, 3, 4}));
590             }
591 
592             SECTION("insert in the middle")
593             {
594                 auto it = j_array.insert(j_array.begin() + 2, 5);
595                 CHECK(j_array.size() == 5);
596                 CHECK(*it == j_value);
597                 CHECK((it - j_array.begin()) == 2);
598                 CHECK(j_array == json({1, 2, 5, 3, 4}));
599             }
600 
601             SECTION("insert before end()")
602             {
603                 auto it = j_array.insert(j_array.end(), 5);
604                 CHECK(j_array.size() == 5);
605                 CHECK(*it == j_value);
606                 CHECK((j_array.end() - it) == 1);
607                 CHECK(j_array == json({1, 2, 3, 4, 5}));
608             }
609         }
610 
611         SECTION("copies at position")
612         {
613             SECTION("insert before begin()")
614             {
615                 auto it = j_array.insert(j_array.begin(), 3, 5);
616                 CHECK(j_array.size() == 7);
617                 CHECK(*it == j_value);
618                 CHECK(j_array.begin() == it);
619                 CHECK(j_array == json({5, 5, 5, 1, 2, 3, 4}));
620             }
621 
622             SECTION("insert in the middle")
623             {
624                 auto it = j_array.insert(j_array.begin() + 2, 3, 5);
625                 CHECK(j_array.size() == 7);
626                 CHECK(*it == j_value);
627                 CHECK((it - j_array.begin()) == 2);
628                 CHECK(j_array == json({1, 2, 5, 5, 5, 3, 4}));
629             }
630 
631             SECTION("insert before end()")
632             {
633                 auto it = j_array.insert(j_array.end(), 3, 5);
634                 CHECK(j_array.size() == 7);
635                 CHECK(*it == j_value);
636                 CHECK((j_array.end() - it) == 3);
637                 CHECK(j_array == json({1, 2, 3, 4, 5, 5, 5}));
638             }
639 
640             SECTION("insert nothing (count = 0)")
641             {
642                 auto it = j_array.insert(j_array.end(), 0, 5);
643                 CHECK(j_array.size() == 4);
644                 // the returned iterator points to the first inserted element;
645                 // there were 4 elements, so it should point to the 5th
646                 CHECK(it == j_array.begin() + 4);
647                 CHECK(j_array == json({1, 2, 3, 4}));
648             }
649         }
650 
651         SECTION("range for array")
652         {
653             json j_other_array = {"first", "second"};
654 
655             SECTION("proper usage")
656             {
657                 auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());
658                 CHECK(j_array.size() == 6);
659                 CHECK(*it == *j_other_array.begin());
660                 CHECK((j_array.end() - it) == 2);
661                 CHECK(j_array == json({1, 2, 3, 4, "first", "second"}));
662             }
663 
664             SECTION("empty range")
665             {
666                 auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());
667                 CHECK(j_array.size() == 4);
668                 CHECK(it == j_array.end());
669                 CHECK(j_array == json({1, 2, 3, 4}));
670             }
671 
672             SECTION("invalid iterators")
673             {
674                 json j_other_array2 = {"first", "second"};
675 
676                 CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
677                                 json::invalid_iterator&);
678                 CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
679                                 json::invalid_iterator&);
680 
681                 CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
682                                   "[json.exception.invalid_iterator.211] passed iterators may not belong to container");
683                 CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
684                                   "[json.exception.invalid_iterator.210] iterators do not fit");
685             }
686         }
687 
688         SECTION("range for object")
689         {
690             json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
691             json j_object2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};
692 
693             SECTION("proper usage")
694             {
695                 j_object1.insert(j_object2.begin(), j_object2.end());
696                 CHECK(j_object1.size() == 4);
697             }
698 
699             SECTION("empty range")
700             {
701                 j_object1.insert(j_object2.begin(), j_object2.begin());
702                 CHECK(j_object1.size() == 2);
703             }
704 
705             SECTION("invalid iterators")
706             {
707                 json j_other_array2 = {"first", "second"};
708 
709                 CHECK_THROWS_AS(j_array.insert(j_object2.begin(), j_object2.end()), json::type_error&);
710                 CHECK_THROWS_AS(j_object1.insert(j_object1.begin(), j_object2.end()), json::invalid_iterator&);
711                 CHECK_THROWS_AS(j_object1.insert(j_array.begin(), j_array.end()), json::invalid_iterator&);
712 
713                 CHECK_THROWS_WITH(j_array.insert(j_object2.begin(), j_object2.end()),
714                                   "[json.exception.type_error.309] cannot use insert() with array");
715                 CHECK_THROWS_WITH(j_object1.insert(j_object1.begin(), j_object2.end()),
716                                   "[json.exception.invalid_iterator.210] iterators do not fit");
717                 CHECK_THROWS_WITH(j_object1.insert(j_array.begin(), j_array.end()),
718                                   "[json.exception.invalid_iterator.202] iterators first and last must point to objects");
719             }
720         }
721 
722         SECTION("initializer list at position")
723         {
724             SECTION("insert before begin()")
725             {
726                 auto it = j_array.insert(j_array.begin(), {7, 8, 9});
727                 CHECK(j_array.size() == 7);
728                 CHECK(*it == json(7));
729                 CHECK(j_array.begin() == it);
730                 CHECK(j_array == json({7, 8, 9, 1, 2, 3, 4}));
731             }
732 
733             SECTION("insert in the middle")
734             {
735                 auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9});
736                 CHECK(j_array.size() == 7);
737                 CHECK(*it == json(7));
738                 CHECK((it - j_array.begin()) == 2);
739                 CHECK(j_array == json({1, 2, 7, 8, 9, 3, 4}));
740             }
741 
742             SECTION("insert before end()")
743             {
744                 auto it = j_array.insert(j_array.end(), {7, 8, 9});
745                 CHECK(j_array.size() == 7);
746                 CHECK(*it == json(7));
747                 CHECK((j_array.end() - it) == 3);
748                 CHECK(j_array == json({1, 2, 3, 4, 7, 8, 9}));
749             }
750         }
751 
752         SECTION("invalid iterator")
753         {
754             // pass iterator to a different array
755             json j_another_array = {1, 2};
756             json j_yet_another_array = {"first", "second"};
757             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), json::invalid_iterator&);
758             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), json::invalid_iterator&);
759             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), json::invalid_iterator&);
760             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), json::invalid_iterator&);
761             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), json::invalid_iterator&);
762 
763             CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10),
764                               "[json.exception.invalid_iterator.202] iterator does not fit current value");
765             CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value),
766                               "[json.exception.invalid_iterator.202] iterator does not fit current value");
767             CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11),
768                               "[json.exception.invalid_iterator.202] iterator does not fit current value");
769             CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()),
770                               "[json.exception.invalid_iterator.202] iterator does not fit current value");
771             CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}),
772                               "[json.exception.invalid_iterator.202] iterator does not fit current value");
773         }
774 
775         SECTION("non-array type")
776         {
777             // call insert on a non-array type
778             json j_nonarray = 3;
779             json j_yet_another_array = {"first", "second"};
780             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), json::type_error&);
781             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), json::type_error&);
782             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), json::type_error&);
783             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
784                                               j_yet_another_array.end()), json::type_error&);
785             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), json::type_error&);
786 
787             CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), "[json.exception.type_error.309] cannot use insert() with number");
788             CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), "[json.exception.type_error.309] cannot use insert() with number");
789             CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), "[json.exception.type_error.309] cannot use insert() with number");
790             CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
791                                                 j_yet_another_array.end()), "[json.exception.type_error.309] cannot use insert() with number");
792             CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}),
793                               "[json.exception.type_error.309] cannot use insert() with number");
794         }
795     }
796 
797     SECTION("update()")
798     {
799         json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
800         json j_object2 = {{"three", "drei"}, {"two", "zwo"}};
801         json j_array = {1, 2, 3, 4};
802 
803         SECTION("const reference")
804         {
805             SECTION("proper usage")
806             {
807                 j_object1.update(j_object2);
808                 CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
809 
810                 json j_null;
811                 j_null.update(j_object2);
812                 CHECK(j_null == j_object2);
813             }
814 
815             SECTION("wrong types")
816             {
817                 CHECK_THROWS_AS(j_array.update(j_object1), json::type_error&);
818                 CHECK_THROWS_WITH(j_array.update(j_object1), "[json.exception.type_error.312] cannot use update() with array");
819 
820                 CHECK_THROWS_AS(j_object1.update(j_array), json::type_error&);
821                 CHECK_THROWS_WITH(j_object1.update(j_array), "[json.exception.type_error.312] cannot use update() with array");
822             }
823         }
824 
825         SECTION("iterator range")
826         {
827             SECTION("proper usage")
828             {
829                 j_object1.update(j_object2.begin(), j_object2.end());
830                 CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
831 
832                 json j_null;
833                 j_null.update(j_object2.begin(), j_object2.end());
834                 CHECK(j_null == j_object2);
835             }
836 
837             SECTION("empty range")
838             {
839                 j_object1.update(j_object2.begin(), j_object2.begin());
840                 CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwei"}}));
841             }
842 
843             SECTION("invalid iterators")
844             {
845                 json j_other_array2 = {"first", "second"};
846 
847                 CHECK_THROWS_AS(j_array.update(j_object2.begin(), j_object2.end()), json::type_error&);
848                 CHECK_THROWS_AS(j_object1.update(j_object1.begin(), j_object2.end()), json::invalid_iterator&);
849                 CHECK_THROWS_AS(j_object1.update(j_array.begin(), j_array.end()), json::invalid_iterator&);
850 
851                 CHECK_THROWS_WITH(j_array.update(j_object2.begin(), j_object2.end()),
852                                   "[json.exception.type_error.312] cannot use update() with array");
853                 CHECK_THROWS_WITH(j_object1.update(j_object1.begin(), j_object2.end()),
854                                   "[json.exception.invalid_iterator.210] iterators do not fit");
855                 CHECK_THROWS_WITH(j_object1.update(j_array.begin(), j_array.end()),
856                                   "[json.exception.invalid_iterator.202] iterators first and last must point to objects");
857             }
858         }
859     }
860 
861     SECTION("swap()")
862     {
863         SECTION("json")
864         {
865             SECTION("member swap")
866             {
867                 json j("hello world");
868                 json k(42.23);
869 
870                 j.swap(k);
871 
872                 CHECK(j == json(42.23));
873                 CHECK(k == json("hello world"));
874             }
875 
876             SECTION("nonmember swap")
877             {
878                 json j("hello world");
879                 json k(42.23);
880 
881                 using std::swap;
882                 swap(j, k);
883 
884                 CHECK(j == json(42.23));
885                 CHECK(k == json("hello world"));
886             }
887         }
888 
889         SECTION("array_t")
890         {
891             SECTION("array_t type")
892             {
893                 json j = {1, 2, 3, 4};
894                 json::array_t a = {"foo", "bar", "baz"};
895 
896                 j.swap(a);
897 
898                 CHECK(j == json({"foo", "bar", "baz"}));
899 
900                 j.swap(a);
901 
902                 CHECK(j == json({1, 2, 3, 4}));
903             }
904 
905             SECTION("non-array_t type")
906             {
907                 json j = 17;
908                 json::array_t a = {"foo", "bar", "baz"};
909 
910                 CHECK_THROWS_AS(j.swap(a), json::type_error&);
911                 CHECK_THROWS_WITH(j.swap(a), "[json.exception.type_error.310] cannot use swap() with number");
912             }
913         }
914 
915         SECTION("object_t")
916         {
917             SECTION("object_t type")
918             {
919                 json j = {{"one", 1}, {"two", 2}};
920                 json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
921 
922                 j.swap(o);
923 
924                 CHECK(j == json({{"cow", "Kuh"}, {"chicken", "Huhn"}}));
925 
926                 j.swap(o);
927 
928                 CHECK(j == json({{"one", 1}, {"two", 2}}));
929             }
930 
931             SECTION("non-object_t type")
932             {
933                 json j = 17;
934                 json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
935 
936                 CHECK_THROWS_AS(j.swap(o), json::type_error&);
937                 CHECK_THROWS_WITH(j.swap(o), "[json.exception.type_error.310] cannot use swap() with number");
938             }
939         }
940 
941         SECTION("string_t")
942         {
943             SECTION("string_t type")
944             {
945                 json j = "Hello world";
946                 json::string_t s = "Hallo Welt";
947 
948                 j.swap(s);
949 
950                 CHECK(j == json("Hallo Welt"));
951 
952                 j.swap(s);
953 
954                 CHECK(j == json("Hello world"));
955             }
956 
957             SECTION("non-string_t type")
958             {
959                 json j = 17;
960                 json::string_t s = "Hallo Welt";
961 
962                 CHECK_THROWS_AS(j.swap(s), json::type_error&);
963                 CHECK_THROWS_WITH(j.swap(s), "[json.exception.type_error.310] cannot use swap() with number");
964             }
965         }
966 
967         SECTION("binary_t")
968         {
969             SECTION("binary_t type")
970             {
971                 json j = json::binary({1, 2, 3, 4});
972                 json::binary_t s = {{5, 6, 7, 8}};
973 
974                 j.swap(s);
975 
976                 CHECK(j == json::binary({5, 6, 7, 8}));
977 
978                 j.swap(s);
979 
980                 CHECK(j == json::binary({1, 2, 3, 4}));
981             }
982 
983             SECTION("binary_t::container_type type")
984             {
985                 json j = json::binary({1, 2, 3, 4});
986                 std::vector<std::uint8_t> s = {{5, 6, 7, 8}};
987 
988                 j.swap(s);
989 
990                 CHECK(j == json::binary({5, 6, 7, 8}));
991 
992                 j.swap(s);
993 
994                 CHECK(j == json::binary({1, 2, 3, 4}));
995             }
996 
997             SECTION("non-binary_t type")
998             {
999                 json j = 17;
1000                 json::binary_t s1 = {{1, 2, 3, 4}};
1001                 std::vector<std::uint8_t> s2 = {{5, 6, 7, 8}};
1002 
1003                 CHECK_THROWS_WITH_AS(j.swap(s1), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
1004                 CHECK_THROWS_WITH_AS(j.swap(s2), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
1005             }
1006         }
1007     }
1008 }
1009