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