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