• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.10.0
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("reference access")
36 {
37     // create a JSON value with different types
38     json json_types =
39     {
40         {"boolean", true},
41         {
42             "number", {
43                 {"integer", 42},
44                 {"floating-point", 17.23}
45             }
46         },
47         {"string", "Hello, world!"},
48         {"array", {1, 2, 3, 4, 5}},
49         {"null", nullptr}
50     };
51 
52     SECTION("reference access to object_t")
53     {
54         using test_type = json::object_t;
55         json value = {{"one", 1}, {"two", 2}};
56 
57         // check if references are returned correctly
58         auto& p1 = value.get_ref<test_type&>();
59         CHECK(&p1 == value.get_ptr<test_type*>());
60         CHECK(p1 == value.get<test_type>());
61 
62         const auto& p2 = value.get_ref<const test_type&>();
63         CHECK(&p2 == value.get_ptr<const test_type*>());
64         CHECK(p2 == value.get<test_type>());
65 
66         // check if mismatching references throw correctly
67         CHECK_NOTHROW(value.get_ref<json::object_t&>());
68         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
69         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
70                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
71         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
72         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
73                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
74         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
75         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
76                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
77         CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
78         CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
79                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
80         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
81         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
82                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
83         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
84         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
85                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
86     }
87 
88     SECTION("const reference access to const object_t")
89     {
90         using test_type = json::object_t;
91         const json value = {{"one", 1}, {"two", 2}};
92 
93         // this should not compile
94         // test_type& p1 = value.get_ref<test_type&>();
95 
96         // check if references are returned correctly
97         const auto& p2 = value.get_ref<const test_type&>();
98         CHECK(&p2 == value.get_ptr<const test_type*>());
99         CHECK(p2 == value.get<test_type>());
100     }
101 
102     SECTION("reference access to array_t")
103     {
104         using test_type = json::array_t;
105         json value = {1, 2, 3, 4};
106 
107         // check if references are returned correctly
108         auto& p1 = value.get_ref<test_type&>();
109         CHECK(&p1 == value.get_ptr<test_type*>());
110         CHECK(p1 == value.get<test_type>());
111 
112         const auto& p2 = value.get_ref<const test_type&>();
113         CHECK(&p2 == value.get_ptr<const test_type*>());
114         CHECK(p2 == value.get<test_type>());
115 
116         // check if mismatching references throw correctly
117         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
118         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
119                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
120         CHECK_NOTHROW(value.get_ref<json::array_t&>());
121         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
122         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
123                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
124         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
125         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
126                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
127         CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
128         CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
129                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
130         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
131         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
132                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
133         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
134         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
135                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
136     }
137 
138     SECTION("reference access to string_t")
139     {
140         using test_type = json::string_t;
141         json value = "hello";
142 
143         // check if references are returned correctly
144         auto& p1 = value.get_ref<test_type&>();
145         CHECK(&p1 == value.get_ptr<test_type*>());
146         CHECK(p1 == value.get<test_type>());
147 
148         const auto& p2 = value.get_ref<const test_type&>();
149         CHECK(&p2 == value.get_ptr<const test_type*>());
150         CHECK(p2 == value.get<test_type>());
151 
152         // check if mismatching references throw correctly
153         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
154         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
155                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
156         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
157         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
158                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
159         CHECK_NOTHROW(value.get_ref<json::string_t&>());
160         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
161         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
162                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
163         CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
164         CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
165                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
166         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
167         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
168                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
169         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
170         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
171                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
172     }
173 
174     SECTION("reference access to boolean_t")
175     {
176         using test_type = json::boolean_t;
177         json value = false;
178 
179         // check if references are returned correctly
180         auto& p1 = value.get_ref<test_type&>();
181         CHECK(&p1 == value.get_ptr<test_type*>());
182         CHECK(p1 == value.get<test_type>());
183 
184         const auto& p2 = value.get_ref<const test_type&>();
185         CHECK(&p2 == value.get_ptr<const test_type*>());
186         CHECK(p2 == value.get<test_type>());
187 
188         // check if mismatching references throw correctly
189         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
190         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
191                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
192         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
193         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
194                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
195         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
196         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
197                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
198         CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
199         CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
200         CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
201                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
202         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
203         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
204                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
205         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
206         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
207                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
208     }
209 
210     SECTION("reference access to number_integer_t")
211     {
212         using test_type = json::number_integer_t;
213         json value = -23;
214 
215         // check if references are returned correctly
216         auto& p1 = value.get_ref<test_type&>();
217         CHECK(&p1 == value.get_ptr<test_type*>());
218         CHECK(p1 == value.get<test_type>());
219 
220         const auto& p2 = value.get_ref<const test_type&>();
221         CHECK(&p2 == value.get_ptr<const test_type*>());
222         CHECK(p2 == value.get<test_type>());
223 
224         // check if mismatching references throw correctly
225         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
226         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
227                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
228         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
229         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
230                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
231         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
232         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
233                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
234         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
235         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
236                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
237         CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
238         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
239         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
240                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
241         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
242         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
243                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
244     }
245 
246     SECTION("reference access to number_unsigned_t")
247     {
248         using test_type = json::number_unsigned_t;
249         json value = 23u;
250 
251         // check if references are returned correctly
252         auto& p1 = value.get_ref<test_type&>();
253         CHECK(&p1 == value.get_ptr<test_type*>());
254         CHECK(p1 == value.get<test_type>());
255 
256         const auto& p2 = value.get_ref<const test_type&>();
257         CHECK(&p2 == value.get_ptr<const test_type*>());
258         CHECK(p2 == value.get<test_type>());
259 
260         // check if mismatching references throw correctly
261         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
262         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
263                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
264         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
265         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
266                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
267         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
268         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
269                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
270         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
271         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
272                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
273         //CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
274         //CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
275         //    "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
276         CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
277         CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
278         CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
279                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
280     }
281 
282     SECTION("reference access to number_float_t")
283     {
284         using test_type = json::number_float_t;
285         json value = 42.23;
286 
287         // check if references are returned correctly
288         auto& p1 = value.get_ref<test_type&>();
289         CHECK(&p1 == value.get_ptr<test_type*>());
290         CHECK(p1 == value.get<test_type>());
291 
292         const auto& p2 = value.get_ref<const test_type&>();
293         CHECK(&p2 == value.get_ptr<const test_type*>());
294         CHECK(p2 == value.get<test_type>());
295 
296         // check if mismatching references throw correctly
297         CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
298         CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
299                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
300         CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
301         CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
302                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
303         CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
304         CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
305                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
306         CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
307         CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
308                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
309         CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
310         CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
311                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
312         CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
313         CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
314                           "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
315         CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
316     }
317 }
318