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