Unverified Commit 63c2c62f authored by Niels Lohmann's avatar Niels Lohmann

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

Also merged develop into this feature branch.
parents 4e498298 95474e42
......@@ -78,13 +78,13 @@ matrix:
env:
- COMPILER=g++-4.9
- SPECIAL=no_exceptions
- TEST_PATTERN=-e \"*\"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: [g++-4.9, cppcheck]
before_script:
- CPPFLAGS="-DJSON_NOEXCEPTION" make
after_success:
- make clean
- CPPFLAGS="-DJSON_NOEXCEPTION" make check TEST_PATTERN="-e \"*\""
# Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/)
......
......@@ -49,6 +49,7 @@ doctest:
# -Wno-documentation-unknown-command: code uses user-defined commands like @complexity
# -Wno-exit-time-destructors: warning in Catch code
# -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...)"
pedantic:
$(MAKE) json_unit CXXFLAGS="\
......@@ -58,6 +59,7 @@ pedantic:
-Wno-documentation-unknown-command \
-Wno-exit-time-destructors \
-Wno-keyword-macro \
-Wno-weak-vtables \
-Wno-range-loop-analysis"
......
......@@ -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@&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
cd html ; ../scripts/git-update-ghpages nlohmann/json
......
......@@ -21,13 +21,27 @@ int main()
// output changed array
std::cout << object << '\n';
// try to write at a nonexisting key
// exception type_error.304
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";
}
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/tb5CaFfsMWpAvi7m"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/8ldtT0NOhidn0fOA"><b>online</b></a>
\ No newline at end of file
"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
"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
......@@ -15,12 +15,26 @@ int main()
// output element with key "the ugly"
std::cout << object.at("the ugly") << '\n';
// try to read from a nonexisting key
// exception type_error.304
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';
}
catch (std::out_of_range)
catch (json::out_of_range)
{
std::cout << "out of range" << '\n';
}
......
<a target="_blank" href="http://melpon.org/wandbox/permlink/NFG86H5khRUePc1s"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/nfmFWMaJJHFJ7eVK"><b>online</b></a>
\ No newline at end of file
"il brutto"
[json.exception.type_error.304] cannot use at() with string
out of range
......@@ -16,13 +16,27 @@ int main()
// output changed array
std::cout << array << '\n';
// try to write beyond the array limit
// exception type_error.304
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";
}
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/R7z2SB2rMdFQ9XtR"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/8UnQY256zGX2Lx6d"><b>online</b></a>
\ No newline at end of file
"third"
["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
......@@ -5,18 +5,32 @@ using json = nlohmann::json;
int main()
{
// create JSON array
json array = {"first", "2nd", "third", "fourth"};
const json array = {"first", "2nd", "third", "fourth"};
// output element at index 2 (third element)
std::cout << array.at(2) << '\n';
// try to read beyond the array limit
// exception type_error.304
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';
}
catch (std::out_of_range)
catch (json::out_of_range& e)
{
std::cout << "out of range" << '\n';
std::cout << e.what() << '\n';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/L1bMeiN6nYm7JrvA"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/U1fv6LY7xZOAuSBs"><b>online</b></a>
\ No newline at end of file
"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
......@@ -32,4 +32,60 @@ int main()
j.at("/array/1"_json_pointer) = 21;
// output the changed array
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/NDSjglHZIjIZ0Uxg"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/Fy2xBfZMols2DUQC"><b>online</b></a>
\ No newline at end of file
......@@ -4,3 +4,8 @@
2
"bar"
[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'
......@@ -5,7 +5,7 @@ using json = nlohmann::json;
int main()
{
// create a JSON value
json j =
const json j =
{
{"number", 1}, {"string", "foo"}, {"array", {1, 2}}
};
......@@ -20,4 +20,48 @@ int main()
std::cout << j.at("/array"_json_pointer) << '\n';
// output element with JSON pointer "/array/1"
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/OuLYiMJ3pgyOHupb"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/WxhV3mL9YX8FJonk"><b>online</b></a>
\ No newline at end of file
......@@ -2,3 +2,7 @@
"foo"
[1,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'
......@@ -5,7 +5,6 @@ using json = nlohmann::json;
int main()
{
// create JSON values
json j_null;
json j_boolean = true;
json j_number_integer = 17;
json j_number_float = 23.42;
......@@ -16,7 +15,6 @@ int main()
json j_string = "Hello, world";
// call back()
//std::cout << j_null.back() << '\n'; // would throw
std::cout << j_boolean.back() << '\n';
std::cout << j_number_integer.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_empty.back() << '\n'; // undefined behavior
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/nPVnBcHf8nrNpGOJ"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/CAv4NNr4D1FJhhUv"><b>online</b></a>
\ No newline at end of file
......@@ -4,3 +4,4 @@ true
2
16
"Hello, world"
[json.exception.invalid_iterator.214] cannot get value
......@@ -18,4 +18,14 @@ int main()
std::cout << j_array_range << '\n';
std::cout << j_number_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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/nKF1QcieoCHm6Lez"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/oUU2X0pbZq7gawRB"><b>online</b></a>
\ No newline at end of file
["bravo","charly"]
42
{"one":"eins"}
[json.exception.invalid_iterator.204] iterators out of range
......@@ -19,7 +19,7 @@ int main()
{
auto r3 = value.get_ref<json::number_float_t&>();
}
catch (std::domain_error& ex)
catch (json::type_error& ex)
{
std::cout << ex.what() << '\n';
}
......
<a target="_blank" href="http://melpon.org/wandbox/permlink/WiO1oBWDvIs82OX1"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/lsl8Ex3d3SOYnKHu"><b>online</b></a>
\ No newline at end of file
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
17 17
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number
......@@ -19,9 +19,9 @@ int main()
{
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
......@@ -29,9 +29,9 @@ int main()
{
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
......@@ -39,8 +39,8 @@ int main()
{
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/WM2WWKnXdmdw17Wu"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/Wlvqfd3JpEXTv2iH"><b>online</b></a>
\ No newline at end of file
domain_error: JSON pointer must be empty or begin with '/'
domain_error: escape error: '~' must be followed with '0' or '1'
domain_error: escape error: '~' must be followed with '0' or '1'
[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'
[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'
......@@ -8,10 +8,20 @@ int main()
json j_no_init_list = json::object();
json j_empty_init_list = json::object({});
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
std::cout << j_no_init_list << '\n';
std::cout << j_empty_init_list << '\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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/hhxRaUctq3FA54SW"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/Ub9U5AMbng3oZiao"><b>online</b></a>
\ No newline at end of file
{}
{}
{"one":1,"two":2}
[json.exception.type_error.301] cannot create object from initializer list
......@@ -46,4 +46,14 @@ int main()
{
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';
}
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/rUGX6AaVuZfwiiYI"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/drFSKFXJd8IMzMK3"><b>online</b></a>
\ No newline at end of file
......@@ -9,3 +9,4 @@ number: {"floating-point":17.23,"integer":42}
null: null
boolean: true
array: [1,2,3,4,5]
[json.exception.type_error.302] type must be boolean, but is string
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -41,26 +41,22 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// parse serialization
json j2 = json::from_cbor(vec2);
// deserializations must match
assert(j1 == j2);
// serializations must match
assert(json::to_cbor(j2) == vec2);
}
catch (const std::invalid_argument&)
catch (const json::parse_error&)
{
// parsing a CBOR serialization must not fail
assert(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&)
catch (const json::type_error&)
{
// 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
// type errors can occur during parsing, too
}
// return 0 - non-zero return values are reserved for future use
......
......@@ -49,13 +49,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// serializations must match
assert(s1 == s2);
}
catch (const std::invalid_argument&)
catch (const json::parse_error&)
{
// parsing a JSON serialization must not fail
assert(false);
}
}
catch (const std::invalid_argument&)
catch (const json::parse_error&)
{
// parse errors are ok, because input may be random bytes
}
......
......@@ -44,23 +44,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// deserializations must match
assert(j1 == j2);
}
catch (const std::invalid_argument&)
catch (const json::parse_error&)
{
// parsing a MessagePack serialization must not fail
assert(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&)
catch (const json::type_error&)
{
// 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
// type errors can occur during parsing, too
}
// return 0 - non-zero return values are reserved for future use
......
......@@ -240,8 +240,9 @@ TEST_CASE("algorithms")
SECTION("sorting an object")
{
json j({{"one", 1}, {"two", 2}});
CHECK_THROWS_AS(std::sort(j.begin(), j.end()), std::domain_error);
CHECK_THROWS_WITH(std::sort(j.begin(), j.end()), "cannot use offsets with object iterators");
CHECK_THROWS_AS(std::sort(j.begin(), j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(std::sort(j.begin(), j.end()),
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
}
}
......
This diff is collapsed.
......@@ -147,8 +147,8 @@ TEST_CASE("const_iterator class")
{
json j(json::value_t::null);
json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(*it, std::out_of_range);
CHECK_THROWS_WITH(*it, "cannot get value");
CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("number")
......@@ -157,8 +157,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin();
CHECK(*it == json(17));
it = j.cend();
CHECK_THROWS_AS(*it, std::out_of_range);
CHECK_THROWS_WITH(*it, "cannot get value");
CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("object")
......@@ -182,8 +182,8 @@ TEST_CASE("const_iterator class")
{
json j(json::value_t::null);
json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range);
CHECK_THROWS_WITH(it->type_name(), "cannot get value");
CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("number")
......@@ -192,8 +192,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin();
CHECK(it->type_name() == "number");
it = j.cend();
CHECK_THROWS_AS(it->type_name(), std::out_of_range);
CHECK_THROWS_WITH(it->type_name(), "cannot get value");
CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("object")
......
......@@ -131,8 +131,8 @@ TEST_CASE("iterator class")
{
json j(json::value_t::null);
json::iterator it = j.begin();
CHECK_THROWS_AS(*it, std::out_of_range);
CHECK_THROWS_WITH(*it, "cannot get value");
CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("number")
......@@ -141,8 +141,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin();
CHECK(*it == json(17));
it = j.end();
CHECK_THROWS_AS(*it, std::out_of_range);
CHECK_THROWS_WITH(*it, "cannot get value");
CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("object")
......@@ -166,8 +166,8 @@ TEST_CASE("iterator class")
{
json j(json::value_t::null);
json::iterator it = j.begin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range);
CHECK_THROWS_WITH(it->type_name(), "cannot get value");
CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("number")
......@@ -176,8 +176,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin();
CHECK(it->type_name() == "number");
it = j.end();
CHECK_THROWS_AS(it->type_name(), std::out_of_range);
CHECK_THROWS_WITH(it->type_name(), "cannot get value");
CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
}
SECTION("object")
......
......@@ -190,8 +190,10 @@ TEST_CASE("lexer class")
SECTION("to_unicode")
{
CHECK(json::lexer::to_unicode(0x1F4A9) == "💩");
CHECK_THROWS_AS(json::lexer::to_unicode(0x200000), std::out_of_range);
CHECK_THROWS_WITH(json::lexer::to_unicode(0x200000), "code points above 0x10FFFF are invalid");
// lexer to call to_unicode on
json::lexer dummy_lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(""), 0);
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");
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -90,15 +90,17 @@ TEST_CASE("deserialization")
std::stringstream ss1, ss2;
ss1 << "[\"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_WITH(json::parse(ss2), "parse error - unexpected end of input; expected ']'");
CHECK_THROWS_AS(json::parse(ss1), json::parse_error);
CHECK_THROWS_WITH(json::parse(ss2),
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
}
SECTION("string")
{
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(s), std::invalid_argument);
CHECK_THROWS_WITH(json::parse(s), "parse error - unexpected end of input; expected ']'");
CHECK_THROWS_AS(json::parse(s), json::parse_error);
CHECK_THROWS_WITH(json::parse(s),
"[json.exception.parse_error.101] parse error at 29: parse error - unexpected end of input; expected ']'");
}
SECTION("operator<<")
......@@ -107,8 +109,9 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j;
CHECK_THROWS_AS(j << ss1, std::invalid_argument);
CHECK_THROWS_WITH(j << ss2, "parse error - unexpected end of input; expected ']'");
CHECK_THROWS_AS(j << ss1, json::parse_error);
CHECK_THROWS_WITH(j << ss2,
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
}
SECTION("operator>>")
......@@ -117,15 +120,16 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j;
CHECK_THROWS_AS(ss1 >> j, std::invalid_argument);
CHECK_THROWS_WITH(ss2 >> j, "parse error - unexpected end of input; expected ']'");
CHECK_THROWS_AS(ss1 >> j, json::parse_error);
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")
{
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,
"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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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")
{
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);
}
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1016,6 +1016,90 @@ TEST_CASE("MessagePack")
json j = json::from_msgpack(given);
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_double_close_to_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
//"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
......@@ -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_fraction_exponent.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
//"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
//"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
......
This diff is collapsed.
This diff is collapsed.
......@@ -38,6 +38,9 @@ TEST_CASE("Unicode", "[hide]")
{
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
const auto codepoint_to_unicode = [](std::size_t cp)
{
......@@ -85,7 +88,7 @@ TEST_CASE("Unicode", "[hide]")
// they are checked with codepoint_to_unicode.
if (cp > 0x1f and cp != 0x22 and cp != 0x5c)
{
unescaped_string = json::lexer::to_unicode(cp);
unescaped_string = dummy_lexer.to_unicode(cp);
}
}
else
......@@ -97,7 +100,7 @@ TEST_CASE("Unicode", "[hide]")
const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu);
escaped_string = codepoint_to_unicode(codepoint1);
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
......@@ -170,7 +173,7 @@ TEST_CASE("Unicode", "[hide]")
SECTION("error for incomplete/wrong BOM")
{
CHECK_THROWS_AS(json::parse("\xef\xbb"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), std::invalid_argument);
CHECK_THROWS_AS(json::parse("\xef\xbb"), json::parse_error);
CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), json::parse_error);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment