unit-modifiers.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++ (supporting code)
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
  7. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  8. // SPDX-License-Identifier: MIT
  9. #include "doctest_compatibility.h"
  10. #include <nlohmann/json.hpp>
  11. using nlohmann::json;
  12. TEST_CASE("modifiers")
  13. {
  14. SECTION("clear()")
  15. {
  16. SECTION("boolean")
  17. {
  18. json j = true;
  19. json const k = j;
  20. j.clear();
  21. CHECK(j == json(json::value_t::boolean));
  22. CHECK(j == json(k.type()));
  23. }
  24. SECTION("string")
  25. {
  26. json j = "hello world";
  27. json const k = j;
  28. j.clear();
  29. CHECK(j == json(json::value_t::string));
  30. CHECK(j == json(k.type()));
  31. }
  32. SECTION("array")
  33. {
  34. SECTION("empty array")
  35. {
  36. json j = json::array();
  37. json const k = j;
  38. j.clear();
  39. CHECK(j.empty());
  40. CHECK(j == json(json::value_t::array));
  41. CHECK(j == json(k.type()));
  42. }
  43. SECTION("filled array")
  44. {
  45. json j = {1, 2, 3};
  46. json const k = j;
  47. j.clear();
  48. CHECK(j.empty());
  49. CHECK(j == json(json::value_t::array));
  50. CHECK(j == json(k.type()));
  51. }
  52. }
  53. SECTION("object")
  54. {
  55. SECTION("empty object")
  56. {
  57. json j = json::object();
  58. json const k = j;
  59. j.clear();
  60. CHECK(j.empty());
  61. CHECK(j == json(json::value_t::object));
  62. CHECK(j == json(k.type()));
  63. }
  64. SECTION("filled object")
  65. {
  66. json j = {{"one", 1}, {"two", 2}, {"three", 3}};
  67. json const k = j;
  68. j.clear();
  69. CHECK(j.empty());
  70. CHECK(j == json(json::value_t::object));
  71. CHECK(j == json(k.type()));
  72. }
  73. }
  74. SECTION("binary")
  75. {
  76. SECTION("empty binary")
  77. {
  78. json j = json::binary({});
  79. json const k = j;
  80. j.clear();
  81. CHECK(!j.empty());
  82. CHECK(j == json(json::value_t::binary));
  83. CHECK(j == json(k.type()));
  84. }
  85. SECTION("filled binary")
  86. {
  87. json j = json::binary({1, 2, 3, 4, 5});
  88. json const k = j;
  89. j.clear();
  90. CHECK(!j.empty());
  91. CHECK(j == json(json::value_t::binary));
  92. CHECK(j == json(k.type()));
  93. }
  94. }
  95. SECTION("number (integer)")
  96. {
  97. json j = 23;
  98. json const k = j;
  99. j.clear();
  100. CHECK(j == json(json::value_t::number_integer));
  101. CHECK(j == json(k.type()));
  102. }
  103. SECTION("number (unsigned)")
  104. {
  105. json j = 23u;
  106. json const k = j;
  107. j.clear();
  108. CHECK(j == json(json::value_t::number_integer));
  109. CHECK(j == json(k.type()));
  110. }
  111. SECTION("number (float)")
  112. {
  113. json j = 23.42;
  114. json const k = j;
  115. j.clear();
  116. CHECK(j == json(json::value_t::number_float));
  117. CHECK(j == json(k.type()));
  118. }
  119. SECTION("null")
  120. {
  121. json j = nullptr;
  122. json const k = j;
  123. j.clear();
  124. CHECK(j == json(json::value_t::null));
  125. CHECK(j == json(k.type()));
  126. }
  127. }
  128. SECTION("push_back()")
  129. {
  130. SECTION("to array")
  131. {
  132. SECTION("json&&")
  133. {
  134. SECTION("null")
  135. {
  136. json j;
  137. j.push_back(1);
  138. j.push_back(2);
  139. CHECK(j.type() == json::value_t::array);
  140. CHECK(j == json({1, 2}));
  141. }
  142. SECTION("array")
  143. {
  144. json j = {1, 2, 3};
  145. j.push_back("Hello");
  146. CHECK(j.type() == json::value_t::array);
  147. CHECK(j == json({1, 2, 3, "Hello"}));
  148. }
  149. SECTION("other type")
  150. {
  151. json j = 1;
  152. CHECK_THROWS_WITH_AS(j.push_back("Hello"), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  153. }
  154. }
  155. SECTION("const json&")
  156. {
  157. SECTION("null")
  158. {
  159. json j;
  160. json const k(1);
  161. j.push_back(k);
  162. j.push_back(k);
  163. CHECK(j.type() == json::value_t::array);
  164. CHECK(j == json({1, 1}));
  165. }
  166. SECTION("array")
  167. {
  168. json j = {1, 2, 3};
  169. json const k("Hello");
  170. j.push_back(k);
  171. CHECK(j.type() == json::value_t::array);
  172. CHECK(j == json({1, 2, 3, "Hello"}));
  173. }
  174. SECTION("other type")
  175. {
  176. json j = 1;
  177. json const k("Hello");
  178. CHECK_THROWS_WITH_AS(j.push_back(k), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  179. }
  180. }
  181. }
  182. SECTION("to object")
  183. {
  184. SECTION("null")
  185. {
  186. json j;
  187. j.push_back(json::object_t::value_type({"one", 1}));
  188. j.push_back(json::object_t::value_type({"two", 2}));
  189. CHECK(j.type() == json::value_t::object);
  190. CHECK(j.size() == 2);
  191. CHECK(j["one"] == json(1));
  192. CHECK(j["two"] == json(2));
  193. }
  194. SECTION("object")
  195. {
  196. json j(json::value_t::object);
  197. j.push_back(json::object_t::value_type({"one", 1}));
  198. j.push_back(json::object_t::value_type({"two", 2}));
  199. CHECK(j.size() == 2);
  200. CHECK(j["one"] == json(1));
  201. CHECK(j["two"] == json(2));
  202. }
  203. SECTION("other type")
  204. {
  205. json j = 1;
  206. json const k("Hello");
  207. CHECK_THROWS_WITH_AS(j.push_back(json::object_t::value_type({"one", 1})), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  208. }
  209. }
  210. SECTION("with initializer_list")
  211. {
  212. SECTION("null")
  213. {
  214. json j;
  215. j.push_back({"foo", "bar"});
  216. CHECK(j == json::array({{"foo", "bar"}}));
  217. json k;
  218. k.push_back({1, 2, 3});
  219. CHECK(k == json::array({{1, 2, 3}}));
  220. }
  221. SECTION("array")
  222. {
  223. json j = {1, 2, 3};
  224. j.push_back({"foo", "bar"});
  225. CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
  226. json k = {1, 2, 3};
  227. k.push_back({1, 2, 3});
  228. CHECK(k == json({1, 2, 3, {1, 2, 3}}));
  229. }
  230. SECTION("object")
  231. {
  232. json j = {{"key1", 1}};
  233. j.push_back({"key2", "bar"});
  234. CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
  235. // invalid values (no string/val pair)
  236. CHECK_THROWS_WITH_AS(j.push_back({1}), "[json.exception.type_error.308] cannot use push_back() with object", json::type_error&);
  237. CHECK_THROWS_WITH_AS(j.push_back({1, 2}), "[json.exception.type_error.308] cannot use push_back() with object", json::type_error&);
  238. CHECK_THROWS_WITH_AS(j.push_back({1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object", json::type_error&);
  239. }
  240. }
  241. }
  242. SECTION("emplace_back()")
  243. {
  244. SECTION("to array")
  245. {
  246. SECTION("null")
  247. {
  248. json j;
  249. auto& x1 = j.emplace_back(1);
  250. CHECK(x1 == 1);
  251. auto& x2 = j.emplace_back(2);
  252. CHECK(x2 == 2);
  253. CHECK(j.type() == json::value_t::array);
  254. CHECK(j == json({1, 2}));
  255. }
  256. SECTION("array")
  257. {
  258. json j = {1, 2, 3};
  259. auto& x = j.emplace_back("Hello");
  260. CHECK(x == "Hello");
  261. CHECK(j.type() == json::value_t::array);
  262. CHECK(j == json({1, 2, 3, "Hello"}));
  263. }
  264. SECTION("multiple values")
  265. {
  266. json j;
  267. auto& x = j.emplace_back(3, "foo");
  268. CHECK(x == json({"foo", "foo", "foo"}));
  269. CHECK(j.type() == json::value_t::array);
  270. CHECK(j == json({{"foo", "foo", "foo"}}));
  271. }
  272. }
  273. SECTION("other type")
  274. {
  275. json j = 1;
  276. CHECK_THROWS_WITH_AS(j.emplace_back("Hello"), "[json.exception.type_error.311] cannot use emplace_back() with number", json::type_error&);
  277. }
  278. }
  279. SECTION("emplace()")
  280. {
  281. SECTION("to object")
  282. {
  283. SECTION("null")
  284. {
  285. // start with a null value
  286. json j;
  287. // add a new key
  288. auto res1 = j.emplace("foo", "bar");
  289. CHECK(res1.second == true);
  290. CHECK(*res1.first == "bar");
  291. // the null value is changed to an object
  292. CHECK(j.type() == json::value_t::object);
  293. // add a new key
  294. auto res2 = j.emplace("baz", "bam");
  295. CHECK(res2.second == true);
  296. CHECK(*res2.first == "bam");
  297. // we try to insert at given key - no change
  298. auto res3 = j.emplace("baz", "bad");
  299. CHECK(res3.second == false);
  300. CHECK(*res3.first == "bam");
  301. // the final object
  302. CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
  303. }
  304. SECTION("object")
  305. {
  306. // start with an object
  307. json j = {{"foo", "bar"}};
  308. // add a new key
  309. auto res1 = j.emplace("baz", "bam");
  310. CHECK(res1.second == true);
  311. CHECK(*res1.first == "bam");
  312. // add an existing key
  313. auto res2 = j.emplace("foo", "bad");
  314. CHECK(res2.second == false);
  315. CHECK(*res2.first == "bar");
  316. // check final object
  317. CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
  318. }
  319. }
  320. SECTION("other type")
  321. {
  322. json j = 1;
  323. CHECK_THROWS_WITH_AS(j.emplace("foo", "bar"), "[json.exception.type_error.311] cannot use emplace() with number", json::type_error&);
  324. }
  325. }
  326. SECTION("operator+=")
  327. {
  328. SECTION("to array")
  329. {
  330. SECTION("json&&")
  331. {
  332. SECTION("null")
  333. {
  334. json j;
  335. j += 1;
  336. j += 2;
  337. CHECK(j.type() == json::value_t::array);
  338. CHECK(j == json({1, 2}));
  339. }
  340. SECTION("array")
  341. {
  342. json j = {1, 2, 3};
  343. j += "Hello";
  344. CHECK(j.type() == json::value_t::array);
  345. CHECK(j == json({1, 2, 3, "Hello"}));
  346. }
  347. SECTION("other type")
  348. {
  349. json j = 1;
  350. CHECK_THROWS_WITH_AS(j += "Hello", "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  351. }
  352. }
  353. SECTION("const json&")
  354. {
  355. SECTION("null")
  356. {
  357. json j;
  358. json const k(1);
  359. j += k;
  360. j += k;
  361. CHECK(j.type() == json::value_t::array);
  362. CHECK(j == json({1, 1}));
  363. }
  364. SECTION("array")
  365. {
  366. json j = {1, 2, 3};
  367. json const k("Hello");
  368. j += k;
  369. CHECK(j.type() == json::value_t::array);
  370. CHECK(j == json({1, 2, 3, "Hello"}));
  371. }
  372. SECTION("other type")
  373. {
  374. json j = 1;
  375. json const k("Hello");
  376. CHECK_THROWS_WITH_AS(j += k, "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  377. }
  378. }
  379. }
  380. SECTION("to object")
  381. {
  382. SECTION("null")
  383. {
  384. json j;
  385. j += json::object_t::value_type({"one", 1});
  386. j += json::object_t::value_type({"two", 2});
  387. CHECK(j.type() == json::value_t::object);
  388. CHECK(j.size() == 2);
  389. CHECK(j["one"] == json(1));
  390. CHECK(j["two"] == json(2));
  391. }
  392. SECTION("object")
  393. {
  394. json j(json::value_t::object);
  395. j += json::object_t::value_type({"one", 1});
  396. j += json::object_t::value_type({"two", 2});
  397. CHECK(j.size() == 2);
  398. CHECK(j["one"] == json(1));
  399. CHECK(j["two"] == json(2));
  400. }
  401. SECTION("other type")
  402. {
  403. json j = 1;
  404. json const k("Hello");
  405. CHECK_THROWS_WITH_AS(j += json::object_t::value_type({"one", 1}), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
  406. }
  407. }
  408. SECTION("with initializer_list")
  409. {
  410. SECTION("null")
  411. {
  412. json j;
  413. j += {"foo", "bar"};
  414. CHECK(j == json::array({{"foo", "bar"}}));
  415. json k;
  416. k += {1, 2, 3};
  417. CHECK(k == json::array({{1, 2, 3}}));
  418. }
  419. SECTION("array")
  420. {
  421. json j = {1, 2, 3};
  422. j += {"foo", "bar"};
  423. CHECK(j == json({1, 2, 3, {"foo", "bar"}}));
  424. json k = {1, 2, 3};
  425. k += {1, 2, 3};
  426. CHECK(k == json({1, 2, 3, {1, 2, 3}}));
  427. }
  428. SECTION("object")
  429. {
  430. json j = {{"key1", 1}};
  431. j += {"key2", "bar"};
  432. CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
  433. json k = {{"key1", 1}};
  434. CHECK_THROWS_WITH_AS((k += {1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object", json::type_error&);
  435. }
  436. }
  437. }
  438. SECTION("insert()")
  439. {
  440. json j_array = {1, 2, 3, 4};
  441. json j_value = 5;
  442. SECTION("value at position")
  443. {
  444. SECTION("insert before begin()")
  445. {
  446. auto it = j_array.insert(j_array.begin(), j_value);
  447. CHECK(j_array.size() == 5);
  448. CHECK(*it == j_value);
  449. CHECK(j_array.begin() == it);
  450. CHECK(j_array == json({5, 1, 2, 3, 4}));
  451. }
  452. SECTION("insert in the middle")
  453. {
  454. auto it = j_array.insert(j_array.begin() + 2, j_value);
  455. CHECK(j_array.size() == 5);
  456. CHECK(*it == j_value);
  457. CHECK((it - j_array.begin()) == 2);
  458. CHECK(j_array == json({1, 2, 5, 3, 4}));
  459. }
  460. SECTION("insert before end()")
  461. {
  462. auto it = j_array.insert(j_array.end(), j_value);
  463. CHECK(j_array.size() == 5);
  464. CHECK(*it == j_value);
  465. CHECK((j_array.end() - it) == 1);
  466. CHECK(j_array == json({1, 2, 3, 4, 5}));
  467. }
  468. }
  469. SECTION("rvalue at position")
  470. {
  471. SECTION("insert before begin()")
  472. {
  473. auto it = j_array.insert(j_array.begin(), 5);
  474. CHECK(j_array.size() == 5);
  475. CHECK(*it == j_value);
  476. CHECK(j_array.begin() == it);
  477. CHECK(j_array == json({5, 1, 2, 3, 4}));
  478. }
  479. SECTION("insert in the middle")
  480. {
  481. auto it = j_array.insert(j_array.begin() + 2, 5);
  482. CHECK(j_array.size() == 5);
  483. CHECK(*it == j_value);
  484. CHECK((it - j_array.begin()) == 2);
  485. CHECK(j_array == json({1, 2, 5, 3, 4}));
  486. }
  487. SECTION("insert before end()")
  488. {
  489. auto it = j_array.insert(j_array.end(), 5);
  490. CHECK(j_array.size() == 5);
  491. CHECK(*it == j_value);
  492. CHECK((j_array.end() - it) == 1);
  493. CHECK(j_array == json({1, 2, 3, 4, 5}));
  494. }
  495. }
  496. SECTION("copies at position")
  497. {
  498. SECTION("insert before begin()")
  499. {
  500. auto it = j_array.insert(j_array.begin(), 3, 5);
  501. CHECK(j_array.size() == 7);
  502. CHECK(*it == j_value);
  503. CHECK(j_array.begin() == it);
  504. CHECK(j_array == json({5, 5, 5, 1, 2, 3, 4}));
  505. }
  506. SECTION("insert in the middle")
  507. {
  508. auto it = j_array.insert(j_array.begin() + 2, 3, 5);
  509. CHECK(j_array.size() == 7);
  510. CHECK(*it == j_value);
  511. CHECK((it - j_array.begin()) == 2);
  512. CHECK(j_array == json({1, 2, 5, 5, 5, 3, 4}));
  513. }
  514. SECTION("insert before end()")
  515. {
  516. auto it = j_array.insert(j_array.end(), 3, 5);
  517. CHECK(j_array.size() == 7);
  518. CHECK(*it == j_value);
  519. CHECK((j_array.end() - it) == 3);
  520. CHECK(j_array == json({1, 2, 3, 4, 5, 5, 5}));
  521. }
  522. SECTION("insert nothing (count = 0)")
  523. {
  524. auto it = j_array.insert(j_array.end(), 0, 5);
  525. CHECK(j_array.size() == 4);
  526. // the returned iterator points to the first inserted element;
  527. // there were 4 elements, so it should point to the 5th
  528. CHECK(it == j_array.begin() + 4);
  529. CHECK(j_array == json({1, 2, 3, 4}));
  530. }
  531. }
  532. SECTION("range for array")
  533. {
  534. json j_other_array = {"first", "second"};
  535. SECTION("proper usage")
  536. {
  537. auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());
  538. CHECK(j_array.size() == 6);
  539. CHECK(*it == *j_other_array.begin());
  540. CHECK((j_array.end() - it) == 2);
  541. CHECK(j_array == json({1, 2, 3, 4, "first", "second"}));
  542. }
  543. SECTION("empty range")
  544. {
  545. auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());
  546. CHECK(j_array.size() == 4);
  547. CHECK(it == j_array.end());
  548. CHECK(j_array == json({1, 2, 3, 4}));
  549. }
  550. SECTION("invalid iterators")
  551. {
  552. json j_other_array2 = {"first", "second"};
  553. CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), "[json.exception.invalid_iterator.211] passed iterators may not belong to container",
  554. json::invalid_iterator&);
  555. CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), "[json.exception.invalid_iterator.210] iterators do not fit",
  556. json::invalid_iterator&);
  557. }
  558. }
  559. SECTION("range for object")
  560. {
  561. json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
  562. json j_object2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};
  563. SECTION("proper usage")
  564. {
  565. j_object1.insert(j_object2.begin(), j_object2.end());
  566. CHECK(j_object1.size() == 4);
  567. }
  568. SECTION("empty range")
  569. {
  570. j_object1.insert(j_object2.begin(), j_object2.begin());
  571. CHECK(j_object1.size() == 2);
  572. }
  573. SECTION("invalid iterators")
  574. {
  575. json const j_other_array2 = {"first", "second"};
  576. CHECK_THROWS_WITH_AS(j_array.insert(j_object2.begin(), j_object2.end()), "[json.exception.type_error.309] cannot use insert() with array", json::type_error&);
  577. CHECK_THROWS_WITH_AS(j_object1.insert(j_object1.begin(), j_object2.end()), "[json.exception.invalid_iterator.210] iterators do not fit", json::invalid_iterator&);
  578. CHECK_THROWS_WITH_AS(j_object1.insert(j_array.begin(), j_array.end()), "[json.exception.invalid_iterator.202] iterators first and last must point to objects", json::invalid_iterator&);
  579. }
  580. }
  581. SECTION("initializer list at position")
  582. {
  583. SECTION("insert before begin()")
  584. {
  585. auto it = j_array.insert(j_array.begin(), {7, 8, 9});
  586. CHECK(j_array.size() == 7);
  587. CHECK(*it == json(7));
  588. CHECK(j_array.begin() == it);
  589. CHECK(j_array == json({7, 8, 9, 1, 2, 3, 4}));
  590. }
  591. SECTION("insert in the middle")
  592. {
  593. auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9});
  594. CHECK(j_array.size() == 7);
  595. CHECK(*it == json(7));
  596. CHECK((it - j_array.begin()) == 2);
  597. CHECK(j_array == json({1, 2, 7, 8, 9, 3, 4}));
  598. }
  599. SECTION("insert before end()")
  600. {
  601. auto it = j_array.insert(j_array.end(), {7, 8, 9});
  602. CHECK(j_array.size() == 7);
  603. CHECK(*it == json(7));
  604. CHECK((j_array.end() - it) == 3);
  605. CHECK(j_array == json({1, 2, 3, 4, 7, 8, 9}));
  606. }
  607. }
  608. SECTION("invalid iterator")
  609. {
  610. // pass iterator to a different array
  611. json j_another_array = {1, 2};
  612. json j_yet_another_array = {"first", "second"};
  613. CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
  614. CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_value), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
  615. CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10, 11), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
  616. CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
  617. CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
  618. }
  619. SECTION("non-array type")
  620. {
  621. // call insert on a non-array type
  622. json j_nonarray = 3;
  623. json j_yet_another_array = {"first", "second"};
  624. CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
  625. CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_value), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
  626. CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
  627. CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(), j_yet_another_array.end()), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
  628. CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
  629. }
  630. }
  631. SECTION("update()")
  632. {
  633. SECTION("non-recursive (default)")
  634. {
  635. json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
  636. json j_object2 = {{"three", "drei"}, {"two", "zwo"}};
  637. json j_array = {1, 2, 3, 4};
  638. SECTION("const reference")
  639. {
  640. SECTION("proper usage")
  641. {
  642. j_object1.update(j_object2);
  643. CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
  644. json j_null;
  645. j_null.update(j_object2);
  646. CHECK(j_null == j_object2);
  647. }
  648. SECTION("wrong types")
  649. {
  650. CHECK_THROWS_WITH_AS(j_array.update(j_object1), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
  651. CHECK_THROWS_WITH_AS(j_object1.update(j_array), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
  652. }
  653. }
  654. SECTION("iterator range")
  655. {
  656. SECTION("proper usage")
  657. {
  658. j_object1.update(j_object2.begin(), j_object2.end());
  659. CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
  660. json j_null;
  661. j_null.update(j_object2.begin(), j_object2.end());
  662. CHECK(j_null == j_object2);
  663. }
  664. SECTION("empty range")
  665. {
  666. j_object1.update(j_object2.begin(), j_object2.begin());
  667. CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwei"}}));
  668. }
  669. SECTION("invalid iterators")
  670. {
  671. json const j_other_array2 = {"first", "second"};
  672. CHECK_THROWS_WITH_AS(j_array.update(j_object2.begin(), j_object2.end()), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
  673. CHECK_THROWS_WITH_AS(j_object1.update(j_object1.begin(), j_object2.end()), "[json.exception.invalid_iterator.210] iterators do not fit", json::invalid_iterator&);
  674. CHECK_THROWS_WITH_AS(j_object1.update(j_array.begin(), j_array.end()), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
  675. }
  676. }
  677. }
  678. SECTION("recursive")
  679. {
  680. SECTION("const reference")
  681. {
  682. SECTION("extend object")
  683. {
  684. json j1 = {{"string", "s"}, {"numbers", {{"one", 1}}}};
  685. json const j2 = {{"string", "t"}, {"numbers", {{"two", 2}}}};
  686. j1.update(j2, true);
  687. CHECK(j1 == json({{"string", "t"}, {"numbers", {{"one", 1}, {"two", 2}}}}));
  688. }
  689. SECTION("replace object")
  690. {
  691. json j1 = {{"string", "s"}, {"numbers", {{"one", 1}}}};
  692. json const j2 = {{"string", "t"}, {"numbers", 1}};
  693. j1.update(j2, true);
  694. CHECK(j1 == json({{"string", "t"}, {"numbers", 1}}));
  695. }
  696. }
  697. }
  698. }
  699. SECTION("swap()")
  700. {
  701. SECTION("json")
  702. {
  703. SECTION("member swap")
  704. {
  705. json j("hello world");
  706. json k(42.23);
  707. j.swap(k);
  708. CHECK(j == json(42.23));
  709. CHECK(k == json("hello world"));
  710. }
  711. SECTION("nonmember swap")
  712. {
  713. json j("hello world");
  714. json k(42.23);
  715. using std::swap;
  716. swap(j, k);
  717. CHECK(j == json(42.23));
  718. CHECK(k == json("hello world"));
  719. }
  720. }
  721. SECTION("array_t")
  722. {
  723. SECTION("array_t type")
  724. {
  725. json j = {1, 2, 3, 4};
  726. json::array_t a = {"foo", "bar", "baz"};
  727. j.swap(a);
  728. CHECK(j == json({"foo", "bar", "baz"}));
  729. j.swap(a);
  730. CHECK(j == json({1, 2, 3, 4}));
  731. }
  732. SECTION("non-array_t type")
  733. {
  734. json j = 17;
  735. json::array_t a = {"foo", "bar", "baz"};
  736. CHECK_THROWS_WITH_AS(j.swap(a), "[json.exception.type_error.310] cannot use swap(array_t&) with number", json::type_error&);
  737. }
  738. }
  739. SECTION("object_t")
  740. {
  741. SECTION("object_t type")
  742. {
  743. json j = {{"one", 1}, {"two", 2}};
  744. json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
  745. j.swap(o);
  746. CHECK(j == json({{"cow", "Kuh"}, {"chicken", "Huhn"}}));
  747. j.swap(o);
  748. CHECK(j == json({{"one", 1}, {"two", 2}}));
  749. }
  750. SECTION("non-object_t type")
  751. {
  752. json j = 17;
  753. json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
  754. CHECK_THROWS_WITH_AS(j.swap(o), "[json.exception.type_error.310] cannot use swap(object_t&) with number", json::type_error&);
  755. }
  756. }
  757. SECTION("string_t")
  758. {
  759. SECTION("string_t type")
  760. {
  761. json j = "Hello world";
  762. json::string_t s = "Hallo Welt";
  763. j.swap(s);
  764. CHECK(j == json("Hallo Welt"));
  765. j.swap(s);
  766. CHECK(j == json("Hello world"));
  767. }
  768. SECTION("non-string_t type")
  769. {
  770. json j = 17;
  771. json::string_t s = "Hallo Welt";
  772. CHECK_THROWS_WITH_AS(j.swap(s), "[json.exception.type_error.310] cannot use swap(string_t&) with number", json::type_error&);
  773. }
  774. }
  775. SECTION("binary_t")
  776. {
  777. SECTION("binary_t type")
  778. {
  779. json j = json::binary({1, 2, 3, 4});
  780. json::binary_t s = {{5, 6, 7, 8}};
  781. j.swap(s);
  782. CHECK(j == json::binary({5, 6, 7, 8}));
  783. j.swap(s);
  784. CHECK(j == json::binary({1, 2, 3, 4}));
  785. }
  786. SECTION("binary_t::container_type type")
  787. {
  788. json j = json::binary({1, 2, 3, 4});
  789. std::vector<std::uint8_t> s = {{5, 6, 7, 8}};
  790. j.swap(s);
  791. CHECK(j == json::binary({5, 6, 7, 8}));
  792. j.swap(s);
  793. CHECK(j == json::binary({1, 2, 3, 4}));
  794. }
  795. SECTION("non-binary_t type")
  796. {
  797. json j = 17;
  798. json::binary_t s1 = {{1, 2, 3, 4}};
  799. std::vector<std::uint8_t> s2 = {{5, 6, 7, 8}};
  800. CHECK_THROWS_WITH_AS(j.swap(s1), "[json.exception.type_error.310] cannot use swap(binary_t&) with number", json::type_error);
  801. CHECK_THROWS_WITH_AS(j.swap(s2), "[json.exception.type_error.310] cannot use swap(binary_t::container_type&) with number", json::type_error);
  802. }
  803. }
  804. }
  805. }