mirror of
https://github.com/nlohmann/json.git
synced 2024-12-04 22:49:02 +08:00
🔀 merge branch 'develop' into feature/exceptions_3.0.0
This commit is contained in:
commit
855cdcf05c
86
src/json.hpp
86
src/json.hpp
@ -468,16 +468,8 @@ struct external_constructor<value_t::number_float>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
|
||||
{
|
||||
// replace infinity and NAN by null
|
||||
if (not std::isfinite(val))
|
||||
{
|
||||
j = BasicJsonType{};
|
||||
}
|
||||
else
|
||||
{
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
}
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -904,22 +896,15 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
|
||||
}
|
||||
|
||||
// forward_list doesn't have an insert method
|
||||
template<typename BasicJsonType, typename T, typename Allocator>
|
||||
template<typename BasicJsonType, typename T, typename Allocator,
|
||||
enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
|
||||
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
|
||||
{
|
||||
// do not perform the check when user wants to retrieve jsons
|
||||
// (except when it's null.. ?)
|
||||
if (j.is_null())
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
if (not std::is_same<T, BasicJsonType>::value)
|
||||
{
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
|
||||
{
|
||||
l.push_front(it->template get<T>());
|
||||
@ -951,8 +936,8 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
|
||||
using std::end;
|
||||
|
||||
arr.reserve(j.size());
|
||||
std::transform(
|
||||
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
|
||||
std::transform(j.begin(), j.end(),
|
||||
std::inserter(arr, end(arr)), [](const BasicJsonType & i)
|
||||
{
|
||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||
// method when value_type is BasicJsonType
|
||||
@ -962,22 +947,15 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
|
||||
|
||||
template<typename BasicJsonType, typename CompatibleArrayType,
|
||||
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
|
||||
std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
|
||||
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
|
||||
void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
|
||||
{
|
||||
if (j.is_null())
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
|
||||
// when T == BasicJsonType, do not check if value_t is correct
|
||||
if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
|
||||
{
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
}
|
||||
from_json_array_impl(j, arr, priority_tag<1> {});
|
||||
}
|
||||
|
||||
@ -6916,6 +6894,13 @@ class basic_json
|
||||
*/
|
||||
void dump_float(number_float_t x)
|
||||
{
|
||||
// NaN / inf
|
||||
if (not std::isfinite(x) or std::isnan(x))
|
||||
{
|
||||
o.write("null", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
// special case for 0.0 and -0.0
|
||||
if (x == 0)
|
||||
{
|
||||
@ -8020,6 +8005,35 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief check if the next byte belongs to a string
|
||||
|
||||
While parsing a map, the keys must be strings. This function checks if the
|
||||
current byte is one of the start bytes for a string in MessagePack:
|
||||
|
||||
- 0xa0 - 0xbf: fixstr
|
||||
- 0xd9: str 8
|
||||
- 0xda: str 16
|
||||
- 0xdb: str 32
|
||||
|
||||
@param[in] v MessagePack serialization
|
||||
@param[in] idx byte index in @a v to check for a string
|
||||
|
||||
@throw std::invalid_argument if `v[idx]` does not belong to a string
|
||||
*/
|
||||
static void msgpack_expect_string(const std::vector<uint8_t>& v, size_t idx)
|
||||
{
|
||||
check_length(v.size(), 1, idx);
|
||||
|
||||
const auto byte = v[idx];
|
||||
if ((byte >= 0xa0 and byte <= 0xbf) or (byte >= 0xd9 and byte <= 0xdb))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSON_THROW(std::invalid_argument("error parsing a msgpack string @ " + std::to_string(idx) + ": " + std::to_string(static_cast<int>(v[idx]))));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create a JSON value from a given MessagePack vector
|
||||
|
||||
@ -8054,6 +8068,7 @@ class basic_json
|
||||
const size_t len = v[current_idx] & 0x0f;
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -8233,6 +8248,7 @@ class basic_json
|
||||
idx += 2; // skip 2 size bytes
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -8246,6 +8262,7 @@ class basic_json
|
||||
idx += 4; // skip 4 size bytes
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -11697,11 +11714,10 @@ basic_json_parser_74:
|
||||
result.m_type = value_t::number_float;
|
||||
result.m_value = val;
|
||||
|
||||
// replace infinity and NAN by null
|
||||
// throw in case of infinity or NAN
|
||||
if (not std::isfinite(result.m_value.number_float))
|
||||
{
|
||||
result.m_type = value_t::null;
|
||||
result.m_value = basic_json::json_value();
|
||||
JSON_THROW(std::out_of_range("number overflow: " + get_token_string()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -468,16 +468,8 @@ struct external_constructor<value_t::number_float>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
|
||||
{
|
||||
// replace infinity and NAN by null
|
||||
if (not std::isfinite(val))
|
||||
{
|
||||
j = BasicJsonType{};
|
||||
}
|
||||
else
|
||||
{
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
}
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -904,22 +896,15 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
|
||||
}
|
||||
|
||||
// forward_list doesn't have an insert method
|
||||
template<typename BasicJsonType, typename T, typename Allocator>
|
||||
template<typename BasicJsonType, typename T, typename Allocator,
|
||||
enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
|
||||
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
|
||||
{
|
||||
// do not perform the check when user wants to retrieve jsons
|
||||
// (except when it's null.. ?)
|
||||
if (j.is_null())
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
if (not std::is_same<T, BasicJsonType>::value)
|
||||
{
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
|
||||
{
|
||||
l.push_front(it->template get<T>());
|
||||
@ -951,8 +936,8 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
|
||||
using std::end;
|
||||
|
||||
arr.reserve(j.size());
|
||||
std::transform(
|
||||
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
|
||||
std::transform(j.begin(), j.end(),
|
||||
std::inserter(arr, end(arr)), [](const BasicJsonType & i)
|
||||
{
|
||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||
// method when value_type is BasicJsonType
|
||||
@ -962,22 +947,15 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
|
||||
|
||||
template<typename BasicJsonType, typename CompatibleArrayType,
|
||||
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
|
||||
std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
|
||||
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
|
||||
void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
|
||||
{
|
||||
if (j.is_null())
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
|
||||
// when T == BasicJsonType, do not check if value_t is correct
|
||||
if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
|
||||
{
|
||||
if (not j.is_array())
|
||||
{
|
||||
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name()));
|
||||
}
|
||||
}
|
||||
from_json_array_impl(j, arr, priority_tag<1> {});
|
||||
}
|
||||
|
||||
@ -6916,6 +6894,13 @@ class basic_json
|
||||
*/
|
||||
void dump_float(number_float_t x)
|
||||
{
|
||||
// NaN / inf
|
||||
if (not std::isfinite(x) or std::isnan(x))
|
||||
{
|
||||
o.write("null", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
// special case for 0.0 and -0.0
|
||||
if (x == 0)
|
||||
{
|
||||
@ -8020,6 +8005,35 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief check if the next byte belongs to a string
|
||||
|
||||
While parsing a map, the keys must be strings. This function checks if the
|
||||
current byte is one of the start bytes for a string in MessagePack:
|
||||
|
||||
- 0xa0 - 0xbf: fixstr
|
||||
- 0xd9: str 8
|
||||
- 0xda: str 16
|
||||
- 0xdb: str 32
|
||||
|
||||
@param[in] v MessagePack serialization
|
||||
@param[in] idx byte index in @a v to check for a string
|
||||
|
||||
@throw std::invalid_argument if `v[idx]` does not belong to a string
|
||||
*/
|
||||
static void msgpack_expect_string(const std::vector<uint8_t>& v, size_t idx)
|
||||
{
|
||||
check_length(v.size(), 1, idx);
|
||||
|
||||
const auto byte = v[idx];
|
||||
if ((byte >= 0xa0 and byte <= 0xbf) or (byte >= 0xd9 and byte <= 0xdb))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSON_THROW(std::invalid_argument("error parsing a msgpack string @ " + std::to_string(idx) + ": " + std::to_string(static_cast<int>(v[idx]))));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create a JSON value from a given MessagePack vector
|
||||
|
||||
@ -8054,6 +8068,7 @@ class basic_json
|
||||
const size_t len = v[current_idx] & 0x0f;
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -8233,6 +8248,7 @@ class basic_json
|
||||
idx += 2; // skip 2 size bytes
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -8246,6 +8262,7 @@ class basic_json
|
||||
idx += 4; // skip 4 size bytes
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
msgpack_expect_string(v, idx);
|
||||
std::string key = from_msgpack_internal(v, idx);
|
||||
result[key] = from_msgpack_internal(v, idx);
|
||||
}
|
||||
@ -10730,11 +10747,10 @@ class basic_json
|
||||
result.m_type = value_t::number_float;
|
||||
result.m_value = val;
|
||||
|
||||
// replace infinity and NAN by null
|
||||
// throw in case of infinity or NAN
|
||||
if (not std::isfinite(result.m_value.number_float))
|
||||
{
|
||||
result.m_type = value_t::null;
|
||||
result.m_value = basic_json::json_value();
|
||||
JSON_THROW(std::out_of_range("number overflow: " + get_token_string()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -744,13 +744,17 @@ TEST_CASE("CBOR")
|
||||
SECTION("infinity")
|
||||
{
|
||||
json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));
|
||||
CHECK(j == nullptr);
|
||||
json::number_float_t d = j;
|
||||
CHECK(not std::isfinite(d));
|
||||
CHECK(j.dump() == "null");
|
||||
}
|
||||
|
||||
SECTION("NaN")
|
||||
{
|
||||
json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x01}));
|
||||
CHECK(j == nullptr);
|
||||
json::number_float_t d = j;
|
||||
CHECK(std::isnan(d));
|
||||
CHECK(j.dump() == "null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1430,7 +1434,7 @@ TEST_CASE("CBOR roundtrips", "[hide]")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_after_space.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
|
||||
@ -1442,9 +1446,9 @@ TEST_CASE("CBOR roundtrips", "[hide]")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
|
||||
|
@ -276,7 +276,9 @@ TEST_CASE("parser class")
|
||||
|
||||
SECTION("overflow")
|
||||
{
|
||||
CHECK(json::parser("1.18973e+4932").parse() == json());
|
||||
// overflows during parsing yield an exception
|
||||
CHECK_THROWS_AS(json::parser("1.18973e+4932").parse() == json(), std::out_of_range);
|
||||
CHECK_THROWS_WITH(json::parser("1.18973e+4932").parse() == json(), "number overflow: 1.18973e+4932");
|
||||
}
|
||||
|
||||
SECTION("invalid numbers")
|
||||
|
@ -702,11 +702,17 @@ TEST_CASE("constructors")
|
||||
|
||||
SECTION("infinity")
|
||||
{
|
||||
// infinity is stored as null
|
||||
// should change in the future: https://github.com/nlohmann/json/issues/388
|
||||
// infinity is stored properly, but serialized to null
|
||||
json::number_float_t n(std::numeric_limits<json::number_float_t>::infinity());
|
||||
json j(n);
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(j.type() == json::value_t::number_float);
|
||||
|
||||
// check round trip of infinity
|
||||
json::number_float_t d = j;
|
||||
CHECK(d == n);
|
||||
|
||||
// check that inf is serialized to null
|
||||
CHECK(j.dump() == "null");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1200,7 @@ TEST_CASE("MessagePack roundtrips", "[hide]")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_after_space.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
|
||||
@ -1212,9 +1212,9 @@ TEST_CASE("MessagePack roundtrips", "[hide]")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
|
||||
//"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
|
||||
|
@ -32,6 +32,7 @@ SOFTWARE.
|
||||
using nlohmann::json;
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
TEST_CASE("regression tests")
|
||||
{
|
||||
@ -48,6 +49,7 @@ TEST_CASE("regression tests")
|
||||
|
||||
SECTION("issue #70 - Handle infinity and NaN cases")
|
||||
{
|
||||
/*
|
||||
SECTION("NAN value")
|
||||
{
|
||||
CHECK(json(NAN) == json());
|
||||
@ -59,6 +61,36 @@ TEST_CASE("regression tests")
|
||||
CHECK(json(INFINITY) == json());
|
||||
CHECK(json(json::number_float_t(INFINITY)) == json());
|
||||
}
|
||||
*/
|
||||
|
||||
// With 3.0.0, the semantics of this changed: NAN and infinity are
|
||||
// stored properly inside the JSON value (no exception or conversion
|
||||
// to null), but are serialized as null.
|
||||
SECTION("NAN value")
|
||||
{
|
||||
json j1 = NAN;
|
||||
CHECK(j1.is_number_float());
|
||||
json::number_float_t f1 = j1;
|
||||
CHECK(std::isnan(f1));
|
||||
|
||||
json j2 = json::number_float_t(NAN);
|
||||
CHECK(j2.is_number_float());
|
||||
json::number_float_t f2 = j2;
|
||||
CHECK(std::isnan(f2));
|
||||
}
|
||||
|
||||
SECTION("infinity")
|
||||
{
|
||||
json j1 = INFINITY;
|
||||
CHECK(j1.is_number_float());
|
||||
json::number_float_t f1 = j1;
|
||||
CHECK(not std::isfinite(f1));
|
||||
|
||||
json j2 = json::number_float_t(INFINITY);
|
||||
CHECK(j2.is_number_float());
|
||||
json::number_float_t f2 = j2;
|
||||
CHECK(not std::isfinite(f2));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pull request #71 - handle enum type")
|
||||
@ -558,8 +590,8 @@ TEST_CASE("regression tests")
|
||||
|
||||
SECTION("issue #329 - serialized value not always can be parsed")
|
||||
{
|
||||
json j = json::parse("22e2222");
|
||||
CHECK(j == json());
|
||||
CHECK_THROWS_AS(json::parse("22e2222"), std::out_of_range);
|
||||
CHECK_THROWS_WITH(json::parse("22e2222"), "number overflow: 22e2222");
|
||||
}
|
||||
|
||||
SECTION("issue #366 - json::parse on failed stream gets stuck")
|
||||
@ -834,6 +866,55 @@ TEST_CASE("regression tests")
|
||||
CHECK(s1 == s2);
|
||||
}
|
||||
|
||||
SECTION("issue #473 - inconsistent behavior in conversion to array type")
|
||||
{
|
||||
json j_array = {1, 2, 3, 4};
|
||||
json j_number = 42;
|
||||
json j_null = nullptr;
|
||||
|
||||
SECTION("std::vector")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::vector<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
SECTION("std::list")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::list<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
SECTION("std::forward_list")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::forward_list<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("issue #486 - json::value_t can't be a map's key type in VC++ 2015")
|
||||
{
|
||||
// the code below must compile with MSVC
|
||||
|
@ -460,7 +460,6 @@ TEST_CASE("nst's JSONTestSuite")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_after_space.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
|
||||
@ -472,9 +471,7 @@ TEST_CASE("nst's JSONTestSuite")
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
|
||||
@ -765,9 +762,6 @@ TEST_CASE("nst's JSONTestSuite")
|
||||
{
|
||||
for (auto filename :
|
||||
{
|
||||
// we currently do not limit exponents
|
||||
"test/data/nst_json_testsuite/test_parsing/i_number_neg_int_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/i_number_pos_double_huge_exp.json",
|
||||
// we do not pose a limit on nesting
|
||||
"test/data/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json",
|
||||
// we silently ignore BOMs
|
||||
@ -787,6 +781,26 @@ TEST_CASE("nst's JSONTestSuite")
|
||||
}
|
||||
}
|
||||
|
||||
// numbers that overflow during parsing
|
||||
SECTION("i/y -> n (out of range)")
|
||||
{
|
||||
for (auto filename :
|
||||
{
|
||||
"test/data/nst_json_testsuite/test_parsing/i_number_neg_int_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/i_number_pos_double_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json"
|
||||
}
|
||||
)
|
||||
{
|
||||
CAPTURE(filename);
|
||||
std::ifstream f(filename);
|
||||
json j;
|
||||
CHECK_THROWS_AS(j << f, std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("i -> n")
|
||||
{
|
||||
for (auto filename :
|
||||
|
Loading…
Reference in New Issue
Block a user