From 53c9564c51ecd0c84b597a37813a21a01900ab83 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 11 Feb 2015 14:58:52 +0100 Subject: [PATCH] bug fix and test cases --- src/json.hpp | 3 +- src/json.hpp.re2c | 3 +- test/unit.cpp | 266 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 269 insertions(+), 3 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index dccf768af..57b8de5b4 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -256,6 +256,8 @@ class basic_json std::enable_if< not std::is_same::value and not std::is_same::value and + not std::is_same::value and + not std::is_same::value and std::is_constructible::value, int>::type = 0> inline basic_json(const V& value) @@ -1678,7 +1680,6 @@ class basic_json /// copy assignment inline iterator& operator=(const iterator& other) noexcept { - assert(false); // not sure if function will ever be called m_object = other.m_object; m_it = other.m_it; return *this; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 63e7e1d5c..a7b3622a3 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -256,6 +256,8 @@ class basic_json std::enable_if< not std::is_same::value and not std::is_same::value and + not std::is_same::value and + not std::is_same::value and std::is_constructible::value, int>::type = 0> inline basic_json(const V& value) @@ -1678,7 +1680,6 @@ class basic_json /// copy assignment inline iterator& operator=(const iterator& other) noexcept { - assert(false); // not sure if function will ever be called m_object = other.m_object; m_it = other.m_it; return *this; diff --git a/test/unit.cpp b/test/unit.cpp index fbbc58ea2..00e49168e 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -3912,13 +3912,275 @@ TEST_CASE("deserialization") ss >> j; CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); } - + SECTION("user-defined string literal") { CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}})); } } +TEST_CASE("iterator class") +{ + SECTION("initialization") + { + SECTION("constructor with object") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it(&j); + } + + SECTION("object") + { + json j(json::value_t::object); + json::iterator it(&j); + } + + SECTION("array") + { + json j(json::value_t::array); + json::iterator it(&j); + } + } + + SECTION("copy assignment") + { + json j(json::value_t::null); + json::iterator it(&j); + json::iterator it2(&j); + it2 = it; + } + + SECTION("set_begin") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it(&j); + it.set_begin(); + CHECK(it == j.begin()); + } + + SECTION("object") + { + json j(json::value_t::object); + json::iterator it(&j); + it.set_begin(); + CHECK(it == j.begin()); + } + + SECTION("array") + { + json j(json::value_t::array); + json::iterator it(&j); + it.set_begin(); + CHECK(it == j.begin()); + } + } + + SECTION("set_end") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it(&j); + it.set_end(); + CHECK(it == j.end()); + } + + SECTION("object") + { + json j(json::value_t::object); + json::iterator it(&j); + it.set_end(); + CHECK(it == j.end()); + } + + SECTION("array") + { + json j(json::value_t::array); + json::iterator it(&j); + it.set_end(); + CHECK(it == j.end()); + } + } + } + + SECTION("element access") + { + SECTION("operator*") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it = j.begin(); + CHECK_THROWS_AS(*it, std::out_of_range); + } + + SECTION("number") + { + json j(17); + json::iterator it = j.begin(); + CHECK(*it == json(17)); + it = j.end(); + CHECK_THROWS_AS(*it, std::out_of_range); + } + + SECTION("object") + { + json j({{"foo", "bar"}}); + json::iterator it = j.begin(); + CHECK(*it == json("bar")); + } + + SECTION("array") + { + json j({1, 2, 3, 4}); + json::iterator it = j.begin(); + CHECK(*it == json(1)); + } + } + + SECTION("operator->") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it = j.begin(); + CHECK_THROWS_AS(it->type_name(), std::out_of_range); + } + + SECTION("number") + { + json j(17); + json::iterator it = j.begin(); + CHECK(it->type_name() == "number"); + it = j.end(); + CHECK_THROWS_AS(it->type_name(), std::out_of_range); + } + + SECTION("object") + { + json j({{"foo", "bar"}}); + json::iterator it = j.begin(); + CHECK(it->type_name() == "string"); + } + + SECTION("array") + { + json j({1, 2, 3, 4}); + json::iterator it = j.begin(); + CHECK(it->type_name() == "number"); + } + } + } + + SECTION("increment/decrement") + { + SECTION("post-increment") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it = j.begin(); + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::end); + it++; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::invalid); + } + + SECTION("number") + { + json j(17); + json::iterator it = j.begin(); + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::begin); + it++; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::end); + it++; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::invalid); + } + + SECTION("object") + { + json j({{"foo", "bar"}}); + json::iterator it = j.begin(); + CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin()); + it++; + CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end()); + } + + SECTION("array") + { + json j({1, 2, 3, 4}); + json::iterator it = j.begin(); + CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin()); + it++; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + it++; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + it++; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + it++; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end()); + } + } + + SECTION("pre-increment") + { + SECTION("null") + { + json j(json::value_t::null); + json::iterator it = j.begin(); + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::end); + ++it; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::invalid); + } + + SECTION("number") + { + json j(17); + json::iterator it = j.begin(); + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::begin); + ++it; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::end); + ++it; + CHECK(it.m_it.generic_iterator == json::generic_iterator_value::invalid); + } + + SECTION("object") + { + json j({{"foo", "bar"}}); + json::iterator it = j.begin(); + CHECK(it.m_it.object_iterator == it.m_object->m_value.object->begin()); + ++it; + CHECK(it.m_it.object_iterator == it.m_object->m_value.object->end()); + } + + SECTION("array") + { + json j({1, 2, 3, 4}); + json::iterator it = j.begin(); + CHECK(it.m_it.array_iterator == it.m_object->m_value.array->begin()); + ++it; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + ++it; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + ++it; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->end()); + ++it; + CHECK(it.m_it.array_iterator != it.m_object->m_value.array->begin()); + CHECK(it.m_it.array_iterator == it.m_object->m_value.array->end()); + } + } + } +} TEST_CASE("convenience functions") { @@ -4202,6 +4464,8 @@ TEST_CASE("parser class") CHECK_THROWS_AS(json::parser("-").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("--").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("-0.").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("-.").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("0.:").parse(), std::invalid_argument); // unexpected end of null CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument);