Merge branch 'develop' of https://github.com/nlohmann/json into issue2179
Conflicts: single_include/nlohmann/json.hpp
This commit is contained in:
commit
9c21285133
44 changed files with 1769 additions and 868 deletions
|
|
@ -95,6 +95,7 @@ set(files
|
|||
src/unit-algorithms.cpp
|
||||
src/unit-allocator.cpp
|
||||
src/unit-alt-string.cpp
|
||||
src/unit-assert_macro.cpp
|
||||
src/unit-bson.cpp
|
||||
src/unit-capacity.cpp
|
||||
src/unit-cbor.cpp
|
||||
|
|
@ -133,6 +134,7 @@ set(files
|
|||
src/unit-to_chars.cpp
|
||||
src/unit-ubjson.cpp
|
||||
src/unit-udt.cpp
|
||||
src/unit-udt_macro.cpp
|
||||
src/unit-unicode.cpp
|
||||
src/unit-user_defined_input.cpp
|
||||
src/unit-wstring.cpp)
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.11.0")
|
|||
)
|
||||
set_tests_properties(cmake_fetch_content_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_fetch_content
|
||||
LABELS git_required
|
||||
)
|
||||
set_tests_properties(cmake_fetch_content_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_fetch_content
|
||||
LABELS git_required
|
||||
)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ project(DummyImport CXX)
|
|||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(json
|
||||
GIT_REPOSITORY ${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||
GIT_TAG HEAD)
|
||||
get_filename_component(GIT_REPOSITORY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)
|
||||
FetchContent_Declare(json GIT_REPOSITORY ${GIT_REPOSITORY_DIRECTORY} GIT_TAG HEAD)
|
||||
|
||||
FetchContent_GetProperties(json)
|
||||
if(NOT json_POPULATED)
|
||||
|
|
|
|||
65
test/src/unit-assert_macro.cpp
Normal file
65
test/src/unit-assert_macro.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.8.0
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// avoid warning when assert does not abort
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#endif
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
/// global variable to record side effect of assert calls
|
||||
static int assert_counter;
|
||||
|
||||
/// set failure variable to true instead of calling assert(x)
|
||||
#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
// the test assumes exceptions to work
|
||||
#if not defined(JSON_NOEXCEPTION)
|
||||
TEST_CASE("JSON_ASSERT(x)")
|
||||
{
|
||||
SECTION("basic_json(first, second)")
|
||||
{
|
||||
assert_counter = 0;
|
||||
CHECK(assert_counter == 0);
|
||||
|
||||
json::iterator it;
|
||||
json j;
|
||||
|
||||
// in case assertions do not abort execution, an exception is thrown
|
||||
CHECK_THROWS_WITH_AS(json(it, j.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator);
|
||||
|
||||
// check that assertion actually happened
|
||||
CHECK(assert_counter == 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -37,14 +37,23 @@ using nlohmann::json;
|
|||
namespace
|
||||
{
|
||||
// shortcut to scan a string literal
|
||||
json::lexer::token_type scan_string(const char* s);
|
||||
json::lexer::token_type scan_string(const char* s)
|
||||
json::lexer::token_type scan_string(const char* s, const bool ignore_comments = false);
|
||||
json::lexer::token_type scan_string(const char* s, const bool ignore_comments)
|
||||
{
|
||||
auto ia = nlohmann::detail::input_adapter(s);
|
||||
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia)).scan();
|
||||
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan();
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_error_message(const char* s, const bool ignore_comments = false);
|
||||
std::string get_error_message(const char* s, const bool ignore_comments)
|
||||
{
|
||||
auto ia = nlohmann::detail::input_adapter(s);
|
||||
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments);
|
||||
lexer.scan();
|
||||
return lexer.get_error_message();
|
||||
}
|
||||
|
||||
TEST_CASE("lexer class")
|
||||
{
|
||||
SECTION("scan")
|
||||
|
|
@ -127,6 +136,8 @@ TEST_CASE("lexer class")
|
|||
// store scan() result
|
||||
const auto res = scan_string(s.c_str());
|
||||
|
||||
CAPTURE(s);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
// single characters that are valid tokens
|
||||
|
|
@ -179,4 +190,56 @@ TEST_CASE("lexer class")
|
|||
s += "\"";
|
||||
CHECK((scan_string(s.c_str()) == json::lexer::token_type::value_string));
|
||||
}
|
||||
|
||||
SECTION("fail on comments")
|
||||
{
|
||||
CHECK((scan_string("/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("/!", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/!", false) == "invalid literal");
|
||||
CHECK((scan_string("/*", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*", false) == "invalid literal");
|
||||
CHECK((scan_string("/**", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("//", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("//", false) == "invalid literal");
|
||||
CHECK((scan_string("/**/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**/", false) == "invalid literal");
|
||||
CHECK((scan_string("/** /", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/** /", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("/***/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/***/", false) == "invalid literal");
|
||||
CHECK((scan_string("/* true */", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/* true */", false) == "invalid literal");
|
||||
CHECK((scan_string("/*/**/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*/**/", false) == "invalid literal");
|
||||
CHECK((scan_string("/*/* */", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*/* */", false) == "invalid literal");
|
||||
}
|
||||
|
||||
SECTION("ignore comments")
|
||||
{
|
||||
CHECK((scan_string("/", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||
|
||||
CHECK((scan_string("/!", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/!", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||
CHECK((scan_string("/*", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*", true) == "invalid comment; missing closing '*/'");
|
||||
CHECK((scan_string("/**", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**", true) == "invalid comment; missing closing '*/'");
|
||||
|
||||
CHECK((scan_string("//", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/**/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/** /", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/** /", true) == "invalid comment; missing closing '*/'");
|
||||
|
||||
CHECK((scan_string("/***/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/*/**/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/*/* */", true) == json::lexer::token_type::end_of_input));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ class SaxCountdown : public nlohmann::json::json_sax_t
|
|||
|
||||
json parser_helper(const std::string& s);
|
||||
bool accept_helper(const std::string& s);
|
||||
void comments_helper(const std::string& s);
|
||||
|
||||
json parser_helper(const std::string& s)
|
||||
{
|
||||
|
|
@ -241,6 +242,8 @@ json parser_helper(const std::string& s)
|
|||
json::sax_parse(s, &sdp);
|
||||
CHECK(j_sax == j);
|
||||
|
||||
comments_helper(s);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
|
@ -275,11 +278,51 @@ bool accept_helper(const std::string& s)
|
|||
// 6. check if this approach came to the same result
|
||||
CHECK(ok_noexcept == ok_noexcept_cb);
|
||||
|
||||
// 7. return result
|
||||
// 7. check if comments are properly ignored
|
||||
if (ok_accept)
|
||||
{
|
||||
comments_helper(s);
|
||||
}
|
||||
|
||||
// 8. return result
|
||||
return ok_accept;
|
||||
}
|
||||
|
||||
void comments_helper(const std::string& s)
|
||||
{
|
||||
json _;
|
||||
|
||||
// parse/accept with default parser
|
||||
CHECK_NOTHROW(_ = json::parse(s));
|
||||
CHECK(json::accept(s));
|
||||
|
||||
// parse/accept while skipping comments
|
||||
CHECK_NOTHROW(_ = json::parse(s, nullptr, false, true));
|
||||
CHECK(json::accept(s, true));
|
||||
|
||||
std::vector<std::string> json_with_comments;
|
||||
|
||||
// start with a comment
|
||||
json_with_comments.push_back(std::string("// this is a comment\n") + s);
|
||||
json_with_comments.push_back(std::string("/* this is a comment */") + s);
|
||||
// end with a comment
|
||||
json_with_comments.push_back(s + "// this is a comment");
|
||||
json_with_comments.push_back(s + "/* this is a comment */");
|
||||
|
||||
// check all strings
|
||||
for (const auto& json_with_comment : json_with_comments)
|
||||
{
|
||||
CAPTURE(json_with_comment)
|
||||
CHECK_THROWS_AS(_ = json::parse(json_with_comment), json::parse_error);
|
||||
CHECK(not json::accept(json_with_comment));
|
||||
|
||||
CHECK_NOTHROW(_ = json::parse(json_with_comment, nullptr, true, true));
|
||||
CHECK(json::accept(json_with_comment, true));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("parser class")
|
||||
{
|
||||
SECTION("parse")
|
||||
|
|
@ -1834,4 +1877,10 @@ TEST_CASE("parser class")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("error messages for comments")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ TEST_CASE("concepts")
|
|||
json j {1, 2, 3};
|
||||
json::iterator it1 = j.begin();
|
||||
json::iterator it2 = j.end();
|
||||
std::swap(it1, it2);
|
||||
swap(it1, it2);
|
||||
CHECK(it1 == j.end());
|
||||
CHECK(it2 == j.begin());
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ TEST_CASE("concepts")
|
|||
json j {1, 2, 3};
|
||||
json::const_iterator it1 = j.cbegin();
|
||||
json::const_iterator it2 = j.cend();
|
||||
std::swap(it1, it2);
|
||||
swap(it1, it2);
|
||||
CHECK(it1 == j.end());
|
||||
CHECK(it2 == j.begin());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,12 +348,29 @@ TEST_CASE("JSON pointers")
|
|||
CHECK_THROWS_WITH(j_const["/1+1"_json_pointer] == 1,
|
||||
"[json.exception.out_of_range.404] unresolved reference token '1+1'");
|
||||
|
||||
CHECK_THROWS_AS(j["/111111111111111111111111"_json_pointer] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j["/111111111111111111111111"_json_pointer] = 1,
|
||||
"[json.exception.out_of_range.404] unresolved reference token '111111111111111111111111'");
|
||||
CHECK_THROWS_AS(j_const["/111111111111111111111111"_json_pointer] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const["/111111111111111111111111"_json_pointer] == 1,
|
||||
"[json.exception.out_of_range.404] unresolved reference token '111111111111111111111111'");
|
||||
{
|
||||
auto too_large_index = std::to_string((std::numeric_limits<unsigned long long>::max)()) + "1";
|
||||
json::json_pointer jp(std::string("/") + too_large_index);
|
||||
std::string throw_msg = std::string("[json.exception.out_of_range.404] unresolved reference token '") + too_large_index + "'";
|
||||
|
||||
CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());
|
||||
CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
|
||||
}
|
||||
|
||||
if (sizeof(typename json::size_type) < sizeof(unsigned long long))
|
||||
{
|
||||
auto size_type_max_uul = static_cast<unsigned long long>((std::numeric_limits<json::size_type>::max)());
|
||||
auto too_large_index = std::to_string(size_type_max_uul);
|
||||
json::json_pointer jp(std::string("/") + too_large_index);
|
||||
std::string throw_msg = std::string("[json.exception.out_of_range.410] array index ") + too_large_index + " exceeds size_type";
|
||||
|
||||
CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());
|
||||
CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(j.at("/one"_json_pointer) = 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.at("/one"_json_pointer) = 1,
|
||||
|
|
|
|||
|
|
@ -878,7 +878,8 @@ TEST_CASE("modifiers")
|
|||
json j("hello world");
|
||||
json k(42.23);
|
||||
|
||||
std::swap(j, k);
|
||||
using std::swap;
|
||||
swap(j, k);
|
||||
|
||||
CHECK(j == json(42.23));
|
||||
CHECK(k == json("hello world"));
|
||||
|
|
|
|||
|
|
@ -783,6 +783,40 @@ TEST_CASE("MessagePack")
|
|||
CHECK(json::from_msgpack(result) == v);
|
||||
CHECK(json::from_msgpack(result, true, false) == j);
|
||||
}
|
||||
|
||||
SECTION("1.0")
|
||||
{
|
||||
double v = 1.0;
|
||||
json j = v;
|
||||
std::vector<uint8_t> expected =
|
||||
{
|
||||
0xca, 0x3f, 0x80, 0x00, 0x00
|
||||
};
|
||||
const auto result = json::to_msgpack(j);
|
||||
CHECK(result == expected);
|
||||
|
||||
// roundtrip
|
||||
CHECK(json::from_msgpack(result) == j);
|
||||
CHECK(json::from_msgpack(result) == v);
|
||||
CHECK(json::from_msgpack(result, true, false) == j);
|
||||
}
|
||||
|
||||
SECTION("128.128")
|
||||
{
|
||||
double v = 128.1280059814453125;
|
||||
json j = v;
|
||||
std::vector<uint8_t> expected =
|
||||
{
|
||||
0xca, 0x43, 0x00, 0x20, 0xc5
|
||||
};
|
||||
const auto result = json::to_msgpack(j);
|
||||
CHECK(result == expected);
|
||||
|
||||
// roundtrip
|
||||
CHECK(json::from_msgpack(result) == j);
|
||||
CHECK(json::from_msgpack(result) == v);
|
||||
CHECK(json::from_msgpack(result, true, false) == j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1945,6 +1945,15 @@ TEST_CASE("regression tests")
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
SECTION("PR #2181 - regression bug with lvalue")
|
||||
{
|
||||
// see https://github.com/nlohmann/json/pull/2181#issuecomment-653326060
|
||||
json j{{"x", "test"}};
|
||||
std::string defval = "default value";
|
||||
auto val = j.value("x", defval);
|
||||
auto val2 = j.value("y", defval);
|
||||
}
|
||||
}
|
||||
|
||||
#if not defined(JSON_NOEXCEPTION)
|
||||
|
|
|
|||
130
test/src/unit-udt_macro.cpp
Normal file
130
test/src/unit-udt_macro.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.8.0
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace persons
|
||||
{
|
||||
class person_with_private_data
|
||||
{
|
||||
private:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
public:
|
||||
bool operator==(const person_with_private_data& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_with_private_data() = default;
|
||||
person_with_private_data(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
|
||||
};
|
||||
|
||||
class person_without_private_data_1
|
||||
{
|
||||
public:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
bool operator==(const person_without_private_data_1& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_without_private_data_1() = default;
|
||||
person_without_private_data_1(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)
|
||||
};
|
||||
|
||||
class person_without_private_data_2
|
||||
{
|
||||
public:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
bool operator==(const person_without_private_data_2& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_without_private_data_2() = default;
|
||||
person_without_private_data_2(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
|
||||
} // namespace persons
|
||||
|
||||
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE", T,
|
||||
persons::person_with_private_data,
|
||||
persons::person_without_private_data_1,
|
||||
persons::person_without_private_data_2)
|
||||
{
|
||||
SECTION("person")
|
||||
{
|
||||
// serialization
|
||||
T p1("Erik", 1, {{"haircuts", 2}});
|
||||
CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
|
||||
|
||||
// deserialization
|
||||
T p2 = json(p1);
|
||||
CHECK(p2 == p1);
|
||||
|
||||
// roundtrip
|
||||
CHECK(T(json(p1)) == p1);
|
||||
CHECK(json(T(json(p1))) == json(p1));
|
||||
|
||||
// check exception in case of missing field
|
||||
json j = json(p1);
|
||||
j.erase("age");
|
||||
T p3;
|
||||
CHECK_THROWS_WITH_AS(p3 = json(j), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue