🔨 changed call from "not good()" to "fail()" #493

Also merged develop into this feature branch.
This commit is contained in:
Niels Lohmann 2017-03-14 21:24:53 +01:00
commit 63c2c62f19
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
67 changed files with 3837 additions and 2123 deletions

View file

@ -78,13 +78,13 @@ matrix:
env: env:
- COMPILER=g++-4.9 - COMPILER=g++-4.9
- SPECIAL=no_exceptions - SPECIAL=no_exceptions
- TEST_PATTERN=-e \"*\"
addons: addons:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: [g++-4.9, cppcheck] packages: [g++-4.9, cppcheck]
before_script: after_success:
- CPPFLAGS="-DJSON_NOEXCEPTION" make - make clean
- CPPFLAGS="-DJSON_NOEXCEPTION" make check TEST_PATTERN="-e \"*\""
# Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/) # Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/)

View file

@ -49,6 +49,7 @@ doctest:
# -Wno-documentation-unknown-command: code uses user-defined commands like @complexity # -Wno-documentation-unknown-command: code uses user-defined commands like @complexity
# -Wno-exit-time-destructors: warning in Catch code # -Wno-exit-time-destructors: warning in Catch code
# -Wno-keyword-macro: unit-tests use "#define private public" # -Wno-keyword-macro: unit-tests use "#define private public"
# -Wno-weak-vtables: exception class is defined inline, but has virtual method
# -Wno-range-loop-analysis: iterator_wrapper tests tests "for(const auto i...)" # -Wno-range-loop-analysis: iterator_wrapper tests tests "for(const auto i...)"
pedantic: pedantic:
$(MAKE) json_unit CXXFLAGS="\ $(MAKE) json_unit CXXFLAGS="\
@ -58,6 +59,7 @@ pedantic:
-Wno-documentation-unknown-command \ -Wno-documentation-unknown-command \
-Wno-exit-time-destructors \ -Wno-exit-time-destructors \
-Wno-keyword-macro \ -Wno-keyword-macro \
-Wno-weak-vtables \
-Wno-range-loop-analysis" -Wno-range-loop-analysis"

View file

@ -58,6 +58,9 @@ doxygen: create_output create_links
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType&#160;JSONSerializer&#160;&gt;@@g' html/*.html $(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType&#160;JSONSerializer&#160;&gt;@@g' html/*.html
$(SED) -i 's@template&lt;template&lt; typename U, typename V, typename... Args &gt; class ObjectType = std::map, template&lt; typename U, typename... Args &gt; class ArrayType = std::vector, class StringType = std::string, class BooleanType = bool, class NumberIntegerType = std::int64_t, class NumberUnsignedType = std::uint64_t, class NumberFloatType = double, template&lt; typename U &gt; class AllocatorType = std::allocator, template&lt; typename T, typename SFINAE=void &gt; class JSONSerializer = adl_serializer&gt;@@g' html/*.html
$(SED) -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer &gt;@@g' html/*.html
$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType,&#160;JSONSerializer&#160;&gt;@@g' html/*.html
upload: clean doxygen check_output upload: clean doxygen check_output
cd html ; ../scripts/git-update-ghpages nlohmann/json cd html ; ../scripts/git-update-ghpages nlohmann/json

View file

@ -21,13 +21,27 @@ int main()
// output changed array // output changed array
std::cout << object << '\n'; std::cout << object << '\n';
// try to write at a nonexisting key
// exception type_error.304
try try
{ {
// use at() on a non-object type
json str = "I am a string";
str.at("the good") = "Another string";
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try
{
// try to write at a nonexisting key
object.at("the fast") = "il rapido"; object.at("the fast") = "il rapido";
} }
catch (std::out_of_range& e) catch (json::out_of_range& e)
{ {
std::cout << "out of range: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/tb5CaFfsMWpAvi7m"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/8ldtT0NOhidn0fOA"><b>online</b></a>

View file

@ -1,3 +1,4 @@
"il brutto" "il brutto"
{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} {"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"}
out of range: key 'the fast' not found [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.403] key 'the fast' not found

View file

@ -0,0 +1,3 @@
"il brutto"
{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"}
[json.exception.out_of_range.403] key 'the fast' not found

View file

@ -15,12 +15,26 @@ int main()
// output element with key "the ugly" // output element with key "the ugly"
std::cout << object.at("the ugly") << '\n'; std::cout << object.at("the ugly") << '\n';
// try to read from a nonexisting key
// exception type_error.304
try try
{ {
// use at() on a non-object type
const json str = "I am a string";
std::cout << str.at("the good") << '\n';
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try
{
// try to read from a nonexisting key
std::cout << object.at("the fast") << '\n'; std::cout << object.at("the fast") << '\n';
} }
catch (std::out_of_range) catch (json::out_of_range)
{ {
std::cout << "out of range" << '\n'; std::cout << "out of range" << '\n';
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/NFG86H5khRUePc1s"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/nfmFWMaJJHFJ7eVK"><b>online</b></a>

View file

@ -1,2 +1,3 @@
"il brutto" "il brutto"
[json.exception.type_error.304] cannot use at() with string
out of range out of range

View file

@ -16,13 +16,27 @@ int main()
// output changed array // output changed array
std::cout << array << '\n'; std::cout << array << '\n';
// try to write beyond the array limit
// exception type_error.304
try try
{ {
// use at() on a non-array type
json str = "I am a string";
str.at(0) = "Another string";
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try
{
// try to write beyond the array limit
array.at(5) = "sixth"; array.at(5) = "sixth";
} }
catch (std::out_of_range& e) catch (json::out_of_range& e)
{ {
std::cout << "out of range: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/R7z2SB2rMdFQ9XtR"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/8UnQY256zGX2Lx6d"><b>online</b></a>

View file

@ -1,3 +1,4 @@
"third" "third"
["first","second","third","fourth"] ["first","second","third","fourth"]
out of range: array index 5 is out of range [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.401] array index 5 is out of range

View file

@ -5,18 +5,32 @@ using json = nlohmann::json;
int main() int main()
{ {
// create JSON array // create JSON array
json array = {"first", "2nd", "third", "fourth"}; const json array = {"first", "2nd", "third", "fourth"};
// output element at index 2 (third element) // output element at index 2 (third element)
std::cout << array.at(2) << '\n'; std::cout << array.at(2) << '\n';
// try to read beyond the array limit
// exception type_error.304
try try
{ {
// use at() on a non-array type
const json str = "I am a string";
std::cout << str.at(0) << '\n';
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try
{
// try to read beyond the array limit
std::cout << array.at(5) << '\n'; std::cout << array.at(5) << '\n';
} }
catch (std::out_of_range) catch (json::out_of_range& e)
{ {
std::cout << "out of range" << '\n'; std::cout << e.what() << '\n';
} }
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/L1bMeiN6nYm7JrvA"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/U1fv6LY7xZOAuSBs"><b>online</b></a>

View file

@ -1,2 +1,3 @@
"third" "third"
out of range [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.401] array index 5 is out of range

View file

@ -32,4 +32,60 @@ int main()
j.at("/array/1"_json_pointer) = 21; j.at("/array/1"_json_pointer) = 21;
// output the changed array // output the changed array
std::cout << j["array"] << '\n'; std::cout << j["array"] << '\n';
// out_of_range.106
try
{
// try to use an array index with leading '0'
json::reference ref = j.at("/array/01"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.109
try
{
// try to use an array index that is not a number
json::reference ref = j.at("/array/one"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.401
try
{
// try to use a an invalid array index
json::reference ref = j.at("/array/4"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.402
try
{
// try to use the array index '-'
json::reference ref = j.at("/array/-"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.404
try
{
// try to use a JSON pointer that cannot be resolved
json::reference ref = j.at("/number/foo"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/NDSjglHZIjIZ0Uxg"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Fy2xBfZMols2DUQC"><b>online</b></a>

View file

@ -4,3 +4,8 @@
2 2
"bar" "bar"
[1,21] [1,21]
[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'
[json.exception.parse_error.109] parse error: array index 'one' is not a number
[json.exception.out_of_range.401] array index 4 is out of range
[json.exception.out_of_range.402] array index '-' (2) is out of range
[json.exception.out_of_range.404] unresolved reference token 'foo'

View file

@ -5,7 +5,7 @@ using json = nlohmann::json;
int main() int main()
{ {
// create a JSON value // create a JSON value
json j = const json j =
{ {
{"number", 1}, {"string", "foo"}, {"array", {1, 2}} {"number", 1}, {"string", "foo"}, {"array", {1, 2}}
}; };
@ -20,4 +20,48 @@ int main()
std::cout << j.at("/array"_json_pointer) << '\n'; std::cout << j.at("/array"_json_pointer) << '\n';
// output element with JSON pointer "/array/1" // output element with JSON pointer "/array/1"
std::cout << j.at("/array/1"_json_pointer) << '\n'; std::cout << j.at("/array/1"_json_pointer) << '\n';
// out_of_range.109
try
{
// try to use an array index that is not a number
json::const_reference ref = j.at("/array/one"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.401
try
{
// try to use a an invalid array index
json::const_reference ref = j.at("/array/4"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.402
try
{
// try to use the array index '-'
json::const_reference ref = j.at("/array/-"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.404
try
{
// try to use a JSON pointer that cannot be resolved
json::const_reference ref = j.at("/number/foo"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/OuLYiMJ3pgyOHupb"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/WxhV3mL9YX8FJonk"><b>online</b></a>

View file

@ -2,3 +2,7 @@
"foo" "foo"
[1,2] [1,2]
2 2
[json.exception.parse_error.109] parse error: array index 'one' is not a number
[json.exception.out_of_range.401] array index 4 is out of range
[json.exception.out_of_range.402] array index '-' (2) is out of range
[json.exception.out_of_range.404] unresolved reference token 'foo'

View file

@ -5,7 +5,6 @@ using json = nlohmann::json;
int main() int main()
{ {
// create JSON values // create JSON values
json j_null;
json j_boolean = true; json j_boolean = true;
json j_number_integer = 17; json j_number_integer = 17;
json j_number_float = 23.42; json j_number_float = 23.42;
@ -16,7 +15,6 @@ int main()
json j_string = "Hello, world"; json j_string = "Hello, world";
// call back() // call back()
//std::cout << j_null.back() << '\n'; // would throw
std::cout << j_boolean.back() << '\n'; std::cout << j_boolean.back() << '\n';
std::cout << j_number_integer.back() << '\n'; std::cout << j_number_integer.back() << '\n';
std::cout << j_number_float.back() << '\n'; std::cout << j_number_float.back() << '\n';
@ -25,4 +23,15 @@ int main()
std::cout << j_array.back() << '\n'; std::cout << j_array.back() << '\n';
//std::cout << j_array_empty.back() << '\n'; // undefined behavior //std::cout << j_array_empty.back() << '\n'; // undefined behavior
std::cout << j_string.back() << '\n'; std::cout << j_string.back() << '\n';
// back() called on a null value
try
{
json j_null;
j_null.back();
}
catch (json::invalid_iterator& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/nPVnBcHf8nrNpGOJ"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/CAv4NNr4D1FJhhUv"><b>online</b></a>

View file

@ -4,3 +4,4 @@ true
2 2
16 16
"Hello, world" "Hello, world"
[json.exception.invalid_iterator.214] cannot get value

View file

@ -18,4 +18,14 @@ int main()
std::cout << j_array_range << '\n'; std::cout << j_array_range << '\n';
std::cout << j_number_range << '\n'; std::cout << j_number_range << '\n';
std::cout << j_object_range << '\n'; std::cout << j_object_range << '\n';
// example for an exception
try
{
json j_invalid(j_number.begin() + 1, j_number.end());
}
catch (json::invalid_iterator& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/nKF1QcieoCHm6Lez"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/oUU2X0pbZq7gawRB"><b>online</b></a>

View file

@ -1,3 +1,4 @@
["bravo","charly"] ["bravo","charly"]
42 42
{"one":"eins"} {"one":"eins"}
[json.exception.invalid_iterator.204] iterators out of range

View file

@ -19,7 +19,7 @@ int main()
{ {
auto r3 = value.get_ref<json::number_float_t&>(); auto r3 = value.get_ref<json::number_float_t&>();
} }
catch (std::domain_error& ex) catch (json::type_error& ex)
{ {
std::cout << ex.what() << '\n'; std::cout << ex.what() << '\n';
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/WiO1oBWDvIs82OX1"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/lsl8Ex3d3SOYnKHu"><b>online</b></a>

View file

@ -1,2 +1,2 @@
17 17 17 17
incompatible ReferenceType for get_ref, actual type is number [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number

View file

@ -0,0 +1,2 @@
17 17
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number

View file

@ -19,9 +19,9 @@ int main()
{ {
json::json_pointer p9("foo"); json::json_pointer p9("foo");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
// error: JSON pointer uses escape symbol ~ not followed by 0 or 1 // error: JSON pointer uses escape symbol ~ not followed by 0 or 1
@ -29,9 +29,9 @@ int main()
{ {
json::json_pointer p10("/foo/~"); json::json_pointer p10("/foo/~");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
// error: JSON pointer uses escape symbol ~ not followed by 0 or 1 // error: JSON pointer uses escape symbol ~ not followed by 0 or 1
@ -39,8 +39,8 @@ int main()
{ {
json::json_pointer p11("/foo/~3"); json::json_pointer p11("/foo/~3");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/WM2WWKnXdmdw17Wu"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Wlvqfd3JpEXTv2iH"><b>online</b></a>

View file

@ -1,3 +1,3 @@
domain_error: JSON pointer must be empty or begin with '/' [json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'
domain_error: escape error: '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
domain_error: escape error: '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'

View file

@ -0,0 +1,3 @@
[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'

View file

@ -8,10 +8,20 @@ int main()
json j_no_init_list = json::object(); json j_no_init_list = json::object();
json j_empty_init_list = json::object({}); json j_empty_init_list = json::object({});
json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} }); json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} });
//json j_invalid_list = json::object({ "one", 1 }); // would throw
// serialize the JSON objects // serialize the JSON objects
std::cout << j_no_init_list << '\n'; std::cout << j_no_init_list << '\n';
std::cout << j_empty_init_list << '\n'; std::cout << j_empty_init_list << '\n';
std::cout << j_list_of_pairs << '\n'; std::cout << j_list_of_pairs << '\n';
// example for an exception
try
{
// can only create an object from a list of pairs
json j_invalid_object = json::object({{ "one", 1, 2 }});
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/hhxRaUctq3FA54SW"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Ub9U5AMbng3oZiao"><b>online</b></a>

View file

@ -1,3 +1,4 @@
{} {}
{} {}
{"one":1,"two":2} {"one":1,"two":2}
[json.exception.type_error.301] cannot create object from initializer list

View file

@ -46,4 +46,14 @@ int main()
{ {
std::cout << i.first << ": " << i.second << '\n'; std::cout << i.first << ": " << i.second << '\n';
} }
// example for an exception
try
{
bool v1 = json_types["string"];
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
} }

View file

@ -1 +1 @@
<a target="_blank" href="http://melpon.org/wandbox/permlink/rUGX6AaVuZfwiiYI"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/drFSKFXJd8IMzMK3"><b>online</b></a>

View file

@ -9,3 +9,4 @@ number: {"floating-point":17.23,"integer":42}
null: null null: null
boolean: true boolean: true
array: [1,2,3,4,5] array: [1,2,3,4,5]
[json.exception.type_error.302] type must be boolean, but is string

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -41,26 +41,22 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// parse serialization // parse serialization
json j2 = json::from_cbor(vec2); json j2 = json::from_cbor(vec2);
// deserializations must match // serializations must match
assert(j1 == j2); assert(json::to_cbor(j2) == vec2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a CBOR serialization must not fail // parsing a CBOR serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
catch (const std::out_of_range&) catch (const json::type_error&)
{ {
// parse errors are ok, because input may be random bytes // type errors can occur during parsing, too
}
catch (const std::domain_error&)
{
// parse errors are ok, because input may be random bytes
} }
// return 0 - non-zero return values are reserved for future use // return 0 - non-zero return values are reserved for future use

View file

@ -49,13 +49,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// serializations must match // serializations must match
assert(s1 == s2); assert(s1 == s2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a JSON serialization must not fail // parsing a JSON serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }

View file

@ -44,23 +44,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// deserializations must match // deserializations must match
assert(j1 == j2); assert(j1 == j2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a MessagePack serialization must not fail // parsing a MessagePack serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
catch (const std::out_of_range&) catch (const json::type_error&)
{ {
// parse errors are ok, because input may be random bytes // type errors can occur during parsing, too
}
catch (const std::domain_error&)
{
// parse errors are ok, because input may be random bytes
} }
// return 0 - non-zero return values are reserved for future use // return 0 - non-zero return values are reserved for future use

View file

@ -240,8 +240,9 @@ TEST_CASE("algorithms")
SECTION("sorting an object") SECTION("sorting an object")
{ {
json j({{"one", 1}, {"two", 2}}); json j({{"one", 1}, {"two", 2}});
CHECK_THROWS_AS(std::sort(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(std::sort(j.begin(), j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(std::sort(j.begin(), j.end()), "cannot use offsets with object iterators"); CHECK_THROWS_WITH(std::sort(j.begin(), j.end()),
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
} }

View file

@ -744,13 +744,17 @@ TEST_CASE("CBOR")
SECTION("infinity") SECTION("infinity")
{ {
json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00})); 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") SECTION("NaN")
{ {
json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x01})); 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");
} }
} }
} }
@ -1145,21 +1149,115 @@ TEST_CASE("CBOR")
{ {
SECTION("too short byte vector") SECTION("too short byte vector")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x18})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x18})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x19})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x19})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
}
SECTION("unsupported bytes")
{
SECTION("concrete examples")
{
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1c})),
"[json.exception.parse_error.112] parse error at 1: error reading CBOR; last byte: 0x1c");
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf8})),
"[json.exception.parse_error.112] parse error at 1: error reading CBOR; last byte: 0xf8");
}
SECTION("all unsupported bytes")
{
for (auto byte :
{
// ?
0x1c, 0x1d, 0x1e, 0x1f,
// ?
0x3c, 0x3d, 0x3e, 0x3f,
// byte strings
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
// byte strings
0x58, 0x59, 0x5a, 0x5b,
// ?
0x5c, 0x5d, 0x5e,
// byte string
0x5f,
// ?
0x7c, 0x7d, 0x7e,
// ?
0x9c, 0x9d, 0x9e,
// ?
0xbc, 0xbd, 0xbe,
// date/time
0xc0, 0xc1,
// bignum
0xc2, 0xc3,
// fraction
0xc4,
// bigfloat
0xc5,
// tagged item
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
// expected conversion
0xd5, 0xd6, 0xd7,
// more tagged items
0xd8, 0xd9, 0xda, 0xdb,
// ?
0xdc, 0xdd, 0xde, 0xdf,
// (simple value)
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
// undefined
0xf7,
// simple value
0xf8
})
{
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error);
}
}
} }
} }
} }
@ -1247,21 +1345,13 @@ TEST_CASE("CBOR regressions", "[!throws]")
// deserializations must match // deserializations must match
CHECK(j1 == j2); CHECK(j1 == j2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a CBOR serialization must not fail // parsing a CBOR serialization must not fail
CHECK(false); CHECK(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{
// parse errors are ok, because input may be random bytes
}
catch (const std::out_of_range&)
{
// parse errors are ok, because input may be random bytes
}
catch (const std::domain_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
@ -1271,7 +1361,7 @@ TEST_CASE("CBOR regressions", "[!throws]")
SECTION("improve code coverage") SECTION("improve code coverage")
{ {
// exotic edge case // exotic edge case
CHECK_THROWS_AS(json::check_length(0xffffffffffffffffull, 0xfffffffffffffff0ull, 0xff), std::out_of_range); CHECK_THROWS_AS(json::check_length(0xffffffffffffffffull, 0xfffffffffffffff0ull, 0xff), json::parse_error);
} }
} }
@ -1344,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_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_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_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_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_minus_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json", "test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
@ -1356,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_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_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_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_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_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_int.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json", "test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",

View file

@ -147,8 +147,8 @@ TEST_CASE("const_iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
@ -157,8 +157,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK(*it == json(17)); CHECK(*it == json(17));
it = j.cend(); it = j.cend();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
@ -182,8 +182,8 @@ TEST_CASE("const_iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
@ -192,8 +192,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK(it->type_name() == "number"); CHECK(it->type_name() == "number");
it = j.cend(); it = j.cend();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")

View file

@ -131,8 +131,8 @@ TEST_CASE("iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
@ -141,8 +141,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK(*it == json(17)); CHECK(*it == json(17));
it = j.end(); it = j.end();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
@ -166,8 +166,8 @@ TEST_CASE("iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
@ -176,8 +176,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK(it->type_name() == "number"); CHECK(it->type_name() == "number");
it = j.end(); it = j.end();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")

View file

@ -190,8 +190,10 @@ TEST_CASE("lexer class")
SECTION("to_unicode") SECTION("to_unicode")
{ {
CHECK(json::lexer::to_unicode(0x1F4A9) == "💩"); // lexer to call to_unicode on
CHECK_THROWS_AS(json::lexer::to_unicode(0x200000), std::out_of_range); json::lexer dummy_lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(""), 0);
CHECK_THROWS_WITH(json::lexer::to_unicode(0x200000), "code points above 0x10FFFF are invalid"); CHECK(dummy_lexer.to_unicode(0x1F4A9) == "💩");
CHECK_THROWS_AS(dummy_lexer.to_unicode(0x200000), json::parse_error);
CHECK_THROWS_WITH(dummy_lexer.to_unicode(0x200000), "[json.exception.parse_error.103] parse error: code points above 0x10FFFF are invalid");
} }
} }

View file

@ -89,52 +89,56 @@ TEST_CASE("parser class")
SECTION("errors") SECTION("errors")
{ {
// error: tab in string // error: tab in string
CHECK_THROWS_AS(json::parser("\"\t\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\t\"").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("\"\t\"").parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser("\"\t\"").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
// error: newline in string // error: newline in string
CHECK_THROWS_AS(json::parser("\"\n\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\n\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\r\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\r\"").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("\"\n\"").parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser("\"\n\"").parse(),
CHECK_THROWS_WITH(json::parser("\"\r\"").parse(), "parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\r\"").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
// error: backspace in string // error: backspace in string
CHECK_THROWS_AS(json::parser("\"\b\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\b\"").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("\"\b\"").parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser("\"\b\"").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
// improve code coverage // improve code coverage
CHECK_THROWS_AS(json::parser("\uFF01").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\uFF01").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("[-4:1,]").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[-4:1,]").parse(), json::parse_error);
// unescaped control characters // unescaped control characters
CHECK_THROWS_AS(json::parser("\"\x00\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x00\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x01\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x01\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x02\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x02\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x03\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x03\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x04\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x04\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x05\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x05\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x06\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x06\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x07\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x07\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x08\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x08\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x09\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x09\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0a\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0a\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0b\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0b\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0c\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0c\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0d\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0d\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0e\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0e\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x0f\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x0f\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x10\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x10\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x11\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x11\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x12\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x12\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x13\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x13\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x14\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x14\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x15\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x15\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x16\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x16\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x17\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x17\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x18\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x18\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x19\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x19\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1a\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1a\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1b\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1b\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1c\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1c\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1d\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1d\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1e\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1e\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\x1f\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\x1f\"").parse(), json::parse_error);
} }
SECTION("escaped") SECTION("escaped")
@ -272,65 +276,69 @@ TEST_CASE("parser class")
SECTION("overflow") 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(), json::out_of_range);
CHECK_THROWS_WITH(json::parser("1.18973e+4932").parse() == json(),
"[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'");
} }
SECTION("invalid numbers") SECTION("invalid numbers")
{ {
CHECK_THROWS_AS(json::parser("01").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("01").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("--1").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("--1").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1E").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1E-").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E-").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1.E1").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1.E1").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-1E").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-1E").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0E#").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0E#").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0E-#").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0E-#").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0#").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0#").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0.0:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0.0:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0.0Z").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0.0Z").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0E123:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0E123:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0e0-:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0e0-:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0e-:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0e-:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0f").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0f").parse(), json::parse_error);
// numbers must not begin with "+" // numbers must not begin with "+"
CHECK_THROWS_AS(json::parser("+1").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("+1").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("+0").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("+0").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("01").parse(), CHECK_THROWS_WITH(json::parser("01").parse(),
"parse error - unexpected '01'"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected '01'");
CHECK_THROWS_WITH(json::parser("-01").parse(), CHECK_THROWS_WITH(json::parser("-01").parse(),
"parse error - unexpected '-01'"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected '-01'");
CHECK_THROWS_WITH(json::parser("--1").parse(), "parse error - unexpected '-'"); CHECK_THROWS_WITH(json::parser("--1").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '-'");
CHECK_THROWS_WITH(json::parser("1.").parse(), CHECK_THROWS_WITH(json::parser("1.").parse(),
"parse error - unexpected '.'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected '.'; expected end of input");
CHECK_THROWS_WITH(json::parser("1E").parse(), CHECK_THROWS_WITH(json::parser("1E").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("1E-").parse(), CHECK_THROWS_WITH(json::parser("1E-").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("1.E1").parse(), CHECK_THROWS_WITH(json::parser("1.E1").parse(),
"parse error - unexpected '.'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected '.'; expected end of input");
CHECK_THROWS_WITH(json::parser("-1E").parse(), CHECK_THROWS_WITH(json::parser("-1E").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0E#").parse(), CHECK_THROWS_WITH(json::parser("-0E#").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0E-#").parse(), CHECK_THROWS_WITH(json::parser("-0E-#").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0#").parse(), CHECK_THROWS_WITH(json::parser("-0#").parse(),
"parse error - unexpected '#'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected '#'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0.0:").parse(), CHECK_THROWS_WITH(json::parser("-0.0:").parse(),
"parse error - unexpected ':'; expected end of input"); "[json.exception.parse_error.101] parse error at 5: parse error - unexpected ':'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0.0Z").parse(), CHECK_THROWS_WITH(json::parser("-0.0Z").parse(),
"parse error - unexpected 'Z'; expected end of input"); "[json.exception.parse_error.101] parse error at 5: parse error - unexpected 'Z'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0E123:").parse(), CHECK_THROWS_WITH(json::parser("-0E123:").parse(),
"parse error - unexpected ':'; expected end of input"); "[json.exception.parse_error.101] parse error at 7: parse error - unexpected ':'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0e0-:").parse(), CHECK_THROWS_WITH(json::parser("-0e0-:").parse(),
"parse error - unexpected '-'; expected end of input"); "[json.exception.parse_error.101] parse error at 5: parse error - unexpected '-'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0e-:").parse(), CHECK_THROWS_WITH(json::parser("-0e-:").parse(),
"parse error - unexpected 'e'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected 'e'; expected end of input");
CHECK_THROWS_WITH(json::parser("-0f").parse(), CHECK_THROWS_WITH(json::parser("-0f").parse(),
"parse error - unexpected 'f'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected 'f'; expected end of input");
} }
} }
} }
@ -338,147 +346,150 @@ TEST_CASE("parser class")
SECTION("parse errors") SECTION("parse errors")
{ {
// unexpected end of number // unexpected end of number
CHECK_THROWS_AS(json::parser("0.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("0.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("--").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("--").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-0.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("-:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("0.:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("0.:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("e.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("e.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1e.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1e.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1e/").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1e/").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1e:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1e:").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1E.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E.").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1E/").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E/").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("1E:").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E:").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("0.").parse(), CHECK_THROWS_WITH(json::parser("0.").parse(),
"parse error - unexpected '.'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected '.'; expected end of input");
CHECK_THROWS_WITH(json::parser("-").parse(), "parse error - unexpected '-'"); CHECK_THROWS_WITH(json::parser("-").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '-'");
CHECK_THROWS_WITH(json::parser("--").parse(), CHECK_THROWS_WITH(json::parser("--").parse(),
"parse error - unexpected '-'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '-'");
CHECK_THROWS_WITH(json::parser("-0.").parse(), CHECK_THROWS_WITH(json::parser("-0.").parse(),
"parse error - unexpected '.'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected '.'; expected end of input");
CHECK_THROWS_WITH(json::parser("-.").parse(), CHECK_THROWS_WITH(json::parser("-.").parse(),
"parse error - unexpected '-'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '-'");
CHECK_THROWS_WITH(json::parser("-:").parse(), CHECK_THROWS_WITH(json::parser("-:").parse(),
"parse error - unexpected '-'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '-'");
CHECK_THROWS_WITH(json::parser("0.:").parse(), CHECK_THROWS_WITH(json::parser("0.:").parse(),
"parse error - unexpected '.'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected '.'; expected end of input");
CHECK_THROWS_WITH(json::parser("e.").parse(), CHECK_THROWS_WITH(json::parser("e.").parse(),
"parse error - unexpected 'e'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'e'");
CHECK_THROWS_WITH(json::parser("1e.").parse(), CHECK_THROWS_WITH(json::parser("1e.").parse(),
"parse error - unexpected 'e'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'e'; expected end of input");
CHECK_THROWS_WITH(json::parser("1e/").parse(), CHECK_THROWS_WITH(json::parser("1e/").parse(),
"parse error - unexpected 'e'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'e'; expected end of input");
CHECK_THROWS_WITH(json::parser("1e:").parse(), CHECK_THROWS_WITH(json::parser("1e:").parse(),
"parse error - unexpected 'e'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'e'; expected end of input");
CHECK_THROWS_WITH(json::parser("1E.").parse(), CHECK_THROWS_WITH(json::parser("1E.").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("1E/").parse(), CHECK_THROWS_WITH(json::parser("1E/").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'E'; expected end of input");
CHECK_THROWS_WITH(json::parser("1E:").parse(), CHECK_THROWS_WITH(json::parser("1E:").parse(),
"parse error - unexpected 'E'; expected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected 'E'; expected end of input");
// unexpected end of null // unexpected end of null
CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("n").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("nu").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("nu").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("nul").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("nul").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("n").parse(), "parse error - unexpected 'n'"); CHECK_THROWS_WITH(json::parser("n").parse(), "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'n'");
CHECK_THROWS_WITH(json::parser("nu").parse(), CHECK_THROWS_WITH(json::parser("nu").parse(),
"parse error - unexpected 'n'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'n'");
CHECK_THROWS_WITH(json::parser("nul").parse(), CHECK_THROWS_WITH(json::parser("nul").parse(),
"parse error - unexpected 'n'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'n'");
// unexpected end of true // unexpected end of true
CHECK_THROWS_AS(json::parser("t").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("t").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("tr").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("tr").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("tru").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("tru").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("t").parse(), "parse error - unexpected 't'"); CHECK_THROWS_WITH(json::parser("t").parse(), "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 't'");
CHECK_THROWS_WITH(json::parser("tr").parse(), CHECK_THROWS_WITH(json::parser("tr").parse(),
"parse error - unexpected 't'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 't'");
CHECK_THROWS_WITH(json::parser("tru").parse(), CHECK_THROWS_WITH(json::parser("tru").parse(),
"parse error - unexpected 't'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 't'");
// unexpected end of false // unexpected end of false
CHECK_THROWS_AS(json::parser("f").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("f").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("fa").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("fa").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("fal").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("fal").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("fals").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("fals").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("f").parse(), "parse error - unexpected 'f'"); CHECK_THROWS_WITH(json::parser("f").parse(), "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'f'");
CHECK_THROWS_WITH(json::parser("fa").parse(), CHECK_THROWS_WITH(json::parser("fa").parse(),
"parse error - unexpected 'f'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'f'");
CHECK_THROWS_WITH(json::parser("fal").parse(), CHECK_THROWS_WITH(json::parser("fal").parse(),
"parse error - unexpected 'f'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'f'");
CHECK_THROWS_WITH(json::parser("fals").parse(), CHECK_THROWS_WITH(json::parser("fals").parse(),
"parse error - unexpected 'f'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected 'f'");
// missing/unexpected end of array // missing/unexpected end of array
CHECK_THROWS_AS(json::parser("[").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("[1").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[1").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("[1,").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[1,").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("[1,]").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[1,]").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("]").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("]").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("[").parse(), CHECK_THROWS_WITH(json::parser("[").parse(),
"parse error - unexpected end of input"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected end of input");
CHECK_THROWS_WITH(json::parser("[1").parse(), CHECK_THROWS_WITH(json::parser("[1").parse(),
"parse error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at 3: parse error - unexpected end of input; expected ']'");
CHECK_THROWS_WITH(json::parser("[1,").parse(), CHECK_THROWS_WITH(json::parser("[1,").parse(),
"parse error - unexpected end of input"); "[json.exception.parse_error.101] parse error at 4: parse error - unexpected end of input");
CHECK_THROWS_WITH(json::parser("[1,]").parse(), CHECK_THROWS_WITH(json::parser("[1,]").parse(),
"parse error - unexpected ']'"); "[json.exception.parse_error.101] parse error at 4: parse error - unexpected ']'");
CHECK_THROWS_WITH(json::parser("]").parse(), "parse error - unexpected ']'"); CHECK_THROWS_WITH(json::parser("]").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected ']'");
// missing/unexpected end of object // missing/unexpected end of object
CHECK_THROWS_AS(json::parser("{").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("{\"foo\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("{\"foo\":").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\":").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("{\"foo\":}").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\":}").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("{\"foo\":1,}").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\":1,}").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("}").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("}").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("{").parse(), CHECK_THROWS_WITH(json::parser("{").parse(),
"parse error - unexpected end of input; expected string literal"); "[json.exception.parse_error.101] parse error at 2: parse error - unexpected end of input; expected string literal");
CHECK_THROWS_WITH(json::parser("{\"foo\"").parse(), CHECK_THROWS_WITH(json::parser("{\"foo\"").parse(),
"parse error - unexpected end of input; expected ':'"); "[json.exception.parse_error.101] parse error at 7: parse error - unexpected end of input; expected ':'");
CHECK_THROWS_WITH(json::parser("{\"foo\":").parse(), CHECK_THROWS_WITH(json::parser("{\"foo\":").parse(),
"parse error - unexpected end of input"); "[json.exception.parse_error.101] parse error at 8: parse error - unexpected end of input");
CHECK_THROWS_WITH(json::parser("{\"foo\":}").parse(), CHECK_THROWS_WITH(json::parser("{\"foo\":}").parse(),
"parse error - unexpected '}'"); "[json.exception.parse_error.101] parse error at 8: parse error - unexpected '}'");
CHECK_THROWS_WITH(json::parser("{\"foo\":1,}").parse(), CHECK_THROWS_WITH(json::parser("{\"foo\":1,}").parse(),
"parse error - unexpected '}'; expected string literal"); "[json.exception.parse_error.101] parse error at 10: parse error - unexpected '}'; expected string literal");
CHECK_THROWS_WITH(json::parser("}").parse(), "parse error - unexpected '}'"); CHECK_THROWS_WITH(json::parser("}").parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '}'");
// missing/unexpected end of string // missing/unexpected end of string
CHECK_THROWS_AS(json::parser("\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u0\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u0\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u01\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u01\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u012\"").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u012\"").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u0").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u0").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u01").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u01").parse(), json::parse_error);
CHECK_THROWS_AS(json::parser("\"\\u012").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("\"\\u012").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("\"").parse(), CHECK_THROWS_WITH(json::parser("\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\\"").parse(), CHECK_THROWS_WITH(json::parser("\"\\\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u\"").parse(), CHECK_THROWS_WITH(json::parser("\"\\u\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u0\"").parse(), CHECK_THROWS_WITH(json::parser("\"\\u0\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u01\"").parse(), CHECK_THROWS_WITH(json::parser("\"\\u01\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u012\"").parse(), CHECK_THROWS_WITH(json::parser("\"\\u012\"").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u").parse(), CHECK_THROWS_WITH(json::parser("\"\\u").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u0").parse(), CHECK_THROWS_WITH(json::parser("\"\\u0").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u01").parse(), CHECK_THROWS_WITH(json::parser("\"\\u01").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser("\"\\u012").parse(), CHECK_THROWS_WITH(json::parser("\"\\u012").parse(),
"parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
// invalid escapes // invalid escapes
for (int c = 1; c < 128; ++c) for (int c = 1; c < 128; ++c)
@ -510,8 +521,9 @@ TEST_CASE("parser class")
// any other combination of backslash and character is invalid // any other combination of backslash and character is invalid
default: default:
{ {
CHECK_THROWS_AS(json::parser(s.c_str()).parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser(s.c_str()).parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser(s.c_str()).parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser(s.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
break; break;
} }
} }
@ -576,40 +588,49 @@ TEST_CASE("parser class")
} }
else else
{ {
CHECK_THROWS_AS(json::parser(s1.c_str()).parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser(s1.c_str()).parse(), json::parse_error);
CHECK_THROWS_AS(json::parser(s2.c_str()).parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser(s2.c_str()).parse(), json::parse_error);
CHECK_THROWS_AS(json::parser(s3.c_str()).parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser(s3.c_str()).parse(), json::parse_error);
CHECK_THROWS_AS(json::parser(s4.c_str()).parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser(s4.c_str()).parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser(s1.c_str()).parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser(s1.c_str()).parse(),
CHECK_THROWS_WITH(json::parser(s2.c_str()).parse(), "parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser(s3.c_str()).parse(), "parse error - unexpected '\"'"); CHECK_THROWS_WITH(json::parser(s2.c_str()).parse(),
CHECK_THROWS_WITH(json::parser(s4.c_str()).parse(), "parse error - unexpected '\"'"); "[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser(s3.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
CHECK_THROWS_WITH(json::parser(s4.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected '\"'");
} }
} }
} }
// missing part of a surrogate pair // missing part of a surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), "missing low surrogate"); CHECK_THROWS_WITH(json::parse("\"\\uD80C\""),
"[json.exception.parse_error.102] parse error at 8: missing low surrogate");
// invalid surrogate pair // invalid surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""),
"missing or wrong low surrogate"); "[json.exception.parse_error.102] parse error at 14: missing or wrong low surrogate");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""),
"missing or wrong low surrogate"); "[json.exception.parse_error.102] parse error at 14: missing or wrong low surrogate");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""),
"missing or wrong low surrogate"); "[json.exception.parse_error.102] parse error at 14: missing or wrong low surrogate");
} }
SECTION("tests found by mutate++") SECTION("tests found by mutate++")
{ {
// test case to make sure no comma preceeds the first key // test case to make sure no comma preceeds the first key
CHECK_THROWS_AS(json::parser("{,\"key\": false}").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{,\"key\": false}").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("{,\"key\": false}").parse(),
"[json.exception.parse_error.101] parse error at 2: parse error - unexpected ','");
// test case to make sure an object is properly closed // test case to make sure an object is properly closed
CHECK_THROWS_AS(json::parser("[{\"key\": false true]").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[{\"key\": false true]").parse(), json::parse_error);
CHECK_THROWS_WITH(json::parser("[{\"key\": false true]").parse(),
"[json.exception.parse_error.101] parse error at 19: parse error - unexpected true literal; expected '}'");
// test case to make sure the callback is properly evaluated after reading a key // test case to make sure the callback is properly evaluated after reading a key
{ {

View file

@ -702,11 +702,17 @@ TEST_CASE("constructors")
SECTION("infinity") SECTION("infinity")
{ {
// infinity is stored as null // infinity is stored properly, but serialized to null
// should change in the future: https://github.com/nlohmann/json/issues/388
json::number_float_t n(std::numeric_limits<json::number_float_t>::infinity()); json::number_float_t n(std::numeric_limits<json::number_float_t>::infinity());
json j(n); 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");
} }
} }
@ -943,9 +949,9 @@ TEST_CASE("constructors")
SECTION("object with error") SECTION("object with error")
{ {
CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }),
std::logic_error); json::type_error);
CHECK_THROWS_WITH(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), CHECK_THROWS_WITH(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }),
"cannot create object from initializer list"); "[json.exception.type_error.301] cannot create object from initializer list");
} }
SECTION("empty array") SECTION("empty array")
@ -1017,18 +1023,18 @@ TEST_CASE("constructors")
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), std::domain_error); CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), json::invalid_iterator);
CHECK_THROWS_WITH(json(jobject.begin(), jobject2.end()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jobject.begin(), jobject2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible");
CHECK_THROWS_WITH(json(jobject2.begin(), jobject.end()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jobject2.begin(), jobject.end()), "[json.exception.invalid_iterator.201] iterators are not compatible");
} }
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), std::domain_error); CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(json(jobject.cbegin(), jobject2.cend()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jobject.cbegin(), jobject2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible");
CHECK_THROWS_WITH(json(jobject2.cbegin(), jobject.cend()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jobject2.cbegin(), jobject.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible");
} }
} }
} }
@ -1082,18 +1088,18 @@ TEST_CASE("constructors")
{ {
json jarray = {1, 2, 3, 4}; json jarray = {1, 2, 3, 4};
json jarray2 = {2, 3, 4, 5}; json jarray2 = {2, 3, 4, 5};
CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), std::domain_error); CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), json::invalid_iterator);
CHECK_THROWS_WITH(json(jarray.begin(), jarray2.end()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jarray.begin(), jarray2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible");
CHECK_THROWS_WITH(json(jarray2.begin(), jarray.end()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jarray2.begin(), jarray.end()), "[json.exception.invalid_iterator.201] iterators are not compatible");
} }
{ {
json jarray = {1, 2, 3, 4}; json jarray = {1, 2, 3, 4};
json jarray2 = {2, 3, 4, 5}; json jarray2 = {2, 3, 4, 5};
CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), std::domain_error); CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(json(jarray.cbegin(), jarray2.cend()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jarray.cbegin(), jarray2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible");
CHECK_THROWS_WITH(json(jarray2.cbegin(), jarray.cend()), "iterators are not compatible"); CHECK_THROWS_WITH(json(jarray2.cbegin(), jarray.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible");
} }
} }
} }
@ -1106,13 +1112,15 @@ TEST_CASE("constructors")
{ {
{ {
json j; json j;
CHECK_THROWS_AS(json(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(json(j.begin(), j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.begin(), j.end()), "cannot use construct with iterators from null"); CHECK_THROWS_WITH(json(j.begin(), j.end()),
"[json.exception.invalid_iterator.206] cannot construct with iterators from null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(json(j.cbegin(), j.cend()), std::domain_error); CHECK_THROWS_AS(json(j.cbegin(), j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cbegin(), j.cend()), "cannot use construct with iterators from null"); CHECK_THROWS_WITH(json(j.cbegin(), j.cend()),
"[json.exception.invalid_iterator.206] cannot construct with iterators from null");
} }
} }
@ -1193,17 +1201,17 @@ TEST_CASE("constructors")
{ {
{ {
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -1211,17 +1219,17 @@ TEST_CASE("constructors")
{ {
{ {
json j = false; json j = false;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -1229,17 +1237,17 @@ TEST_CASE("constructors")
{ {
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -1247,17 +1255,17 @@ TEST_CASE("constructors")
{ {
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -1265,17 +1273,17 @@ TEST_CASE("constructors")
{ {
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
} }

View file

@ -78,28 +78,28 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-object type") SECTION("exception in case of a non-object type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::object_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::object_t>(),
"type must be object, but is null"); "[json.exception.type_error.302] type must be object, but is null");
CHECK_THROWS_WITH(json(json::value_t::array).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::array).get<json::object_t>(),
"type must be object, but is array"); "[json.exception.type_error.302] type must be object, but is array");
CHECK_THROWS_WITH(json(json::value_t::string).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::string).get<json::object_t>(),
"type must be object, but is string"); "[json.exception.type_error.302] type must be object, but is string");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),
"type must be object, but is boolean"); "[json.exception.type_error.302] type must be object, but is boolean");
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::object_t>(),
"type must be object, but is number"); "[json.exception.type_error.302] type must be object, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::object_t>(),
"type must be object, but is number"); "[json.exception.type_error.302] type must be object, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::object_t>(), CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::object_t>(),
"type must be object, but is number"); "[json.exception.type_error.302] type must be object, but is number");
} }
} }
@ -161,9 +161,9 @@ TEST_CASE("value conversion")
std::forward_list<json> a = j.get<std::forward_list<json>>(); std::forward_list<json> a = j.get<std::forward_list<json>>();
CHECK(json(a) == j); CHECK(json(a) == j);
CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<std::forward_list<json>>(), CHECK_THROWS_WITH(json(json::value_t::null).get<std::forward_list<json>>(),
"type must be array, but is null"); "[json.exception.type_error.302] type must be array, but is null");
} }
SECTION("std::vector<json>") SECTION("std::vector<json>")
@ -171,16 +171,16 @@ TEST_CASE("value conversion")
std::vector<json> a = j.get<std::vector<json>>(); std::vector<json> a = j.get<std::vector<json>>();
CHECK(json(a) == j); CHECK(json(a) == j);
CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<std::vector<json>>(), CHECK_THROWS_WITH(json(json::value_t::null).get<std::vector<json>>(),
"type must be array, but is null"); "[json.exception.type_error.302] type must be array, but is null");
#if not defined(JSON_NOEXCEPTION) #if not defined(JSON_NOEXCEPTION)
SECTION("reserve is called on containers that supports it") SECTION("reserve is called on containers that supports it")
{ {
// making the call to from_json throw in order to check capacity // making the call to from_json throw in order to check capacity
std::vector<float> v; std::vector<float> v;
CHECK_THROWS_AS(nlohmann::from_json(j, v), std::logic_error); CHECK_THROWS_AS(nlohmann::from_json(j, v), json::type_error);
CHECK(v.capacity() == j.size()); CHECK(v.capacity() == j.size());
// make sure all values are properly copied // make sure all values are properly copied
@ -198,30 +198,30 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-array type") SECTION("exception in case of a non-array type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::object).get<std::vector<int>>(), CHECK_THROWS_WITH(json(json::value_t::object).get<std::vector<int>>(),
"type must be array, but is object"); "[json.exception.type_error.302] type must be array, but is object");
CHECK_THROWS_WITH(json(json::value_t::null).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::array_t>(),
"type must be array, but is null"); "[json.exception.type_error.302] type must be array, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::object).get<json::array_t>(),
"type must be array, but is object"); "[json.exception.type_error.302] type must be array, but is object");
CHECK_THROWS_WITH(json(json::value_t::string).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::string).get<json::array_t>(),
"type must be array, but is string"); "[json.exception.type_error.302] type must be array, but is string");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::array_t>(),
"type must be array, but is boolean"); "[json.exception.type_error.302] type must be array, but is boolean");
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::array_t>(),
"type must be array, but is number"); "[json.exception.type_error.302] type must be array, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::array_t>(),
"type must be array, but is number"); "[json.exception.type_error.302] type must be array, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::array_t>(), CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::array_t>(),
"type must be array, but is number"); "[json.exception.type_error.302] type must be array, but is number");
} }
} }
@ -280,28 +280,28 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-string type") SECTION("exception in case of a non-string type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::string_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::string_t>(),
"type must be string, but is null"); "[json.exception.type_error.302] type must be string, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::object).get<json::string_t>(),
"type must be string, but is object"); "[json.exception.type_error.302] type must be string, but is object");
CHECK_THROWS_WITH(json(json::value_t::array).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::array).get<json::string_t>(),
"type must be string, but is array"); "[json.exception.type_error.302] type must be string, but is array");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
"type must be string, but is boolean"); "[json.exception.type_error.302] type must be string, but is boolean");
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::string_t>(),
"type must be string, but is number"); "[json.exception.type_error.302] type must be string, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::string_t>(),
"type must be string, but is number"); "[json.exception.type_error.302] type must be string, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::string_t>(), CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::string_t>(),
"type must be string, but is number"); "[json.exception.type_error.302] type must be string, but is number");
} }
} }
@ -342,28 +342,28 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-string type") SECTION("exception in case of a non-string type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::boolean_t>(),
"type must be boolean, but is null"); "[json.exception.type_error.302] type must be boolean, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
"type must be boolean, but is object"); "[json.exception.type_error.302] type must be boolean, but is object");
CHECK_THROWS_WITH(json(json::value_t::array).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::array).get<json::boolean_t>(),
"type must be boolean, but is array"); "[json.exception.type_error.302] type must be boolean, but is array");
CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
"type must be boolean, but is string"); "[json.exception.type_error.302] type must be boolean, but is string");
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::boolean_t>(),
"type must be boolean, but is number"); "[json.exception.type_error.302] type must be boolean, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::boolean_t>(),
"type must be boolean, but is number"); "[json.exception.type_error.302] type must be boolean, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::boolean_t>(), CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::boolean_t>(),
"type must be boolean, but is number"); "[json.exception.type_error.302] type must be boolean, but is number");
} }
} }
@ -598,22 +598,22 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-number type") SECTION("exception in case of a non-number type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_integer_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_integer_t>(),
"type must be number, but is null"); "[json.exception.type_error.302] type must be number, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_integer_t>(), CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_integer_t>(),
"type must be number, but is object"); "[json.exception.type_error.302] type must be number, but is object");
CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_integer_t>(), CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_integer_t>(),
"type must be number, but is array"); "[json.exception.type_error.302] type must be number, but is array");
CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_integer_t>(), CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_integer_t>(),
"type must be number, but is string"); "[json.exception.type_error.302] type must be number, but is string");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_integer_t>(), CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_integer_t>(),
"type must be number, but is boolean"); "[json.exception.type_error.302] type must be number, but is boolean");
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>()); CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_unsigned_t>()); CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_unsigned_t>());
@ -857,22 +857,22 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-string type") SECTION("exception in case of a non-string type")
{ {
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), json::type_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), json::type_error);
CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_float_t>(), CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_float_t>(),
"type must be number, but is null"); "[json.exception.type_error.302] type must be number, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_float_t>(), CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_float_t>(),
"type must be number, but is object"); "[json.exception.type_error.302] type must be number, but is object");
CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_float_t>(), CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_float_t>(),
"type must be number, but is array"); "[json.exception.type_error.302] type must be number, but is array");
CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_float_t>(), CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_float_t>(),
"type must be number, but is string"); "[json.exception.type_error.302] type must be number, but is string");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_float_t>(), CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_float_t>(),
"type must be number, but is boolean"); "[json.exception.type_error.302] type must be number, but is boolean");
CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>()); CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
CHECK_NOTHROW(json(json::value_t::number_unsigned).get<json::number_float_t>()); CHECK_NOTHROW(json(json::value_t::number_unsigned).get<json::number_float_t>());
@ -954,8 +954,8 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-object type") SECTION("exception in case of a non-object type")
{ {
CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), json::type_error);
CHECK_THROWS_WITH((json().get<std::map<std::string, int>>()), "type must be object, but is null"); CHECK_THROWS_WITH((json().get<std::map<std::string, int>>()), "[json.exception.type_error.302] type must be object, but is null");
} }
} }
@ -1023,17 +1023,17 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-object type") SECTION("exception in case of a non-object type")
{ {
CHECK_THROWS_AS((json().get<std::list<int>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::list<int>>()), json::type_error);
CHECK_THROWS_AS((json().get<std::vector<int>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::vector<int>>()), json::type_error);
CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::vector<json>>()), json::type_error);
CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::list<json>>()), json::type_error);
// does type really must be an array? or it rather must not be null? // does type really must be an array? or it rather must not be null?
// that's what I thought when other test like this one broke // that's what I thought when other test like this one broke
CHECK_THROWS_WITH((json().get<std::list<int>>()), "type must be array, but is null"); CHECK_THROWS_WITH((json().get<std::list<int>>()), "[json.exception.type_error.302] type must be array, but is null");
CHECK_THROWS_WITH((json().get<std::vector<int>>()), "type must be array, but is null"); CHECK_THROWS_WITH((json().get<std::vector<int>>()), "[json.exception.type_error.302] type must be array, but is null");
CHECK_THROWS_WITH((json().get<std::vector<json>>()), "type must be array, but is null"); CHECK_THROWS_WITH((json().get<std::vector<json>>()), "[json.exception.type_error.302] type must be array, but is null");
CHECK_THROWS_WITH((json().get<std::list<json>>()), "type must be array, but is null"); CHECK_THROWS_WITH((json().get<std::list<json>>()), "[json.exception.type_error.302] type must be array, but is null");
} }
} }
} }

View file

@ -90,15 +90,17 @@ TEST_CASE("deserialization")
std::stringstream ss1, ss2; std::stringstream ss1, ss2;
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(ss1), std::invalid_argument); CHECK_THROWS_AS(json::parse(ss1), json::parse_error);
CHECK_THROWS_WITH(json::parse(ss2), "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(json::parse(ss2),
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("string") SECTION("string")
{ {
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(s), std::invalid_argument); CHECK_THROWS_AS(json::parse(s), json::parse_error);
CHECK_THROWS_WITH(json::parse(s), "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(json::parse(s),
"[json.exception.parse_error.101] parse error at 29: parse error - unexpected end of input; expected ']'");
} }
SECTION("operator<<") SECTION("operator<<")
@ -107,8 +109,9 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j; json j;
CHECK_THROWS_AS(j << ss1, std::invalid_argument); CHECK_THROWS_AS(j << ss1, json::parse_error);
CHECK_THROWS_WITH(j << ss2, "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(j << ss2,
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("operator>>") SECTION("operator>>")
@ -117,15 +120,16 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j; json j;
CHECK_THROWS_AS(ss1 >> j, std::invalid_argument); CHECK_THROWS_AS(ss1 >> j, json::parse_error);
CHECK_THROWS_WITH(ss2 >> j, "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(ss2 >> j,
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("user-defined string literal") SECTION("user-defined string literal")
{ {
CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, std::invalid_argument); CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error);
CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json, CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
"parse error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at 29: parse error - unexpected end of input; expected ']'");
} }
} }
@ -178,7 +182,7 @@ TEST_CASE("deserialization")
SECTION("empty container") SECTION("empty container")
{ {
std::vector<uint8_t> v; std::vector<uint8_t> v;
CHECK_THROWS_AS(json::parse(v), std::invalid_argument); CHECK_THROWS_AS(json::parse(v), json::parse_error);
} }
} }
@ -223,7 +227,7 @@ TEST_CASE("deserialization")
SECTION("with empty range") SECTION("with empty range")
{ {
std::vector<uint8_t> v; std::vector<uint8_t> v;
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
} }
@ -233,91 +237,91 @@ TEST_CASE("deserialization")
SECTION("case 1") SECTION("case 1")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 2") SECTION("case 2")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 3") SECTION("case 3")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 4") SECTION("case 4")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 5") SECTION("case 5")
{ {
uint8_t v[] = {'\"', 0x7F, 0xC1}; uint8_t v[] = {'\"', 0x7F, 0xC1};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 6") SECTION("case 6")
{ {
uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 7") SECTION("case 7")
{ {
uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 8") SECTION("case 8")
{ {
uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F}; uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 9") SECTION("case 9")
{ {
uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 10") SECTION("case 10")
{ {
uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 11") SECTION("case 11")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F}; uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 12") SECTION("case 12")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 13") SECTION("case 13")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 14") SECTION("case 14")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 15") SECTION("case 15")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
} }
} }

View file

@ -63,11 +63,13 @@ TEST_CASE("element access 1")
SECTION("access outside bounds") SECTION("access outside bounds")
{ {
CHECK_THROWS_AS(j.at(8), std::out_of_range); CHECK_THROWS_AS(j.at(8), json::out_of_range);
CHECK_THROWS_AS(j_const.at(8), std::out_of_range); CHECK_THROWS_AS(j_const.at(8), json::out_of_range);
CHECK_THROWS_WITH(j.at(8), "array index 8 is out of range"); CHECK_THROWS_WITH(j.at(8),
CHECK_THROWS_WITH(j_const.at(8), "array index 8 is out of range"); "[json.exception.out_of_range.401] array index 8 is out of range");
CHECK_THROWS_WITH(j_const.at(8),
"[json.exception.out_of_range.401] array index 8 is out of range");
} }
SECTION("access on non-array type") SECTION("access on non-array type")
@ -76,77 +78,77 @@ TEST_CASE("element access 1")
{ {
json j_nonarray(json::value_t::null); json j_nonarray(json::value_t::null);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with null"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with null");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with null"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonarray(json::value_t::boolean); json j_nonarray(json::value_t::boolean);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with boolean"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with boolean");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with boolean"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonarray(json::value_t::string); json j_nonarray(json::value_t::string);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with string"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with string");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with string"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with string");
} }
SECTION("object") SECTION("object")
{ {
json j_nonarray(json::value_t::object); json j_nonarray(json::value_t::object);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with object"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with object");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with object"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonarray(json::value_t::number_integer); json j_nonarray(json::value_t::number_integer);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonarray(json::value_t::number_unsigned); json j_nonarray(json::value_t::number_unsigned);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonarray(json::value_t::number_float); json j_nonarray(json::value_t::number_float);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), json::type_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), json::type_error);
CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray.at(0), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonarray_const.at(0), "[json.exception.type_error.304] cannot use at() with number");
} }
} }
} }
@ -191,8 +193,8 @@ TEST_CASE("element access 1")
json j_nonarray(json::value_t::null); json j_nonarray(json::value_t::null);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_NOTHROW(j_nonarray[0]); CHECK_NOTHROW(j_nonarray[0]);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with null"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with null");
} }
SECTION("implicit transformation to properly filled array") SECTION("implicit transformation to properly filled array")
@ -207,60 +209,60 @@ TEST_CASE("element access 1")
{ {
json j_nonarray(json::value_t::boolean); json j_nonarray(json::value_t::boolean);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with boolean");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonarray(json::value_t::string); json j_nonarray(json::value_t::string);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with string"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with string");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with string"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with string");
} }
SECTION("object") SECTION("object")
{ {
json j_nonarray(json::value_t::object); json j_nonarray(json::value_t::object);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with object"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with object");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with object"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonarray(json::value_t::number_integer); json j_nonarray(json::value_t::number_integer);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonarray(json::value_t::number_unsigned); json j_nonarray(json::value_t::number_unsigned);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonarray(json::value_t::number_float); json j_nonarray(json::value_t::number_float);
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], json::type_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], json::type_error);
CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with number");
} }
} }
} }
@ -311,8 +313,9 @@ TEST_CASE("element access 1")
} }
{ {
json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
CHECK_THROWS_AS(jarray.erase(8), std::out_of_range); CHECK_THROWS_AS(jarray.erase(8), json::out_of_range);
CHECK_THROWS_WITH(jarray.erase(8), "array index 8 is out of range"); CHECK_THROWS_WITH(jarray.erase(8),
"[json.exception.out_of_range.401] array index 8 is out of range");
} }
} }
@ -405,34 +408,36 @@ TEST_CASE("element access 1")
{ {
json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
json jarray2 = {"foo", "bar"}; json jarray2 = {"foo", "bar"};
CHECK_THROWS_AS(jarray.erase(jarray2.begin()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.begin()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), json::invalid_iterator);
CHECK_THROWS_WITH(jarray.erase(jarray2.begin()), "iterator does not fit current value"); CHECK_THROWS_WITH(jarray.erase(jarray2.begin()),
"[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()), CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()), CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()), CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
} }
{ {
json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
json jarray2 = {"foo", "bar"}; json jarray2 = {"foo", "bar"};
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), json::invalid_iterator);
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()), "iterator does not fit current value"); CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()),
"[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()), CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()), CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()), CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
} }
} }
} }
@ -442,50 +447,57 @@ TEST_CASE("element access 1")
SECTION("null") SECTION("null")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with null"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with boolean"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with string"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with string");
} }
SECTION("object") SECTION("object")
{ {
json j_nonobject(json::value_t::object); json j_nonobject(json::value_t::object);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with object"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonobject(json::value_t::number_unsigned); json j_nonobject(json::value_t::number_unsigned);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number"); CHECK_THROWS_WITH(j_nonobject.erase(0),
"[json.exception.type_error.307] cannot use erase() with number");
} }
} }
} }
@ -499,17 +511,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j; json j;
CHECK_THROWS_AS(j.front(), std::out_of_range); CHECK_THROWS_AS(j.front(), json::invalid_iterator);
CHECK_THROWS_AS(j.back(), std::out_of_range); CHECK_THROWS_AS(j.back(), json::invalid_iterator);
CHECK_THROWS_WITH(j.front(), "cannot get value"); CHECK_THROWS_WITH(j.front(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(j.back(), "cannot get value"); CHECK_THROWS_WITH(j.back(), "[json.exception.invalid_iterator.214] cannot get value");
} }
{ {
const json j{}; const json j{};
CHECK_THROWS_AS(j.front(), std::out_of_range); CHECK_THROWS_AS(j.front(), json::invalid_iterator);
CHECK_THROWS_AS(j.back(), std::out_of_range); CHECK_THROWS_AS(j.back(), json::invalid_iterator);
CHECK_THROWS_WITH(j.front(), "cannot get value"); CHECK_THROWS_WITH(j.front(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(j.back(), "cannot get value"); CHECK_THROWS_WITH(j.back(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -590,13 +602,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error); CHECK_THROWS_AS(j.erase(j.begin()), json::type_error);
CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null"); CHECK_THROWS_WITH(j.erase(j.begin()),
"[json.exception.type_error.307] cannot use erase() with null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error); CHECK_THROWS_AS(j.erase(j.cbegin()), json::type_error);
CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null"); CHECK_THROWS_WITH(j.erase(j.begin()),
"[json.exception.type_error.307] cannot use erase() with null");
} }
} }
@ -687,13 +701,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.end()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.cend()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
} }
@ -701,13 +717,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j = false; json j = false;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.end()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.cend()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
} }
@ -715,13 +733,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.end()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.cend()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
} }
@ -729,13 +749,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.end()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.cend()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
} }
@ -743,13 +765,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.end()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range"); CHECK_THROWS_WITH(j.erase(j.cend()),
"[json.exception.invalid_iterator.205] iterator out of range");
} }
} }
} }
@ -760,13 +784,15 @@ TEST_CASE("element access 1")
{ {
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(j.erase(j.begin(), j.end()), json::type_error);
CHECK_THROWS_WITH(j.erase(j.begin(), j.end()), "cannot use erase() with null"); CHECK_THROWS_WITH(j.erase(j.begin(), j.end()),
"[json.exception.type_error.307] cannot use erase() with null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), json::type_error);
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()), "cannot use erase() with null"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()),
"[json.exception.type_error.307] cannot use erase() with null");
} }
} }
@ -857,17 +883,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -875,17 +901,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j = false; json j = false;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -893,17 +919,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -911,17 +937,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 17u; json j = 17u;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
@ -929,17 +955,17 @@ TEST_CASE("element access 1")
{ {
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), json::invalid_iterator);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator);
CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range");
CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range"); CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range");
} }
} }
} }

View file

@ -63,10 +63,12 @@ TEST_CASE("element access 2")
SECTION("access outside bounds") SECTION("access outside bounds")
{ {
CHECK_THROWS_AS(j.at("foo"), std::out_of_range); CHECK_THROWS_AS(j.at("foo"), json::out_of_range);
CHECK_THROWS_AS(j_const.at("foo"), std::out_of_range); CHECK_THROWS_AS(j_const.at("foo"), json::out_of_range);
CHECK_THROWS_WITH(j.at("foo"), "key 'foo' not found"); CHECK_THROWS_WITH(j.at("foo"),
CHECK_THROWS_WITH(j_const.at("foo"), "key 'foo' not found"); "[json.exception.out_of_range.403] key 'foo' not found");
CHECK_THROWS_WITH(j_const.at("foo"),
"[json.exception.out_of_range.403] key 'foo' not found");
} }
SECTION("access on non-object type") SECTION("access on non-object type")
@ -75,70 +77,70 @@ TEST_CASE("element access 2")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with null"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with null");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with null"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with boolean"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with boolean"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with string"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with string"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with array"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with array");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with array"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonobject(json::value_t::number_unsigned); json j_nonobject(json::value_t::number_unsigned);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number");
} }
} }
} }
@ -200,70 +202,84 @@ TEST_CASE("element access 2")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with null"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with null"); "[json.exception.type_error.306] cannot use value() with null");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with boolean"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with boolean"); "[json.exception.type_error.306] cannot use value() with boolean");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with string"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with string"); "[json.exception.type_error.306] cannot use value() with string");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with array"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with array"); "[json.exception.type_error.306] cannot use value() with array");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonobject(json::value_t::number_unsigned); json j_nonobject(json::value_t::number_unsigned);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("foo", 1),
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1),
"[json.exception.type_error.306] cannot use value() with number");
} }
} }
} }
@ -304,75 +320,84 @@ TEST_CASE("element access 2")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with null"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), "cannot use value() with null"); "[json.exception.type_error.306] cannot use value() with null");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with boolean"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with boolean");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"cannot use value() with boolean"); "[json.exception.type_error.306] cannot use value() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with string"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with string");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"cannot use value() with string"); "[json.exception.type_error.306] cannot use value() with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with array"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), "cannot use value() with array"); "[json.exception.type_error.306] cannot use value() with array");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonobject(json::value_t::number_unsigned); json j_nonobject(json::value_t::number_unsigned);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error);
CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1), "cannot use value() with number"); CHECK_THROWS_WITH(j_nonobject.value("/foo"_json_pointer, 1),
"[json.exception.type_error.306] cannot use value() with number");
CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1), CHECK_THROWS_WITH(j_nonobject_const.value("/foo"_json_pointer, 1),
"cannot use value() with number"); "[json.exception.type_error.306] cannot use value() with number");
} }
} }
} }
@ -447,106 +472,118 @@ TEST_CASE("element access 2")
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_NOTHROW(j_nonobject["foo"]); CHECK_NOTHROW(j_nonobject["foo"]);
CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]); CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with null"); CHECK_THROWS_WITH(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with null");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with null"); "[json.exception.type_error.305] cannot use operator[] with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with boolean");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with boolean");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with boolean"); CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with boolean");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with boolean"); "[json.exception.type_error.305] cannot use operator[] with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with string"); CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with string");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with string");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with string"); CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with string");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with string"); "[json.exception.type_error.305] cannot use operator[] with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with array"); CHECK_THROWS_WITH(j_nonobject["foo"],
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "cannot use operator[] with array"); "[json.exception.type_error.305] cannot use operator[] with array");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with array"); CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with array");
CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with array");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with array"); "[json.exception.type_error.305] cannot use operator[] with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
} }
SECTION("number (unsigned)") SECTION("number (unsigned)")
{ {
json j_nonobject(json::value_t::number_unsigned); json j_nonobject(json::value_t::number_unsigned);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
const json j_const_nonobject(j_nonobject); const json j_const_nonobject(j_nonobject);
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], json::type_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], json::type_error);
CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number"); CHECK_THROWS_WITH(j_const_nonobject["foo"],
"[json.exception.type_error.305] cannot use operator[] with number");
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")], CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
"cannot use operator[] with number"); "[json.exception.type_error.305] cannot use operator[] with number");
} }
} }
} }
@ -685,32 +722,34 @@ TEST_CASE("element access 2")
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
CHECK_THROWS_AS(jobject.erase(jobject2.begin()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.begin()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), json::invalid_iterator);
CHECK_THROWS_WITH(jobject.erase(jobject2.begin()), "iterator does not fit current value"); CHECK_THROWS_WITH(jobject.erase(jobject2.begin()),
"[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()), CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()), CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()), CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
} }
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), json::invalid_iterator);
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), json::invalid_iterator);
CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()), "iterator does not fit current value"); CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()),
"[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()), CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()), CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()), CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()),
"iterators do not fit current value"); "[json.exception.invalid_iterator.203] iterators do not fit current value");
} }
} }
} }
@ -720,43 +759,49 @@ TEST_CASE("element access 2")
SECTION("null") SECTION("null")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with null"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with boolean"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with string"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with array"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), json::type_error);
CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number"); CHECK_THROWS_WITH(j_nonobject.erase("foo"),
"[json.exception.type_error.307] cannot use erase() with number");
} }
} }
} }

View file

@ -229,23 +229,23 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json(true)); CHECK(it.value() == json(true));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json(true)); CHECK(cit.value() == json(true));
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -433,23 +433,23 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json("hello world")); CHECK(it.value() == json("hello world"));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json("hello world")); CHECK(cit.value() == json("hello world"));
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -630,11 +630,11 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json(1)); CHECK(it.value() == json(1));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json(1)); CHECK(cit.value() == json(1));
} }
} }
@ -1007,23 +1007,23 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json(23)); CHECK(it.value() == json(23));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json(23)); CHECK(cit.value() == json(23));
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -1211,23 +1211,23 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json(23)); CHECK(it.value() == json(23));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json(23)); CHECK(cit.value() == json(23));
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -1415,23 +1415,23 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(it.value() == json(23.42)); CHECK(it.value() == json(23.42));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK(cit.value() == json(23.42)); CHECK(cit.value() == json(23.42));
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -1489,25 +1489,25 @@ TEST_CASE("iterators 1")
{ {
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), json::invalid_iterator);
CHECK_THROWS_AS(it.value(), std::out_of_range); CHECK_THROWS_AS(it.value(), json::invalid_iterator);
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), json::invalid_iterator);
CHECK_THROWS_AS(cit.value(), std::out_of_range); CHECK_THROWS_AS(cit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(it.value(), "cannot get value"); CHECK_THROWS_WITH(it.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(cit.value(), "cannot get value"); CHECK_THROWS_WITH(cit.value(), "[json.exception.invalid_iterator.214] cannot get value");
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
CHECK_THROWS_AS(rit.key(), std::domain_error); CHECK_THROWS_AS(rit.key(), json::invalid_iterator);
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), json::invalid_iterator);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), json::invalid_iterator);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), json::invalid_iterator);
CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(rit.value(), "cannot get value"); CHECK_THROWS_WITH(rit.value(), "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators"); CHECK_THROWS_WITH(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators");
CHECK_THROWS_WITH(crit.value(), "cannot get value"); CHECK_THROWS_WITH(crit.value(), "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
} }

View file

@ -81,22 +81,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 < it1, std::domain_error); CHECK_THROWS_AS(it1 < it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 < it2, std::domain_error); CHECK_THROWS_AS(it1 < it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 < it3, std::domain_error); CHECK_THROWS_AS(it2 < it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 < it3, std::domain_error); CHECK_THROWS_AS(it1 < it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it1_c, std::domain_error); CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it2_c, std::domain_error); CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c < it3_c, std::domain_error); CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it3_c, std::domain_error); CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -115,22 +115,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 <= it1, std::domain_error); CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 <= it2, std::domain_error); CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 <= it3, std::domain_error); CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 <= it3, std::domain_error); CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -150,22 +150,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 > it1, std::domain_error); CHECK_THROWS_AS(it1 > it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 > it2, std::domain_error); CHECK_THROWS_AS(it1 > it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 > it3, std::domain_error); CHECK_THROWS_AS(it2 > it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 > it3, std::domain_error); CHECK_THROWS_AS(it1 > it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it1_c, std::domain_error); CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it2_c, std::domain_error); CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c > it3_c, std::domain_error); CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it3_c, std::domain_error); CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -185,22 +185,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 >= it1, std::domain_error); CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 >= it2, std::domain_error); CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 >= it3, std::domain_error); CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 >= it3, std::domain_error); CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -224,15 +224,15 @@ TEST_CASE("iterators 2")
{ {
if (j != k) if (j != k)
{ {
CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error); CHECK_THROWS_AS(j.begin() == k.begin(), json::invalid_iterator);
CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error); CHECK_THROWS_AS(j.cbegin() == k.cbegin(), json::invalid_iterator);
CHECK_THROWS_WITH(j.begin() == k.begin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.begin() == k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error); CHECK_THROWS_AS(j.begin() < k.begin(), json::invalid_iterator);
CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error); CHECK_THROWS_AS(j.cbegin() < k.cbegin(), json::invalid_iterator);
CHECK_THROWS_WITH(j.begin() < k.begin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.begin() < k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
} }
} }
} }
@ -251,53 +251,53 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, json::invalid_iterator);
CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, json::invalid_iterator);
CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, json::invalid_iterator);
CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, json::invalid_iterator);
CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, json::invalid_iterator);
CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, json::invalid_iterator);
CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
} }
@ -380,17 +380,17 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it[0], std::domain_error); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::domain_error); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it[0], std::domain_error); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::domain_error); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
} }
} }
@ -420,17 +420,17 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_null.begin(); auto it = j_null.begin();
CHECK_THROWS_AS(it[0], std::out_of_range); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot get value"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
{ {
auto it = j_null.cbegin(); auto it = j_null.cbegin();
CHECK_THROWS_AS(it[0], std::out_of_range); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot get value"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -439,14 +439,14 @@ TEST_CASE("iterators 2")
{ {
auto it = j_value.begin(); auto it = j_value.begin();
CHECK(it[0] == json(42)); CHECK(it[0] == json(42));
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
{ {
auto it = j_value.cbegin(); auto it = j_value.cbegin();
CHECK(it[0] == json(42)); CHECK(it[0] == json(42));
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
} }
@ -500,22 +500,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 < it1, std::domain_error); CHECK_THROWS_AS(it1 < it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 < it2, std::domain_error); CHECK_THROWS_AS(it1 < it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 < it3, std::domain_error); CHECK_THROWS_AS(it2 < it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 < it3, std::domain_error); CHECK_THROWS_AS(it1 < it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it1_c, std::domain_error); CHECK_THROWS_AS(it1_c < it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it2_c, std::domain_error); CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c < it3_c, std::domain_error); CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c < it3_c, std::domain_error); CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -534,22 +534,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 <= it1, std::domain_error); CHECK_THROWS_AS(it1 <= it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 <= it2, std::domain_error); CHECK_THROWS_AS(it1 <= it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 <= it3, std::domain_error); CHECK_THROWS_AS(it2 <= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 <= it3, std::domain_error); CHECK_THROWS_AS(it1 <= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -569,22 +569,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 > it1, std::domain_error); CHECK_THROWS_AS(it1 > it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 > it2, std::domain_error); CHECK_THROWS_AS(it1 > it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 > it3, std::domain_error); CHECK_THROWS_AS(it2 > it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 > it3, std::domain_error); CHECK_THROWS_AS(it1 > it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it1_c, std::domain_error); CHECK_THROWS_AS(it1_c > it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it2_c, std::domain_error); CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c > it3_c, std::domain_error); CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c > it3_c, std::domain_error); CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -604,22 +604,22 @@ TEST_CASE("iterators 2")
{ {
if (j.type() == json::value_t::object) if (j.type() == json::value_t::object)
{ {
CHECK_THROWS_AS(it1 >= it1, std::domain_error); CHECK_THROWS_AS(it1 >= it1, json::invalid_iterator);
CHECK_THROWS_AS(it1 >= it2, std::domain_error); CHECK_THROWS_AS(it1 >= it2, json::invalid_iterator);
CHECK_THROWS_AS(it2 >= it3, std::domain_error); CHECK_THROWS_AS(it2 >= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1 >= it3, std::domain_error); CHECK_THROWS_AS(it1 >= it3, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it1_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator);
CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator);
CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator);
CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators"); CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
} }
else else
{ {
@ -643,15 +643,15 @@ TEST_CASE("iterators 2")
{ {
if (j != k) if (j != k)
{ {
CHECK_THROWS_AS(j.rbegin() == k.rbegin(), std::domain_error); CHECK_THROWS_AS(j.rbegin() == k.rbegin(), json::invalid_iterator);
CHECK_THROWS_AS(j.crbegin() == k.crbegin(), std::domain_error); CHECK_THROWS_AS(j.crbegin() == k.crbegin(), json::invalid_iterator);
CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_AS(j.rbegin() < k.rbegin(), std::domain_error); CHECK_THROWS_AS(j.rbegin() < k.rbegin(), json::invalid_iterator);
CHECK_THROWS_AS(j.crbegin() < k.crbegin(), std::domain_error); CHECK_THROWS_AS(j.crbegin() < k.crbegin(), json::invalid_iterator);
CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "cannot compare iterators of different containers"); CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
} }
} }
} }
@ -670,53 +670,53 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, json::invalid_iterator);
CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, json::invalid_iterator);
CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it += 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it -= 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, json::invalid_iterator);
CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, json::invalid_iterator);
CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, json::invalid_iterator);
CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, json::invalid_iterator);
CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it - it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
} }
@ -799,17 +799,17 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_object.rbegin(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it[0], std::domain_error); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::domain_error); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
{ {
auto it = j_object.crbegin(); auto it = j_object.crbegin();
CHECK_THROWS_AS(it[0], std::domain_error); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::domain_error); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
} }
@ -839,17 +839,17 @@ TEST_CASE("iterators 2")
{ {
{ {
auto it = j_null.rbegin(); auto it = j_null.rbegin();
CHECK_THROWS_AS(it[0], std::out_of_range); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot get value"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
{ {
auto it = j_null.crbegin(); auto it = j_null.crbegin();
CHECK_THROWS_AS(it[0], std::out_of_range); CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "cannot get value"); CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
@ -858,14 +858,14 @@ TEST_CASE("iterators 2")
{ {
auto it = j_value.rbegin(); auto it = j_value.rbegin();
CHECK(it[0] == json(42)); CHECK(it[0] == json(42));
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
{ {
auto it = j_value.crbegin(); auto it = j_value.crbegin();
CHECK(it[0] == json(42)); CHECK(it[0] == json(42));
CHECK_THROWS_AS(it[1], std::out_of_range); CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[1], "cannot get value"); CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
} }
} }
} }

View file

@ -75,8 +75,9 @@ TEST_CASE("JSON patch")
json doc2 = R"({ "q": { "bar": 2 } })"_json; json doc2 = R"({ "q": { "bar": 2 } })"_json;
// because "a" does not exist. // because "a" does not exist.
CHECK_THROWS_AS(doc2.patch(patch), std::out_of_range); CHECK_THROWS_AS(doc2.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(doc2.patch(patch), "key 'a' not found"); CHECK_THROWS_WITH(doc2.patch(patch),
"[json.exception.out_of_range.403] key 'a' not found");
} }
SECTION("4.2 remove") SECTION("4.2 remove")
@ -336,8 +337,8 @@ TEST_CASE("JSON patch")
)"_json; )"_json;
// check that evaluation throws // check that evaluation throws
CHECK_THROWS_AS(doc.patch(patch), std::domain_error); CHECK_THROWS_AS(doc.patch(patch), json::other_error);
CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump()); CHECK_THROWS_WITH(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
} }
SECTION("A.10. Adding a Nested Member Object") SECTION("A.10. Adding a Nested Member Object")
@ -420,8 +421,9 @@ TEST_CASE("JSON patch")
// references neither the root of the document, nor a member of // references neither the root of the document, nor a member of
// an existing object, nor a member of an existing array. // an existing object, nor a member of an existing array.
CHECK_THROWS_AS(doc.patch(patch), std::out_of_range); CHECK_THROWS_AS(doc.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(doc.patch(patch), "key 'baz' not found"); CHECK_THROWS_WITH(doc.patch(patch),
"[json.exception.out_of_range.403] key 'baz' not found");
} }
// A.13. Invalid JSON Patch Document // A.13. Invalid JSON Patch Document
@ -476,8 +478,8 @@ TEST_CASE("JSON patch")
)"_json; )"_json;
// check that evaluation throws // check that evaluation throws
CHECK_THROWS_AS(doc.patch(patch), std::domain_error); CHECK_THROWS_AS(doc.patch(patch), json::other_error);
CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump()); CHECK_THROWS_WITH(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
} }
SECTION("A.16. Adding an Array Value") SECTION("A.16. Adding an Array Value")
@ -666,40 +668,45 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{"op", "add"}, {"path", ""}, {"value", 1}}; json patch = {{"op", "add"}, {"path", ""}, {"value", 1}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "JSON patch must be an array of objects"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects");
} }
SECTION("not an array of objects") SECTION("not an array of objects")
{ {
json j; json j;
json patch = {"op", "add", "path", "", "value", 1}; json patch = {"op", "add", "path", "", "value", 1};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "JSON patch must be an array of objects"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects");
} }
SECTION("missing 'op'") SECTION("missing 'op'")
{ {
json j; json j;
json patch = {{{"foo", "bar"}}}; json patch = {{{"foo", "bar"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation must have member 'op'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation must have member 'op'");
} }
SECTION("non-string 'op'") SECTION("non-string 'op'")
{ {
json j; json j;
json patch = {{{"op", 1}}}; json patch = {{{"op", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation must have string member 'op'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation must have string member 'op'");
} }
SECTION("invalid operation") SECTION("invalid operation")
{ {
json j; json j;
json patch = {{{"op", "foo"}, {"path", ""}}}; json patch = {{{"op", "foo"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation value 'foo' is invalid"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation value 'foo' is invalid");
} }
} }
@ -709,32 +716,36 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "add"}}}; json patch = {{{"op", "add"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "add"}, {"path", 1}}}; json patch = {{{"op", "add"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'");
} }
SECTION("missing 'value'") SECTION("missing 'value'")
{ {
json j; json j;
json patch = {{{"op", "add"}, {"path", ""}}}; json patch = {{{"op", "add"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'add' must have member 'value'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'");
} }
SECTION("invalid array index") SECTION("invalid array index")
{ {
json j = {1, 2}; json j = {1, 2};
json patch = {{{"op", "add"}, {"path", "/4"}, {"value", 4}}}; json patch = {{{"op", "add"}, {"path", "/4"}, {"value", 4}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "array index 4 is out of range"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.401] array index 4 is out of range");
} }
} }
@ -744,40 +755,45 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "remove"}}}; json patch = {{{"op", "remove"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'remove' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "remove"}, {"path", 1}}}; json patch = {{{"op", "remove"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'remove' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'");
} }
SECTION("nonexisting target location (array)") SECTION("nonexisting target location (array)")
{ {
json j = {1, 2, 3}; json j = {1, 2, 3};
json patch = {{{"op", "remove"}, {"path", "/17"}}}; json patch = {{{"op", "remove"}, {"path", "/17"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "array index 17 is out of range"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.401] array index 17 is out of range");
} }
SECTION("nonexisting target location (object)") SECTION("nonexisting target location (object)")
{ {
json j = {{"foo", 1}, {"bar", 2}}; json j = {{"foo", 1}, {"bar", 2}};
json patch = {{{"op", "remove"}, {"path", "/baz"}}}; json patch = {{{"op", "remove"}, {"path", "/baz"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.403] key 'baz' not found");
} }
SECTION("root element as target location") SECTION("root element as target location")
{ {
json j = "string"; json j = "string";
json patch = {{{"op", "remove"}, {"path", ""}}}; json patch = {{{"op", "remove"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::domain_error); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "JSON pointer has no parent"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.405] JSON pointer has no parent");
} }
} }
@ -787,40 +803,45 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "replace"}}}; json patch = {{{"op", "replace"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "replace"}, {"path", 1}}}; json patch = {{{"op", "replace"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'");
} }
SECTION("missing 'value'") SECTION("missing 'value'")
{ {
json j; json j;
json patch = {{{"op", "replace"}, {"path", ""}}}; json patch = {{{"op", "replace"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'replace' must have member 'value'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'");
} }
SECTION("nonexisting target location (array)") SECTION("nonexisting target location (array)")
{ {
json j = {1, 2, 3}; json j = {1, 2, 3};
json patch = {{{"op", "replace"}, {"path", "/17"}, {"value", 19}}}; json patch = {{{"op", "replace"}, {"path", "/17"}, {"value", 19}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "array index 17 is out of range"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.401] array index 17 is out of range");
} }
SECTION("nonexisting target location (object)") SECTION("nonexisting target location (object)")
{ {
json j = {{"foo", 1}, {"bar", 2}}; json j = {{"foo", 1}, {"bar", 2}};
json patch = {{{"op", "replace"}, {"path", "/baz"}, {"value", 3}}}; json patch = {{{"op", "replace"}, {"path", "/baz"}, {"value", 3}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.403] key 'baz' not found");
} }
} }
@ -830,48 +851,54 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "move"}}}; json patch = {{{"op", "move"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "move"}, {"path", 1}}}; json patch = {{{"op", "move"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'");
} }
SECTION("missing 'from'") SECTION("missing 'from'")
{ {
json j; json j;
json patch = {{{"op", "move"}, {"path", ""}}}; json patch = {{{"op", "move"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have member 'from'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'");
} }
SECTION("non-string 'from'") SECTION("non-string 'from'")
{ {
json j; json j;
json patch = {{{"op", "move"}, {"path", ""}, {"from", 1}}}; json patch = {{{"op", "move"}, {"path", ""}, {"from", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'move' must have string member 'from'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'");
} }
SECTION("nonexisting from location (array)") SECTION("nonexisting from location (array)")
{ {
json j = {1, 2, 3}; json j = {1, 2, 3};
json patch = {{{"op", "move"}, {"path", "/0"}, {"from", "/5"}}}; json patch = {{{"op", "move"}, {"path", "/0"}, {"from", "/5"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "array index 5 is out of range"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.401] array index 5 is out of range");
} }
SECTION("nonexisting from location (object)") SECTION("nonexisting from location (object)")
{ {
json j = {{"foo", 1}, {"bar", 2}}; json j = {{"foo", 1}, {"bar", 2}};
json patch = {{{"op", "move"}, {"path", "/baz"}, {"from", "/baz"}}}; json patch = {{{"op", "move"}, {"path", "/baz"}, {"from", "/baz"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.403] key 'baz' not found");
} }
} }
@ -881,48 +908,54 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "copy"}}}; json patch = {{{"op", "copy"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "copy"}, {"path", 1}}}; json patch = {{{"op", "copy"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'");
} }
SECTION("missing 'from'") SECTION("missing 'from'")
{ {
json j; json j;
json patch = {{{"op", "copy"}, {"path", ""}}}; json patch = {{{"op", "copy"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have member 'from'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'");
} }
SECTION("non-string 'from'") SECTION("non-string 'from'")
{ {
json j; json j;
json patch = {{{"op", "copy"}, {"path", ""}, {"from", 1}}}; json patch = {{{"op", "copy"}, {"path", ""}, {"from", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'copy' must have string member 'from'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'");
} }
SECTION("nonexisting from location (array)") SECTION("nonexisting from location (array)")
{ {
json j = {1, 2, 3}; json j = {1, 2, 3};
json patch = {{{"op", "copy"}, {"path", "/0"}, {"from", "/5"}}}; json patch = {{{"op", "copy"}, {"path", "/0"}, {"from", "/5"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "array index 5 is out of range"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.401] array index 5 is out of range");
} }
SECTION("nonexisting from location (object)") SECTION("nonexisting from location (object)")
{ {
json j = {{"foo", 1}, {"bar", 2}}; json j = {{"foo", 1}, {"bar", 2}};
json patch = {{{"op", "copy"}, {"path", "/fob"}, {"from", "/baz"}}}; json patch = {{{"op", "copy"}, {"path", "/fob"}, {"from", "/baz"}}};
CHECK_THROWS_AS(j.patch(patch), std::out_of_range); CHECK_THROWS_AS(j.patch(patch), json::out_of_range);
CHECK_THROWS_WITH(j.patch(patch), "key 'baz' not found"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.out_of_range.403] key 'baz' not found");
} }
} }
@ -932,24 +965,27 @@ TEST_CASE("JSON patch")
{ {
json j; json j;
json patch = {{{"op", "test"}}}; json patch = {{{"op", "test"}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'");
} }
SECTION("non-string 'path'") SECTION("non-string 'path'")
{ {
json j; json j;
json patch = {{{"op", "test"}, {"path", 1}}}; json patch = {{{"op", "test"}, {"path", 1}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have string member 'path'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'");
} }
SECTION("missing 'value'") SECTION("missing 'value'")
{ {
json j; json j;
json patch = {{{"op", "test"}, {"path", ""}}}; json patch = {{{"op", "test"}, {"path", ""}}};
CHECK_THROWS_AS(j.patch(patch), std::invalid_argument); CHECK_THROWS_AS(j.patch(patch), json::parse_error);
CHECK_THROWS_WITH(j.patch(patch), "operation 'test' must have member 'value'"); CHECK_THROWS_WITH(j.patch(patch),
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'");
} }
} }
} }
@ -1141,8 +1177,8 @@ TEST_CASE("JSON patch")
)"_json; )"_json;
// the test will fail // the test will fail
CHECK_THROWS_AS(doc.patch(patch), std::domain_error); CHECK_THROWS_AS(doc.patch(patch), json::other_error);
CHECK_THROWS_WITH(doc.patch(patch), "unsuccessful: " + patch[0].dump()); CHECK_THROWS_WITH(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
} }
} }
} }

View file

@ -36,20 +36,25 @@ TEST_CASE("JSON pointers")
{ {
SECTION("errors") SECTION("errors")
{ {
CHECK_THROWS_AS(json::json_pointer("foo"), std::domain_error); CHECK_THROWS_AS(json::json_pointer("foo"), json::parse_error);
CHECK_THROWS_WITH(json::json_pointer("foo"), "JSON pointer must be empty or begin with '/'"); CHECK_THROWS_WITH(json::json_pointer("foo"),
"[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'");
CHECK_THROWS_AS(json::json_pointer("/~~"), std::domain_error); CHECK_THROWS_AS(json::json_pointer("/~~"), json::parse_error);
CHECK_THROWS_WITH(json::json_pointer("/~~"), "escape error: '~' must be followed with '0' or '1'"); CHECK_THROWS_WITH(json::json_pointer("/~~"),
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
CHECK_THROWS_AS(json::json_pointer("/~"), std::domain_error); CHECK_THROWS_AS(json::json_pointer("/~"), json::parse_error);
CHECK_THROWS_WITH(json::json_pointer("/~"), "escape error: '~' must be followed with '0' or '1'"); CHECK_THROWS_WITH(json::json_pointer("/~"),
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
json::json_pointer p; json::json_pointer p;
CHECK_THROWS_AS(p.top(), std::domain_error); CHECK_THROWS_AS(p.top(), json::out_of_range);
CHECK_THROWS_WITH(p.top(), "JSON pointer has no parent"); CHECK_THROWS_WITH(p.top(),
CHECK_THROWS_AS(p.pop_back(), std::domain_error); "[json.exception.out_of_range.405] JSON pointer has no parent");
CHECK_THROWS_WITH(p.pop_back(), "JSON pointer has no parent"); CHECK_THROWS_AS(p.pop_back(), json::out_of_range);
CHECK_THROWS_WITH(p.pop_back(),
"[json.exception.out_of_range.405] JSON pointer has no parent");
} }
SECTION("examples from RFC 6901") SECTION("examples from RFC 6901")
@ -121,10 +126,12 @@ TEST_CASE("JSON pointers")
// unresolved access // unresolved access
json j_primitive = 1; json j_primitive = 1;
CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], std::out_of_range); CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], json::out_of_range);
CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer], "unresolved reference token 'foo'"); CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer],
CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), std::out_of_range); "[json.exception.out_of_range.404] unresolved reference token 'foo'");
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer), "unresolved reference token 'foo'"); CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer),
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
} }
SECTION("const access") SECTION("const access")
@ -182,15 +189,18 @@ TEST_CASE("JSON pointers")
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]); CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
// unescaped access // unescaped access
CHECK_THROWS_AS(j.at(json::json_pointer("/a/b")), std::out_of_range); CHECK_THROWS_AS(j.at(json::json_pointer("/a/b")), json::out_of_range);
CHECK_THROWS_WITH(j.at(json::json_pointer("/a/b")), "key 'a' not found"); CHECK_THROWS_WITH(j.at(json::json_pointer("/a/b")),
"[json.exception.out_of_range.403] key 'a' not found");
// unresolved access // unresolved access
const json j_primitive = 1; const json j_primitive = 1;
CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], std::out_of_range); CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], json::out_of_range);
CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer], "unresolved reference token 'foo'"); CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer],
CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), std::out_of_range); "[json.exception.out_of_range.404] unresolved reference token 'foo'");
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer), "unresolved reference token 'foo'"); CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer),
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
} }
SECTION("user-defined string literal") SECTION("user-defined string literal")
@ -245,31 +255,54 @@ TEST_CASE("JSON pointers")
CHECK(j == json({1, 13, 3, 33, nullptr, 55})); CHECK(j == json({1, 13, 3, 33, nullptr, 55}));
// error with leading 0 // error with leading 0
CHECK_THROWS_AS(j["/01"_json_pointer], std::domain_error); CHECK_THROWS_AS(j["/01"_json_pointer], json::parse_error);
CHECK_THROWS_WITH(j["/01"_json_pointer], "array index must not begin with '0'"); CHECK_THROWS_WITH(j["/01"_json_pointer],
CHECK_THROWS_AS(j_const["/01"_json_pointer], std::domain_error); "[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
CHECK_THROWS_WITH(j_const["/01"_json_pointer], "array index must not begin with '0'"); CHECK_THROWS_AS(j_const["/01"_json_pointer], json::parse_error);
CHECK_THROWS_AS(j.at("/01"_json_pointer), std::domain_error); CHECK_THROWS_WITH(j_const["/01"_json_pointer],
CHECK_THROWS_WITH(j.at("/01"_json_pointer), "array index must not begin with '0'"); "[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
CHECK_THROWS_AS(j_const.at("/01"_json_pointer), std::domain_error); CHECK_THROWS_AS(j.at("/01"_json_pointer), json::parse_error);
CHECK_THROWS_WITH(j_const.at("/01"_json_pointer), "array index must not begin with '0'"); CHECK_THROWS_WITH(j.at("/01"_json_pointer),
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
CHECK_THROWS_AS(j_const.at("/01"_json_pointer), json::parse_error);
CHECK_THROWS_WITH(j_const.at("/01"_json_pointer),
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
// error with incorrect numbers // error with incorrect numbers
CHECK_THROWS_AS(j["/one"_json_pointer] = 1, std::invalid_argument); CHECK_THROWS_AS(j["/one"_json_pointer] = 1, json::parse_error);
CHECK_THROWS_WITH(j["/one"_json_pointer] = 1,
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
CHECK_THROWS_AS(j_const["/one"_json_pointer] == 1, json::parse_error);
CHECK_THROWS_WITH(j_const["/one"_json_pointer] == 1,
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
CHECK_THROWS_AS(j.at("/one"_json_pointer) = 1, json::parse_error);
CHECK_THROWS_WITH(j.at("/one"_json_pointer) = 1,
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
CHECK_THROWS_AS(j_const.at("/one"_json_pointer) == 1, json::parse_error);
CHECK_THROWS_WITH(j_const.at("/one"_json_pointer) == 1,
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
CHECK_THROWS_AS(json({{"/list/0", 1}, {"/list/1", 2}, {"/list/three", 3}}).unflatten(), json::parse_error);
CHECK_THROWS_WITH(json({{"/list/0", 1}, {"/list/1", 2}, {"/list/three", 3}}).unflatten(),
"[json.exception.parse_error.109] parse error: array index 'three' is not a number");
// assign to "-" // assign to "-"
j["/-"_json_pointer] = 99; j["/-"_json_pointer] = 99;
CHECK(j == json({1, 13, 3, 33, nullptr, 55, 99})); CHECK(j == json({1, 13, 3, 33, nullptr, 55, 99}));
// error when using "-" in const object // error when using "-" in const object
CHECK_THROWS_AS(j_const["/-"_json_pointer], std::out_of_range); CHECK_THROWS_AS(j_const["/-"_json_pointer], json::out_of_range);
CHECK_THROWS_WITH(j_const["/-"_json_pointer], "array index '-' (3) is out of range"); CHECK_THROWS_WITH(j_const["/-"_json_pointer],
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
// error when using "-" with at // error when using "-" with at
CHECK_THROWS_AS(j.at("/-"_json_pointer), std::out_of_range); CHECK_THROWS_AS(j.at("/-"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j.at("/-"_json_pointer), "array index '-' (7) is out of range"); CHECK_THROWS_WITH(j.at("/-"_json_pointer),
CHECK_THROWS_AS(j_const.at("/-"_json_pointer), std::out_of_range); "[json.exception.out_of_range.402] array index '-' (7) is out of range");
CHECK_THROWS_WITH(j_const.at("/-"_json_pointer), "array index '-' (3) is out of range"); CHECK_THROWS_AS(j_const.at("/-"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j_const.at("/-"_json_pointer),
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
} }
SECTION("const access") SECTION("const access")
@ -282,18 +315,22 @@ TEST_CASE("JSON pointers")
CHECK(j["/2"_json_pointer] == j[2]); CHECK(j["/2"_json_pointer] == j[2]);
// assign to nonexisting index // assign to nonexisting index
CHECK_THROWS_AS(j.at("/3"_json_pointer), std::out_of_range); CHECK_THROWS_AS(j.at("/3"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j.at("/3"_json_pointer), "array index 3 is out of range"); CHECK_THROWS_WITH(j.at("/3"_json_pointer),
"[json.exception.out_of_range.401] array index 3 is out of range");
// assign to nonexisting index (with gap) // assign to nonexisting index (with gap)
CHECK_THROWS_AS(j.at("/5"_json_pointer), std::out_of_range); CHECK_THROWS_AS(j.at("/5"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j.at("/5"_json_pointer), "array index 5 is out of range"); CHECK_THROWS_WITH(j.at("/5"_json_pointer),
"[json.exception.out_of_range.401] array index 5 is out of range");
// assign to "-" // assign to "-"
CHECK_THROWS_AS(j["/-"_json_pointer], std::out_of_range); CHECK_THROWS_AS(j["/-"_json_pointer], json::out_of_range);
CHECK_THROWS_WITH(j["/-"_json_pointer], "array index '-' (3) is out of range"); CHECK_THROWS_WITH(j["/-"_json_pointer],
CHECK_THROWS_AS(j.at("/-"_json_pointer), std::out_of_range); "[json.exception.out_of_range.402] array index '-' (3) is out of range");
CHECK_THROWS_WITH(j.at("/-"_json_pointer), "array index '-' (3) is out of range"); CHECK_THROWS_AS(j.at("/-"_json_pointer), json::out_of_range);
CHECK_THROWS_WITH(j.at("/-"_json_pointer),
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
} }
} }
@ -349,17 +386,20 @@ TEST_CASE("JSON pointers")
CHECK(j_flatten.unflatten() == j); CHECK(j_flatten.unflatten() == j);
// error for nonobjects // error for nonobjects
CHECK_THROWS_AS(json(1).unflatten(), std::domain_error); CHECK_THROWS_AS(json(1).unflatten(), json::type_error);
CHECK_THROWS_WITH(json(1).unflatten(), "only objects can be unflattened"); CHECK_THROWS_WITH(json(1).unflatten(),
"[json.exception.type_error.314] only objects can be unflattened");
// error for nonprimitve values // error for nonprimitve values
CHECK_THROWS_AS(json({{"/1", {1, 2, 3}}}).unflatten(), std::domain_error); CHECK_THROWS_AS(json({{"/1", {1, 2, 3}}}).unflatten(), json::type_error);
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "values in object must be primitive"); CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(),
"[json.exception.type_error.315] values in object must be primitive");
// error for conflicting values // error for conflicting values
json j_error = {{"", 42}, {"/foo", 17}}; json j_error = {{"", 42}, {"/foo", 17}};
CHECK_THROWS_AS(j_error.unflatten(), std::domain_error); CHECK_THROWS_AS(j_error.unflatten(), json::type_error);
CHECK_THROWS_WITH(j_error.unflatten(), "invalid value to unflatten"); CHECK_THROWS_WITH(j_error.unflatten(),
"[json.exception.type_error.313] invalid value to unflatten");
// explicit roundtrip check // explicit roundtrip check
CHECK(j.flatten().unflatten() == j); CHECK(j.flatten().unflatten() == j);

View file

@ -152,8 +152,8 @@ TEST_CASE("modifiers")
SECTION("other type") SECTION("other type")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j.push_back("Hello"), std::domain_error); CHECK_THROWS_AS(j.push_back("Hello"), json::type_error);
CHECK_THROWS_WITH(j.push_back("Hello"), "cannot use push_back() with number"); CHECK_THROWS_WITH(j.push_back("Hello"), "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
@ -182,8 +182,8 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j.push_back(k), std::domain_error); CHECK_THROWS_AS(j.push_back(k), json::type_error);
CHECK_THROWS_WITH(j.push_back(k), "cannot use push_back() with number"); CHECK_THROWS_WITH(j.push_back(k), "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
} }
@ -215,9 +215,9 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error); CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), json::type_error);
CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({"one", 1})), CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({"one", 1})),
"cannot use push_back() with number"); "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
@ -252,8 +252,8 @@ TEST_CASE("modifiers")
CHECK(j == json({{"key1", 1}, {"key2", "bar"}})); CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
json k = {{"key1", 1}}; json k = {{"key1", 1}};
CHECK_THROWS_AS(k.push_back({1, 2, 3, 4}), std::domain_error); CHECK_THROWS_AS(k.push_back({1, 2, 3, 4}), json::type_error);
CHECK_THROWS_WITH(k.push_back({1, 2, 3, 4}), "cannot use push_back() with object"); CHECK_THROWS_WITH(k.push_back({1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object");
} }
} }
} }
@ -291,8 +291,9 @@ TEST_CASE("modifiers")
SECTION("other type") SECTION("other type")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j.emplace_back("Hello"), std::domain_error); CHECK_THROWS_AS(j.emplace_back("Hello"), json::type_error);
CHECK_THROWS_WITH(j.emplace_back("Hello"), "cannot use emplace_back() with number"); CHECK_THROWS_WITH(j.emplace_back("Hello"),
"[json.exception.type_error.311] cannot use emplace_back() with number");
} }
} }
@ -350,8 +351,9 @@ TEST_CASE("modifiers")
SECTION("other type") SECTION("other type")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j.emplace("foo", "bar"), std::domain_error); CHECK_THROWS_AS(j.emplace("foo", "bar"), json::type_error);
CHECK_THROWS_WITH(j.emplace("foo", "bar"), "cannot use emplace() with number"); CHECK_THROWS_WITH(j.emplace("foo", "bar"),
"[json.exception.type_error.311] cannot use emplace() with number");
} }
} }
@ -381,8 +383,8 @@ TEST_CASE("modifiers")
SECTION("other type") SECTION("other type")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j += "Hello", std::domain_error); CHECK_THROWS_AS(j += "Hello", json::type_error);
CHECK_THROWS_WITH(j += "Hello", "cannot use push_back() with number"); CHECK_THROWS_WITH(j += "Hello", "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
@ -411,8 +413,8 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j += k, std::domain_error); CHECK_THROWS_AS(j += k, json::type_error);
CHECK_THROWS_WITH(j += k, "cannot use push_back() with number"); CHECK_THROWS_WITH(j += k, "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
} }
@ -444,9 +446,9 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), std::domain_error); CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), json::type_error);
CHECK_THROWS_WITH(j += json::object_t::value_type({"one", 1}), CHECK_THROWS_WITH(j += json::object_t::value_type({"one", 1}),
"cannot use push_back() with number"); "[json.exception.type_error.308] cannot use push_back() with number");
} }
} }
@ -481,8 +483,8 @@ TEST_CASE("modifiers")
CHECK(j == json({{"key1", 1}, {"key2", "bar"}})); CHECK(j == json({{"key1", 1}, {"key2", "bar"}}));
json k = {{"key1", 1}}; json k = {{"key1", 1}};
CHECK_THROWS_AS((k += {1, 2, 3, 4}), std::domain_error); CHECK_THROWS_AS((k += {1, 2, 3, 4}), json::type_error);
CHECK_THROWS_WITH((k += {1, 2, 3, 4}), "cannot use push_back() with object"); CHECK_THROWS_WITH((k += {1, 2, 3, 4}), "[json.exception.type_error.308] cannot use push_back() with object");
} }
} }
} }
@ -617,14 +619,15 @@ TEST_CASE("modifiers")
{ {
json j_other_array2 = {"first", "second"}; json j_other_array2 = {"first", "second"};
CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
json::invalid_iterator);
CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
std::domain_error); json::invalid_iterator);
CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
"passed iterators may not belong to container"); "[json.exception.invalid_iterator.211] passed iterators may not belong to container");
CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
"iterators do not fit"); "[json.exception.invalid_iterator.210] iterators do not fit");
} }
} }
@ -663,22 +666,22 @@ TEST_CASE("modifiers")
// pass iterator to a different array // pass iterator to a different array
json j_another_array = {1, 2}; json j_another_array = {1, 2};
json j_yet_another_array = {"first", "second"}; json j_yet_another_array = {"first", "second"};
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), json::invalid_iterator);
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), json::invalid_iterator);
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), json::invalid_iterator);
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), json::invalid_iterator);
j_yet_another_array.end()), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), json::invalid_iterator);
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), std::domain_error);
CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10), "iterator does not fit current value"); CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10),
"[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value), CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value),
"iterator does not fit current value"); "[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11), CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11),
"iterator does not fit current value"); "[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()),
j_yet_another_array.end()), "iterator does not fit current value"); "[json.exception.invalid_iterator.202] iterator does not fit current value");
CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}),
"iterator does not fit current value"); "[json.exception.invalid_iterator.202] iterator does not fit current value");
} }
SECTION("non-array type") SECTION("non-array type")
@ -686,20 +689,20 @@ TEST_CASE("modifiers")
// call insert on a non-array type // call insert on a non-array type
json j_nonarray = 3; json j_nonarray = 3;
json j_yet_another_array = {"first", "second"}; json j_yet_another_array = {"first", "second"};
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), std::domain_error); CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), json::type_error);
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), std::domain_error); CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), json::type_error);
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), std::domain_error); CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), json::type_error);
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(), CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
j_yet_another_array.end()), std::domain_error); j_yet_another_array.end()), json::type_error);
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), std::domain_error); CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), json::type_error);
CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), "cannot use insert() with number"); CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), "[json.exception.type_error.309] cannot use insert() with number");
CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), "cannot use insert() with number"); CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), "[json.exception.type_error.309] cannot use insert() with number");
CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), "cannot use insert() with number"); CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), "[json.exception.type_error.309] cannot use insert() with number");
CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(), CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
j_yet_another_array.end()), "cannot use insert() with number"); j_yet_another_array.end()), "[json.exception.type_error.309] cannot use insert() with number");
CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}),
"cannot use insert() with number"); "[json.exception.type_error.309] cannot use insert() with number");
} }
} }
@ -751,8 +754,8 @@ TEST_CASE("modifiers")
json j = 17; json j = 17;
json::array_t a = {"foo", "bar", "baz"}; json::array_t a = {"foo", "bar", "baz"};
CHECK_THROWS_AS(j.swap(a), std::domain_error); CHECK_THROWS_AS(j.swap(a), json::type_error);
CHECK_THROWS_WITH(j.swap(a), "cannot use swap() with number"); CHECK_THROWS_WITH(j.swap(a), "[json.exception.type_error.310] cannot use swap() with number");
} }
} }
@ -777,8 +780,8 @@ TEST_CASE("modifiers")
json j = 17; json j = 17;
json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}}; json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
CHECK_THROWS_AS(j.swap(o), std::domain_error); CHECK_THROWS_AS(j.swap(o), json::type_error);
CHECK_THROWS_WITH(j.swap(o), "cannot use swap() with number"); CHECK_THROWS_WITH(j.swap(o), "[json.exception.type_error.310] cannot use swap() with number");
} }
} }
@ -803,8 +806,8 @@ TEST_CASE("modifiers")
json j = 17; json j = 17;
json::string_t s = "Hallo Welt"; json::string_t s = "Hallo Welt";
CHECK_THROWS_AS(j.swap(s), std::domain_error); CHECK_THROWS_AS(j.swap(s), json::type_error);
CHECK_THROWS_WITH(j.swap(s), "cannot use swap() with number"); CHECK_THROWS_WITH(j.swap(s), "[json.exception.type_error.310] cannot use swap() with number");
} }
} }
} }

View file

@ -1016,6 +1016,90 @@ TEST_CASE("MessagePack")
json j = json::from_msgpack(given); json j = json::from_msgpack(given);
CHECK(j.get<double>() == Approx(25.0000019073486)); CHECK(j.get<double>() == Approx(25.0000019073486));
} }
SECTION("errors")
{
SECTION("too short byte vector")
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcc})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcd})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
}
SECTION("unsupported bytes")
{
SECTION("concrete examples")
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xc1");
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xc6");
}
SECTION("all unsupported bytes")
{
for (auto byte :
{
// never used
0xc1,
// bin
0xc4, 0xc5, 0xc6,
// ext
0xc7, 0xc8, 0xc9,
// fixext
0xd4, 0xd5, 0xd6, 0xd7, 0xd8
})
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error);
}
}
}
}
} }
@ -1116,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_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_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_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_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_minus_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json", "test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
@ -1128,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_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_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_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_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_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_int.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json", "test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",

View file

@ -33,6 +33,7 @@ SOFTWARE.
using nlohmann::json; using nlohmann::json;
#include <fstream> #include <fstream>
#include <list>
TEST_CASE("regression tests") TEST_CASE("regression tests")
{ {
@ -49,6 +50,7 @@ TEST_CASE("regression tests")
SECTION("issue #70 - Handle infinity and NaN cases") SECTION("issue #70 - Handle infinity and NaN cases")
{ {
/*
SECTION("NAN value") SECTION("NAN value")
{ {
CHECK(json(NAN) == json()); CHECK(json(NAN) == json());
@ -60,6 +62,36 @@ TEST_CASE("regression tests")
CHECK(json(INFINITY) == json()); CHECK(json(INFINITY) == json());
CHECK(json(json::number_float_t(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") SECTION("pull request #71 - handle enum type")
@ -429,16 +461,6 @@ TEST_CASE("regression tests")
{ {
setlocale(LC_NUMERIC, "de_DE.UTF-8"); setlocale(LC_NUMERIC, "de_DE.UTF-8");
// Verify that snprintf uses special decimal and grouping characters.
// Disabled, because can't trigger locale-specific behavior in AppVeyor
#ifndef _MSC_VER
{
std::array<char, 64> buf;
std::snprintf(buf.data(), buf.size(), "%.2f", 12345.67);
CHECK(strcmp(buf.data(), "12345,67") == 0);
}
#endif
// verify that dumped correctly with '.' and no grouping // verify that dumped correctly with '.' and no grouping
const json j1 = 12345.67; const json j1 = 12345.67;
CHECK(json(12345.67).dump() == "12345.67"); CHECK(json(12345.67).dump() == "12345.67");
@ -449,18 +471,6 @@ TEST_CASE("regression tests")
{ {
setlocale(LC_NUMERIC, "de_DE.UTF-8"); setlocale(LC_NUMERIC, "de_DE.UTF-8");
// disabled, because locale-specific beharivor is not
// triggered in AppVeyor for some reason
#ifndef _MSC_VER
{
// verify that strtod now uses commas as decimal-separator
CHECK(std::strtod("3,14", nullptr) == 3.14);
// verify that strtod does not understand dots as decimal separator
CHECK(std::strtod("3.14", nullptr) == 3);
}
#endif
// verify that parsed correctly despite using strtod internally // verify that parsed correctly despite using strtod internally
CHECK(json::parse("3.14").get<double>() == 3.14); CHECK(json::parse("3.14").get<double>() == 3.14);
@ -559,14 +569,16 @@ TEST_CASE("regression tests")
SECTION("issue #329 - serialized value not always can be parsed") SECTION("issue #329 - serialized value not always can be parsed")
{ {
json j = json::parse("22e2222"); CHECK_THROWS_AS(json::parse("22e2222"), json::out_of_range);
CHECK(j == json()); CHECK_THROWS_WITH(json::parse("22e2222"),
"[json.exception.out_of_range.406] number overflow parsing '22e2222'");
} }
SECTION("issue #366 - json::parse on failed stream gets stuck") SECTION("issue #366 - json::parse on failed stream gets stuck")
{ {
std::ifstream f("file_not_found.json"); std::ifstream f("file_not_found.json");
CHECK_THROWS_AS(json::parse(f), std::invalid_argument); CHECK_THROWS_AS(json::parse(f), json::parse_error);
CHECK_THROWS_WITH(json::parse(f), "[json.exception.parse_error.111] parse error: bad input stream");
} }
SECTION("issue #367 - calling stream at EOF") SECTION("issue #367 - calling stream at EOF")
@ -580,8 +592,9 @@ TEST_CASE("regression tests")
// ss is not at EOF; this yielded an error before the fix // ss is not at EOF; this yielded an error before the fix
// (threw basic_string::append). No, it should just throw // (threw basic_string::append). No, it should just throw
// a parse error because of the EOF. // a parse error because of the EOF.
CHECK_THROWS_AS(j << ss, std::invalid_argument); CHECK_THROWS_AS(j << ss, json::parse_error);
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); CHECK_THROWS_WITH(j << ss,
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected end of input");
} }
SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)") SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
@ -612,37 +625,51 @@ TEST_CASE("regression tests")
{ {
// original test case // original test case
std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21}; std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.110] parse error at 2: cannot read 5 bytes from vector");
} }
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)") SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
{ {
// original test case: incomplete float64 // original test case: incomplete float64
std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a}; std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_msgpack(vec1), std::out_of_range); CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(vec1),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
// related test case: incomplete float32 // related test case: incomplete float32
std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a}; std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range); CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(vec2),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
// related test case: incomplete Half-Precision Float (CBOR) // related test case: incomplete Half-Precision Float (CBOR)
std::vector<uint8_t> vec3 {0xf9, 0x8f}; std::vector<uint8_t> vec3 {0xf9, 0x8f};
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
// related test case: incomplete Single-Precision Float (CBOR) // related test case: incomplete Single-Precision Float (CBOR)
std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a}; std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_cbor(vec4), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec4),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
// related test case: incomplete Double-Precision Float (CBOR) // related test case: incomplete Double-Precision Float (CBOR)
std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a}; std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_cbor(vec5), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec5),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
} }
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)") SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
{ {
// original test case // original test case
std::vector<uint8_t> vec1 {0x87}; std::vector<uint8_t> vec1 {0x87};
CHECK_THROWS_AS(json::from_msgpack(vec1), std::out_of_range); CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(vec1),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
// more test cases for MessagePack // more test cases for MessagePack
for (auto b : for (auto b :
@ -654,7 +681,7 @@ TEST_CASE("regression tests")
}) })
{ {
std::vector<uint8_t> vec(1, static_cast<uint8_t>(b)); std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
CHECK_THROWS_AS(json::from_msgpack(vec), std::out_of_range); CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error);
} }
// more test cases for CBOR // more test cases for CBOR
@ -669,28 +696,38 @@ TEST_CASE("regression tests")
}) })
{ {
std::vector<uint8_t> vec(1, static_cast<uint8_t>(b)); std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
} }
// special case: empty input // special case: empty input
std::vector<uint8_t> vec2; std::vector<uint8_t> vec2;
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range); CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(vec2),
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
} }
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)") SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
{ {
// original test case: empty UTF-8 string (indefinite length) // original test case: empty UTF-8 string (indefinite length)
std::vector<uint8_t> vec1 {0x7f}; std::vector<uint8_t> vec1 {0x7f};
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
// related test case: empty array (indefinite length) // related test case: empty array (indefinite length)
std::vector<uint8_t> vec2 {0x9f}; std::vector<uint8_t> vec2 {0x9f};
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
// related test case: empty map (indefinite length) // related test case: empty map (indefinite length)
std::vector<uint8_t> vec3 {0xbf}; std::vector<uint8_t> vec3 {0xbf};
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
} }
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)") SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
@ -716,19 +753,27 @@ TEST_CASE("regression tests")
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
}; };
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.110] parse error at 137: cannot read 1 bytes from vector");
// related test case: nonempty UTF-8 string (indefinite length) // related test case: nonempty UTF-8 string (indefinite length)
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61}; std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.110] parse error at 4: cannot read 1 bytes from vector");
// related test case: nonempty array (indefinite length) // related test case: nonempty array (indefinite length)
std::vector<uint8_t> vec2 {0x9f, 0x01}; std::vector<uint8_t> vec2 {0x9f, 0x01};
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at 3: cannot read 1 bytes from vector");
// related test case: nonempty map (indefinite length) // related test case: nonempty map (indefinite length)
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01}; std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at 5: cannot read 1 bytes from vector");
} }
SECTION("issue #414 - compare with literal 0)") SECTION("issue #414 - compare with literal 0)")
@ -761,7 +806,9 @@ TEST_CASE("regression tests")
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61, 0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
}; };
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.110] parse error at 49: cannot read 4 bytes from vector");
// related test case: double-precision // related test case: double-precision
std::vector<uint8_t> vec2 std::vector<uint8_t> vec2
@ -773,13 +820,15 @@ TEST_CASE("regression tests")
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61, 0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
}; };
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at 49: cannot read 8 bytes from vector");
} }
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)") SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
{ {
std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'}; std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'};
CHECK_THROWS_AS(json::parse(vec), std::invalid_argument); CHECK_THROWS_AS(json::parse(vec), json::parse_error);
} }
SECTION("issue #454 - doubles are printed as integers") SECTION("issue #454 - doubles are printed as integers")
@ -797,6 +846,62 @@ TEST_CASE("regression tests")
CHECK(s1 == s2); 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
std::map<json::value_t, std::string> jsonTypes ;
jsonTypes[json::value_t::array] = "array";
}
SECTION("issue #494 - conversion from vector<bool> to json fails to build") SECTION("issue #494 - conversion from vector<bool> to json fails to build")
{ {
std::vector<bool> boolVector = {false, true, false, false}; std::vector<bool> boolVector = {false, true, false, false};
@ -836,4 +941,24 @@ TEST_CASE("regression tests")
CHECK_THROWS_AS(l.fill_line_buffer(), std::invalid_argument); CHECK_THROWS_AS(l.fill_line_buffer(), std::invalid_argument);
} }
} }
SECTION("issue #504 - assertion error (OSS-Fuzz 856)")
{
std::vector<uint8_t> vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};
json j1 = json::from_cbor(vec1);
// step 2: round trip
std::vector<uint8_t> vec2 = json::to_cbor(j1);
// parse serialization
json j2 = json::from_cbor(vec2);
// NaN is dumped to "null"
CHECK(j2.is_number_float());
CHECK(std::isnan(j2.get<json::number_float_t>()));
CHECK(j2.dump() == "null");
// check if serializations match
CHECK(json::to_cbor(j2) == vec2);
}
} }

View file

@ -79,7 +79,7 @@ TEST_CASE("compliance tests from json.org")
CAPTURE(filename); CAPTURE(filename);
json j; json j;
std::ifstream f(filename); std::ifstream f(filename);
CHECK_THROWS_AS(j << f, std::invalid_argument); CHECK_THROWS_AS(j << f, json::parse_error);
} }
} }
@ -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_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_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_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_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_minus_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.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_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_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_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_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_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_int.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json", "test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
@ -757,7 +754,7 @@ TEST_CASE("nst's JSONTestSuite")
CAPTURE(filename); CAPTURE(filename);
std::ifstream f(filename); std::ifstream f(filename);
json j; json j;
CHECK_THROWS_AS(j << f, std::invalid_argument); CHECK_THROWS_AS(j << f, json::parse_error);
} }
} }
@ -765,9 +762,6 @@ TEST_CASE("nst's JSONTestSuite")
{ {
for (auto filename : 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 // we do not pose a limit on nesting
"test/data/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json", "test/data/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json",
// we silently ignore BOMs // 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, json::out_of_range);
}
}
SECTION("i -> n") SECTION("i -> n")
{ {
for (auto filename : for (auto filename :
@ -810,7 +824,7 @@ TEST_CASE("nst's JSONTestSuite")
CAPTURE(filename); CAPTURE(filename);
std::ifstream f(filename); std::ifstream f(filename);
json j; json j;
CHECK_THROWS_AS(j << f, std::invalid_argument); CHECK_THROWS_AS(j << f, json::parse_error);
} }
} }
} }

View file

@ -38,6 +38,9 @@ TEST_CASE("Unicode", "[hide]")
{ {
SECTION("full enumeration of Unicode code points") SECTION("full enumeration of Unicode code points")
{ {
// lexer to call to_unicode on
json::lexer dummy_lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(""), 0);
// create an escaped string from a code point // create an escaped string from a code point
const auto codepoint_to_unicode = [](std::size_t cp) const auto codepoint_to_unicode = [](std::size_t cp)
{ {
@ -85,7 +88,7 @@ TEST_CASE("Unicode", "[hide]")
// they are checked with codepoint_to_unicode. // they are checked with codepoint_to_unicode.
if (cp > 0x1f and cp != 0x22 and cp != 0x5c) if (cp > 0x1f and cp != 0x22 and cp != 0x5c)
{ {
unescaped_string = json::lexer::to_unicode(cp); unescaped_string = dummy_lexer.to_unicode(cp);
} }
} }
else else
@ -97,7 +100,7 @@ TEST_CASE("Unicode", "[hide]")
const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu); const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu);
escaped_string = codepoint_to_unicode(codepoint1); escaped_string = codepoint_to_unicode(codepoint1);
escaped_string += codepoint_to_unicode(codepoint2); escaped_string += codepoint_to_unicode(codepoint2);
unescaped_string += json::lexer::to_unicode(codepoint1, codepoint2); unescaped_string += dummy_lexer.to_unicode(codepoint1, codepoint2);
} }
// all other code points are valid and must not yield parse errors // all other code points are valid and must not yield parse errors
@ -170,7 +173,7 @@ TEST_CASE("Unicode", "[hide]")
SECTION("error for incomplete/wrong BOM") SECTION("error for incomplete/wrong BOM")
{ {
CHECK_THROWS_AS(json::parse("\xef\xbb"), std::invalid_argument); CHECK_THROWS_AS(json::parse("\xef\xbb"), json::parse_error);
CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), std::invalid_argument); CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), json::parse_error);
} }
} }