Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
855cdcf0
Unverified
Commit
855cdcf0
authored
Mar 12, 2017
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Plain Diff
🔀
merge branch 'develop' into feature/exceptions_3.0.0
parents
28dbe4e6
8feaf8dc
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
229 additions
and
90 deletions
+229
-90
json.hpp
src/json.hpp
+51
-35
json.hpp.re2c
src/json.hpp.re2c
+51
-35
unit-cbor.cpp
test/src/unit-cbor.cpp
+9
-5
unit-class_parser.cpp
test/src/unit-class_parser.cpp
+3
-1
unit-constructor1.cpp
test/src/unit-constructor1.cpp
+9
-3
unit-msgpack.cpp
test/src/unit-msgpack.cpp
+3
-3
unit-regression.cpp
test/src/unit-regression.cpp
+83
-2
unit-testsuites.cpp
test/src/unit-testsuites.cpp
+20
-6
No files found.
src/json.hpp
View file @
855cdcf0
...
...
@@ -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
)
{
...
...
@@ -8021,6 +8006,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
@param[in] v MessagePack serialization
...
...
@@ -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
;
...
...
src/json.hpp.re2c
View file @
855cdcf0
...
...
@@ -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)
{
...
...
@@ -8021,6 +8006,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
@param[in] v MessagePack serialization
...
...
@@ -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;
...
...
test/src/unit-cbor.cpp
View file @
855cdcf0
...
...
@@ -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"
,
...
...
test/src/unit-class_parser.cpp
View file @
855cdcf0
...
...
@@ -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"
)
...
...
test/src/unit-constructor1.cpp
View file @
855cdcf0
...
...
@@ -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"
);
}
}
...
...
test/src/unit-msgpack.cpp
View file @
855cdcf0
...
...
@@ -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"
,
...
...
test/src/unit-regression.cpp
View file @
855cdcf0
...
...
@@ -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
...
...
test/src/unit-testsuites.cpp
View file @
855cdcf0
...
...
@@ -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
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment