1// __ _____ _____ _____ 2// __| | __| | | | JSON for Modern C++ (supporting code) 3// | | |__ | | | | | | version 3.11.2 4// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5// 6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7// SPDX-License-Identifier: MIT 8 9#include "doctest_compatibility.h" 10 11#include <nlohmann/json.hpp> 12using nlohmann::json; 13 14TEST_CASE("reference access") 15{ 16 // create a JSON value with different types 17 json json_types = 18 { 19 {"boolean", true}, 20 { 21 "number", { 22 {"integer", 42}, 23 {"floating-point", 17.23} 24 } 25 }, 26 {"string", "Hello, world!"}, 27 {"array", {1, 2, 3, 4, 5}}, 28 {"null", nullptr} 29 }; 30 31 SECTION("reference access to object_t") 32 { 33 using test_type = json::object_t; 34 json value = {{"one", 1}, {"two", 2}}; 35 36 // check if references are returned correctly 37 auto& p1 = value.get_ref<test_type&>(); 38 CHECK(&p1 == value.get_ptr<test_type*>()); 39 CHECK(p1 == value.get<test_type>()); 40 41 const auto& p2 = value.get_ref<const test_type&>(); 42 CHECK(&p2 == value.get_ptr<const test_type*>()); 43 CHECK(p2 == value.get<test_type>()); 44 45 // check if mismatching references throw correctly 46 CHECK_NOTHROW(value.get_ref<json::object_t&>()); 47 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), 48 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 49 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), 50 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 51 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), 52 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 53 CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), 54 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 55 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), 56 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 57 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), 58 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&); 59 } 60 61 SECTION("const reference access to const object_t") 62 { 63 using test_type = json::object_t; 64 const json value = {{"one", 1}, {"two", 2}}; 65 66 // this should not compile 67 // test_type& p1 = value.get_ref<test_type&>(); 68 69 // check if references are returned correctly 70 const auto& p2 = value.get_ref<const test_type&>(); 71 CHECK(&p2 == value.get_ptr<const test_type*>()); 72 CHECK(p2 == value.get<test_type>()); 73 } 74 75 SECTION("reference access to array_t") 76 { 77 using test_type = json::array_t; 78 json value = {1, 2, 3, 4}; 79 80 // check if references are returned correctly 81 auto& p1 = value.get_ref<test_type&>(); 82 CHECK(&p1 == value.get_ptr<test_type*>()); 83 CHECK(p1 == value.get<test_type>()); 84 85 const auto& p2 = value.get_ref<const test_type&>(); 86 CHECK(&p2 == value.get_ptr<const test_type*>()); 87 CHECK(p2 == value.get<test_type>()); 88 89 // check if mismatching references throw correctly 90 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), 91 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 92 CHECK_NOTHROW(value.get_ref<json::array_t&>()); 93 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), 94 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 95 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), 96 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 97 CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), 98 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 99 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), 100 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 101 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), 102 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&); 103 } 104 105 SECTION("reference access to string_t") 106 { 107 using test_type = json::string_t; 108 json value = "hello"; 109 110 // check if references are returned correctly 111 auto& p1 = value.get_ref<test_type&>(); 112 CHECK(&p1 == value.get_ptr<test_type*>()); 113 CHECK(p1 == value.get<test_type>()); 114 115 const auto& p2 = value.get_ref<const test_type&>(); 116 CHECK(&p2 == value.get_ptr<const test_type*>()); 117 CHECK(p2 == value.get<test_type>()); 118 119 // check if mismatching references throw correctly 120 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), 121 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 122 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), 123 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 124 CHECK_NOTHROW(value.get_ref<json::string_t&>()); 125 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), 126 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 127 CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), 128 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 129 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), 130 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 131 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), 132 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&); 133 } 134 135 SECTION("reference access to boolean_t") 136 { 137 using test_type = json::boolean_t; 138 json value = false; 139 140 // check if references are returned correctly 141 auto& p1 = value.get_ref<test_type&>(); 142 CHECK(&p1 == value.get_ptr<test_type*>()); 143 CHECK(p1 == value.get<test_type>()); 144 145 const auto& p2 = value.get_ref<const test_type&>(); 146 CHECK(&p2 == value.get_ptr<const test_type*>()); 147 CHECK(p2 == value.get<test_type>()); 148 149 // check if mismatching references throw correctly 150 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), 151 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 152 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), 153 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 154 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), 155 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 156 CHECK_NOTHROW(value.get_ref<json::boolean_t&>()); 157 CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), 158 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 159 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), 160 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 161 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), 162 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&); 163 } 164 165 SECTION("reference access to number_integer_t") 166 { 167 using test_type = json::number_integer_t; 168 json value = -23; 169 170 // check if references are returned correctly 171 auto& p1 = value.get_ref<test_type&>(); 172 CHECK(&p1 == value.get_ptr<test_type*>()); 173 CHECK(p1 == value.get<test_type>()); 174 175 const auto& p2 = value.get_ref<const test_type&>(); 176 CHECK(&p2 == value.get_ptr<const test_type*>()); 177 CHECK(p2 == value.get<test_type>()); 178 179 // check if mismatching references throw correctly 180 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), 181 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 182 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), 183 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 184 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), 185 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 186 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), 187 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 188 CHECK_NOTHROW(value.get_ref<json::number_integer_t&>()); 189 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), 190 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 191 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), 192 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 193 } 194 195 SECTION("reference access to number_unsigned_t") 196 { 197 using test_type = json::number_unsigned_t; 198 json value = 23u; 199 200 // check if references are returned correctly 201 auto& p1 = value.get_ref<test_type&>(); 202 CHECK(&p1 == value.get_ptr<test_type*>()); 203 CHECK(p1 == value.get<test_type>()); 204 205 const auto& p2 = value.get_ref<const test_type&>(); 206 CHECK(&p2 == value.get_ptr<const test_type*>()); 207 CHECK(p2 == value.get<test_type>()); 208 209 // check if mismatching references throw correctly 210 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), 211 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 212 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), 213 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 214 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), 215 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 216 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), 217 "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 218 //CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), 219 // "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 220 CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>()); 221 CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 222 } 223 224 SECTION("reference access to number_float_t") 225 { 226 using test_type = json::number_float_t; 227 json value = 42.23; 228 229 // check if references are returned correctly 230 auto& p1 = value.get_ref<test_type&>(); 231 CHECK(&p1 == value.get_ptr<test_type*>()); 232 CHECK(p1 == value.get<test_type>()); 233 234 const auto& p2 = value.get_ref<const test_type&>(); 235 CHECK(&p2 == value.get_ptr<const test_type*>()); 236 CHECK(p2 == value.get<test_type>()); 237 238 // check if mismatching references throw correctly 239 CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 240 CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 241 CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 242 CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 243 CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 244 CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&); 245 CHECK_NOTHROW(value.get_ref<json::number_float_t&>()); 246 } 247} 248