Skip to content

Commit

Permalink
json_reference_arg tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Nov 19, 2024
1 parent b00582b commit b885214
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 26 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ constructed value with the key if no such key already exists.
a const reference to the value that is associated with key, returning a const reference to a default
constructed value with static storage duration if no such key already exists.

Changes to basic_json_parser:

Until 0.179.0, a buffer of text is supplied to the parser with a call to `update()`
followed by a call to `parse_some()`. Once the parser reaches the end of the buffer,
additional JSON text can be supplied to the parser with another call to `update()`,
followed by another call to `parse_some()`. See [Incremental parsing (until 0.179.0)](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_parser.md#incremental-parsing-until-01790).

Since 0.179, an initial buffer of text is supplied to the parse with a call to
`set_buffer`, and parsing commences with a call to `parse_some`. The parser can be
constructed with a user provided chunk reader to obtain additional JSON text
as needed. See [Incremental parsing (since 0.179.0)](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_parser.md#incremental-parsing-since-01790).

Enhancements:

- New `basic_json(json_reference_arg_t, basic_json& j)` constructor to
allow a `basic_json` value to contain a non-owning view of another `basic_json`
value.

- Added constant `null_arg` so that a null json value can be
constructed with
```
json j{jsoncons::null_arg};
```

0.178.0
-------

Expand Down
5 changes: 5 additions & 0 deletions doc/ref/corelib/json/constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ basic_json(byte_string_arg_t,
const Allocator& alloc = Allocator()); (24)

basic_json(json_const_pointer_arg, const basic_json* j_ptr); (25) (since 0.156.0)

basic_json(json_reference_arg, basic_json& j); (26) (since 0.179.0)
```
(1) Constructs an empty json object.
Expand Down Expand Up @@ -158,6 +160,9 @@ Uses [byte_string_arg_t](../byte_string_arg_t.md) as first argument to disambigu
another `basic_json` value. If second argument `j_ptr` is null,
constructs a `null` value.
(26) Constructs a `basic_json` value that provides a non-owning view of
another `basic_json` value.
### Helpers
Helper |Definition
Expand Down
58 changes: 32 additions & 26 deletions include/jsoncons/basic_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2586,7 +2586,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value()[key];
default:
JSONCONS_THROW(not_an_object(key.data(),key.length()));
break;
}
}

Expand Down Expand Up @@ -2617,7 +2616,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value()[key];
default:
JSONCONS_THROW(not_an_object(key.data(),key.length()));
break;
}
}

Expand Down Expand Up @@ -3586,9 +3584,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().at(key);
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand All @@ -3612,9 +3608,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().at(key);
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand Down Expand Up @@ -3669,9 +3663,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().find(key);
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand All @@ -3688,9 +3680,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().find(key);
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand Down Expand Up @@ -3720,9 +3710,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().at_or_null(key);
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand Down Expand Up @@ -3755,9 +3743,7 @@ namespace jsoncons {
case json_storage_kind::json_reference:
return cast<json_reference_storage>().value().template get_value_or<T,U>(key,std::forward<U>(default_value));
default:
{
JSONCONS_THROW(not_an_object(key.data(),key.length()));
}
}
}

Expand Down Expand Up @@ -3811,7 +3797,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value().erase(pos);
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Not an object"));
break;
}
}

Expand All @@ -3827,7 +3812,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value().erase(first, last);
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Not an object"));
break;
}
}

Expand All @@ -3854,7 +3838,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value().erase(first, last);
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Not an array"));
break;
}
}

Expand All @@ -3873,7 +3856,6 @@ namespace jsoncons {
return cast<json_reference_storage>().value().erase(key);
default:
JSONCONS_THROW(not_an_object(key.data(),key.length()));
break;
}
}

Expand Down Expand Up @@ -3942,12 +3924,15 @@ namespace jsoncons {
cast<object_storage>().value().merge(source.cast<object_storage>().value());
break;
case json_storage_kind::json_reference:
merge(source.cast<json_reference_storage>().value());
cast<json_reference_storage>().value().merge(source);
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge(source.cast<json_reference_storage>().value());
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -3970,12 +3955,15 @@ namespace jsoncons {
cast<object_storage>().value().merge(std::move(source.cast<object_storage>().value()));
break;
case json_storage_kind::json_reference:
merge(std::move(source.cast<json_reference_storage>().value()));
cast<json_reference_storage>().value().merge(std::move(source));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge(std::move(source.cast<json_reference_storage>().value()));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -3998,12 +3986,15 @@ namespace jsoncons {
cast<object_storage>().value().merge(hint, source.cast<object_storage>().value());
break;
case json_storage_kind::json_reference:
merge(hint, source.cast<json_reference_storage>().value());
cast<json_reference_storage>().value().merge(hint, source);
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge(hint, source.cast<json_reference_storage>().value());
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -4026,12 +4017,15 @@ namespace jsoncons {
cast<object_storage>().value().merge(hint, std::move(source.cast<object_storage>().value()));
break;
case json_storage_kind::json_reference:
merge(hint, std::move(source.cast<json_reference_storage>().value()));
cast<json_reference_storage>().value().merge(hint, std::move(source));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge(hint, std::move(source.cast<json_reference_storage>().value()));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -4056,12 +4050,15 @@ namespace jsoncons {
cast<object_storage>().value().merge_or_update(source.cast<object_storage>().value());
break;
case json_storage_kind::json_reference:
merge_or_update(source.cast<json_reference_storage>().value());
cast<json_reference_storage>().value().merge_or_update(source);
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge or update a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge_or_update(source.cast<json_reference_storage>().value());
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -4084,12 +4081,15 @@ namespace jsoncons {
cast<object_storage>().value().merge_or_update(std::move(source.cast<object_storage>().value()));
break;
case json_storage_kind::json_reference:
merge_or_update(std::move(source.cast<json_reference_storage>().value()));
cast<json_reference_storage>().value().merge_or_update(std::move(source));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge or update a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge_or_update(std::move(source.cast<json_reference_storage>().value()));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -4112,12 +4112,15 @@ namespace jsoncons {
cast<object_storage>().value().merge_or_update(hint, source.cast<object_storage>().value());
break;
case json_storage_kind::json_reference:
merge_or_update(hint, source.cast<json_reference_storage>().value());
cast<json_reference_storage>().value().merge_or_update(hint, source);
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge or update a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge_or_update(hint, source.cast<json_reference_storage>().value());
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand All @@ -4140,12 +4143,15 @@ namespace jsoncons {
cast<object_storage>().value().merge_or_update(hint, std::move(source.cast<object_storage>().value()));
break;
case json_storage_kind::json_reference:
merge_or_update(hint, std::move(source.cast<json_reference_storage>().value()));
cast<json_reference_storage>().value().merge_or_update(hint, std::move(source));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge or update a value that is not an object"));
}
break;
case json_storage_kind::json_reference:
merge_or_update(hint, std::move(source.cast<json_reference_storage>().value()));
break;
default:
JSONCONS_THROW(json_runtime_error<std::domain_error>("Attempting to merge a value that is not an object"));
}
Expand Down
68 changes: 68 additions & 0 deletions test/corelib/src/json_reference_arg_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,74 @@ TEST_CASE("json_reference object tests")
v.at("one") = "first";
CHECK("first" == v.at("one"));
}
SECTION("insert_or_assign()")
{
json expected = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4} )");

json v(json_reference_arg, j);
REQUIRE(v.is_object());
REQUIRE_NOTHROW(v.at("two"));
CHECK(v.contains("two"));
CHECK(v.count("two") == 1);

CHECK(v.get_value_or<int>("three", 0) == 3);
CHECK(v.get_value_or<int>("four", 4) == 4);

v.insert_or_assign("four", 4);
v.insert_or_assign("three", "third");
CHECK(expected == v);
}
SECTION("try_emplace()")
{
json expected = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4} )");

json v(json_reference_arg, j);
REQUIRE(v.is_object());
REQUIRE_NOTHROW(v.at("two"));
CHECK(v.contains("two"));
CHECK(v.count("two") == 1);

CHECK(v.get_value_or<int>("three", 0) == 3);
CHECK(v.get_value_or<int>("four", 4) == 4);

v.try_emplace("four", 4);
v.try_emplace("three", "third"); // does nothing
CHECK(expected == v);
}
SECTION("merge()")
{
json expected1 = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4} )");
json expected2 = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5} )");

json j1 = json::parse(R"( {"three" : "third", "four" : 4} )");

json v(json_reference_arg, j);
REQUIRE(v.is_object());

v.merge(j1);
CHECK(expected1 == v);

json j2 = json::parse(R"( {"five" : 5} )");
j2.merge(v);
CHECK(expected2 == j2);
}
SECTION("merge_or_update()")
{
json expected1 = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4} )");
json expected2 = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4, "five" : 5} )");

json j1 = json::parse(R"( {"three" : "third", "four" : 4} )");

json v(json_reference_arg, j);
REQUIRE(v.is_object());

v.merge_or_update(j1);
CHECK(expected1 == v);

json j2 = json::parse(R"( {"five" : 5} )");
j2.merge_or_update(v);
CHECK(expected2 == j2);
}
}

TEST_CASE("json_reference string tests")
Expand Down

0 comments on commit b885214

Please sign in to comment.