1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ (supporting code) 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>. 7c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 8c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 9c5f01b2fSopenharmony_ci 10c5f01b2fSopenharmony_ci#include "doctest_compatibility.h" 11c5f01b2fSopenharmony_ci 12c5f01b2fSopenharmony_ci#ifdef JSON_DIAGNOSTICS 13c5f01b2fSopenharmony_ci #undef JSON_DIAGNOSTICS 14c5f01b2fSopenharmony_ci#endif 15c5f01b2fSopenharmony_ci 16c5f01b2fSopenharmony_ci#define JSON_DIAGNOSTICS 1 17c5f01b2fSopenharmony_ci 18c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp> 19c5f01b2fSopenharmony_ciusing nlohmann::json; 20c5f01b2fSopenharmony_ci 21c5f01b2fSopenharmony_ciTEST_CASE("Better diagnostics") 22c5f01b2fSopenharmony_ci{ 23c5f01b2fSopenharmony_ci SECTION("empty JSON Pointer") 24c5f01b2fSopenharmony_ci { 25c5f01b2fSopenharmony_ci json j = 1; 26c5f01b2fSopenharmony_ci std::string s; 27c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(s = j.get<std::string>(), "[json.exception.type_error.302] type must be string, but is number", json::type_error); 28c5f01b2fSopenharmony_ci } 29c5f01b2fSopenharmony_ci 30c5f01b2fSopenharmony_ci SECTION("invalid type") 31c5f01b2fSopenharmony_ci { 32c5f01b2fSopenharmony_ci json j; 33c5f01b2fSopenharmony_ci j["a"]["b"]["c"] = 1; 34c5f01b2fSopenharmony_ci std::string s; 35c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(s = j["a"]["b"]["c"].get<std::string>(), "[json.exception.type_error.302] (/a/b/c) type must be string, but is number", json::type_error); 36c5f01b2fSopenharmony_ci } 37c5f01b2fSopenharmony_ci 38c5f01b2fSopenharmony_ci SECTION("missing key") 39c5f01b2fSopenharmony_ci { 40c5f01b2fSopenharmony_ci json j; 41c5f01b2fSopenharmony_ci j["object"]["object"] = true; 42c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j["object"].at("not_found"), "[json.exception.out_of_range.403] (/object) key 'not_found' not found", json::out_of_range); 43c5f01b2fSopenharmony_ci } 44c5f01b2fSopenharmony_ci 45c5f01b2fSopenharmony_ci SECTION("array index out of range") 46c5f01b2fSopenharmony_ci { 47c5f01b2fSopenharmony_ci json j; 48c5f01b2fSopenharmony_ci j["array"][4] = true; 49c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j["array"].at(5), "[json.exception.out_of_range.401] (/array) array index 5 is out of range", json::out_of_range); 50c5f01b2fSopenharmony_ci } 51c5f01b2fSopenharmony_ci 52c5f01b2fSopenharmony_ci SECTION("array index at wrong type") 53c5f01b2fSopenharmony_ci { 54c5f01b2fSopenharmony_ci json j; 55c5f01b2fSopenharmony_ci j["array"][4] = true; 56c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j["array"][4][5], "[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean", json::type_error); 57c5f01b2fSopenharmony_ci } 58c5f01b2fSopenharmony_ci 59c5f01b2fSopenharmony_ci SECTION("wrong iterator") 60c5f01b2fSopenharmony_ci { 61c5f01b2fSopenharmony_ci json j; 62c5f01b2fSopenharmony_ci j["array"] = json::array(); 63c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j["array"].erase(j.begin()), "[json.exception.invalid_iterator.202] (/array) iterator does not fit current value", json::invalid_iterator); 64c5f01b2fSopenharmony_ci } 65c5f01b2fSopenharmony_ci 66c5f01b2fSopenharmony_ci SECTION("JSON Pointer escaping") 67c5f01b2fSopenharmony_ci { 68c5f01b2fSopenharmony_ci json j; 69c5f01b2fSopenharmony_ci j["a/b"]["m~n"] = 1; 70c5f01b2fSopenharmony_ci std::string s; 71c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(s = j["a/b"]["m~n"].get<std::string>(), "[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number", json::type_error); 72c5f01b2fSopenharmony_ci } 73c5f01b2fSopenharmony_ci 74c5f01b2fSopenharmony_ci SECTION("Parse error") 75c5f01b2fSopenharmony_ci { 76c5f01b2fSopenharmony_ci json _; 77c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(_ = json::parse(""), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error); 78c5f01b2fSopenharmony_ci } 79c5f01b2fSopenharmony_ci 80c5f01b2fSopenharmony_ci SECTION("Wrong type in update()") 81c5f01b2fSopenharmony_ci { 82c5f01b2fSopenharmony_ci json j = {{"foo", "bar"}}; 83c5f01b2fSopenharmony_ci json k = {{"bla", 1}}; 84c5f01b2fSopenharmony_ci 85c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j.update(k["bla"].begin(), k["bla"].end()), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error); 86c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j.update(k["bla"]), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error); 87c5f01b2fSopenharmony_ci } 88c5f01b2fSopenharmony_ci} 89c5f01b2fSopenharmony_ci 90c5f01b2fSopenharmony_ciTEST_CASE("Regression tests for extended diagnostics") 91c5f01b2fSopenharmony_ci{ 92c5f01b2fSopenharmony_ci SECTION("Regression test for https://github.com/nlohmann/json/pull/2562#pullrequestreview-574858448") 93c5f01b2fSopenharmony_ci { 94c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(json({"0", "0"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error); 95c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(json({"0", "1"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error); 96c5f01b2fSopenharmony_ci } 97c5f01b2fSopenharmony_ci 98c5f01b2fSopenharmony_ci SECTION("Regression test for https://github.com/nlohmann/json/pull/2562/files/380a613f2b5d32425021129cd1f371ddcfd54ddf#r563259793") 99c5f01b2fSopenharmony_ci { 100c5f01b2fSopenharmony_ci json j; 101c5f01b2fSopenharmony_ci j["/foo"] = {1, 2, 3}; 102c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error); 103c5f01b2fSopenharmony_ci } 104c5f01b2fSopenharmony_ci 105c5f01b2fSopenharmony_ci SECTION("Regression test for issue #2838 - Assertion failure when inserting into arrays with JSON_DIAGNOSTICS set") 106c5f01b2fSopenharmony_ci { 107c5f01b2fSopenharmony_ci // void push_back(basic_json&& val) 108c5f01b2fSopenharmony_ci { 109c5f01b2fSopenharmony_ci json j_arr = json::array(); 110c5f01b2fSopenharmony_ci j_arr.push_back(json::object()); 111c5f01b2fSopenharmony_ci j_arr.push_back(json::object()); 112c5f01b2fSopenharmony_ci j_arr.push_back(json::object()); 113c5f01b2fSopenharmony_ci j_arr.push_back(json::object()); 114c5f01b2fSopenharmony_ci json j_obj = json::object(); 115c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 116c5f01b2fSopenharmony_ci } 117c5f01b2fSopenharmony_ci 118c5f01b2fSopenharmony_ci // void push_back(const basic_json& val) 119c5f01b2fSopenharmony_ci { 120c5f01b2fSopenharmony_ci json j_arr = json::array(); 121c5f01b2fSopenharmony_ci auto object = json::object(); 122c5f01b2fSopenharmony_ci j_arr.push_back(object); 123c5f01b2fSopenharmony_ci j_arr.push_back(object); 124c5f01b2fSopenharmony_ci j_arr.push_back(object); 125c5f01b2fSopenharmony_ci j_arr.push_back(object); 126c5f01b2fSopenharmony_ci json j_obj = json::object(); 127c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 128c5f01b2fSopenharmony_ci } 129c5f01b2fSopenharmony_ci 130c5f01b2fSopenharmony_ci // reference emplace_back(Args&& ... args) 131c5f01b2fSopenharmony_ci { 132c5f01b2fSopenharmony_ci json j_arr = json::array(); 133c5f01b2fSopenharmony_ci j_arr.emplace_back(json::object()); 134c5f01b2fSopenharmony_ci j_arr.emplace_back(json::object()); 135c5f01b2fSopenharmony_ci j_arr.emplace_back(json::object()); 136c5f01b2fSopenharmony_ci j_arr.emplace_back(json::object()); 137c5f01b2fSopenharmony_ci json j_obj = json::object(); 138c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 139c5f01b2fSopenharmony_ci } 140c5f01b2fSopenharmony_ci 141c5f01b2fSopenharmony_ci // iterator insert(const_iterator pos, const basic_json& val) 142c5f01b2fSopenharmony_ci { 143c5f01b2fSopenharmony_ci json j_arr = json::array(); 144c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), json::object()); 145c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), json::object()); 146c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), json::object()); 147c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), json::object()); 148c5f01b2fSopenharmony_ci json j_obj = json::object(); 149c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 150c5f01b2fSopenharmony_ci } 151c5f01b2fSopenharmony_ci 152c5f01b2fSopenharmony_ci // iterator insert(const_iterator pos, size_type cnt, const basic_json& val) 153c5f01b2fSopenharmony_ci { 154c5f01b2fSopenharmony_ci json j_arr = json::array(); 155c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), 2, json::object()); 156c5f01b2fSopenharmony_ci json j_obj = json::object(); 157c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 158c5f01b2fSopenharmony_ci } 159c5f01b2fSopenharmony_ci 160c5f01b2fSopenharmony_ci // iterator insert(const_iterator pos, const_iterator first, const_iterator last) 161c5f01b2fSopenharmony_ci { 162c5f01b2fSopenharmony_ci json j_arr = json::array(); 163c5f01b2fSopenharmony_ci json j_objects = {json::object(), json::object()}; 164c5f01b2fSopenharmony_ci j_arr.insert(j_arr.begin(), j_objects.begin(), j_objects.end()); 165c5f01b2fSopenharmony_ci json j_obj = json::object(); 166c5f01b2fSopenharmony_ci j_obj["key"] = j_arr; 167c5f01b2fSopenharmony_ci } 168c5f01b2fSopenharmony_ci } 169c5f01b2fSopenharmony_ci 170c5f01b2fSopenharmony_ci SECTION("Regression test for issue #2962 - JSON_DIAGNOSTICS assertion for ordered_json") 171c5f01b2fSopenharmony_ci { 172c5f01b2fSopenharmony_ci nlohmann::ordered_json j; 173c5f01b2fSopenharmony_ci nlohmann::ordered_json j2; 174c5f01b2fSopenharmony_ci const std::string value; 175c5f01b2fSopenharmony_ci j["first"] = value; 176c5f01b2fSopenharmony_ci j["second"] = value; 177c5f01b2fSopenharmony_ci j2["something"] = j; 178c5f01b2fSopenharmony_ci } 179c5f01b2fSopenharmony_ci 180c5f01b2fSopenharmony_ci SECTION("Regression test for issue #3007 - Parent pointers properly set when using update()") 181c5f01b2fSopenharmony_ci { 182c5f01b2fSopenharmony_ci // void update(const_reference j) 183c5f01b2fSopenharmony_ci { 184c5f01b2fSopenharmony_ci json j = json::object(); 185c5f01b2fSopenharmony_ci 186c5f01b2fSopenharmony_ci { 187c5f01b2fSopenharmony_ci json j2 = json::object(); 188c5f01b2fSopenharmony_ci j2["one"] = 1; 189c5f01b2fSopenharmony_ci 190c5f01b2fSopenharmony_ci j.update(j2); 191c5f01b2fSopenharmony_ci } 192c5f01b2fSopenharmony_ci 193c5f01b2fSopenharmony_ci // Must call operator[] on const element, otherwise m_parent gets updated. 194c5f01b2fSopenharmony_ci auto const& constJ = j; 195c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(constJ["one"].at(0), "[json.exception.type_error.304] (/one) cannot use at() with number", json::type_error); 196c5f01b2fSopenharmony_ci } 197c5f01b2fSopenharmony_ci 198c5f01b2fSopenharmony_ci // void update(const_iterator first, const_iterator last) 199c5f01b2fSopenharmony_ci { 200c5f01b2fSopenharmony_ci json j = json::object(); 201c5f01b2fSopenharmony_ci 202c5f01b2fSopenharmony_ci { 203c5f01b2fSopenharmony_ci json j2 = json::object(); 204c5f01b2fSopenharmony_ci j2["one"] = 1; 205c5f01b2fSopenharmony_ci 206c5f01b2fSopenharmony_ci j.update(j2.begin(), j2.end()); 207c5f01b2fSopenharmony_ci } 208c5f01b2fSopenharmony_ci 209c5f01b2fSopenharmony_ci // Must call operator[] on const element, otherwise m_parent gets updated. 210c5f01b2fSopenharmony_ci auto const& constJ = j; 211c5f01b2fSopenharmony_ci CHECK_THROWS_WITH_AS(constJ["one"].at(0), "[json.exception.type_error.304] (/one) cannot use at() with number", json::type_error); 212c5f01b2fSopenharmony_ci } 213c5f01b2fSopenharmony_ci 214c5f01b2fSopenharmony_ci // Code from #3007 triggering unwanted assertion without fix to update(). 215c5f01b2fSopenharmony_ci { 216c5f01b2fSopenharmony_ci json root = json::array(); 217c5f01b2fSopenharmony_ci json lower = json::object(); 218c5f01b2fSopenharmony_ci 219c5f01b2fSopenharmony_ci { 220c5f01b2fSopenharmony_ci json lowest = json::object(); 221c5f01b2fSopenharmony_ci lowest["one"] = 1; 222c5f01b2fSopenharmony_ci 223c5f01b2fSopenharmony_ci lower.update(lowest); 224c5f01b2fSopenharmony_ci } 225c5f01b2fSopenharmony_ci 226c5f01b2fSopenharmony_ci root.push_back(lower); 227c5f01b2fSopenharmony_ci } 228c5f01b2fSopenharmony_ci } 229c5f01b2fSopenharmony_ci 230c5f01b2fSopenharmony_ci SECTION("Regression test for issue #3032 - Yet another assertion failure when inserting into arrays with JSON_DIAGNOSTICS set") 231c5f01b2fSopenharmony_ci { 232c5f01b2fSopenharmony_ci // reference operator[](size_type idx) 233c5f01b2fSopenharmony_ci { 234c5f01b2fSopenharmony_ci json j_arr = json::array(); 235c5f01b2fSopenharmony_ci j_arr[0] = 0; 236c5f01b2fSopenharmony_ci j_arr[1] = 1; 237c5f01b2fSopenharmony_ci j_arr[2] = 2; 238c5f01b2fSopenharmony_ci j_arr[3] = 3; 239c5f01b2fSopenharmony_ci j_arr[4] = 4; 240c5f01b2fSopenharmony_ci j_arr[5] = 5; 241c5f01b2fSopenharmony_ci j_arr[6] = 6; 242c5f01b2fSopenharmony_ci j_arr[7] = 7; 243c5f01b2fSopenharmony_ci json j_arr_copy = j_arr; 244c5f01b2fSopenharmony_ci } 245c5f01b2fSopenharmony_ci } 246c5f01b2fSopenharmony_ci} 247