✨ add contains function for JSON pointers
This commit is contained in:
parent
39011a1759
commit
258fa798f1
7 changed files with 338 additions and 23 deletions
45
doc/examples/contains_json_pointer.cpp
Normal file
45
doc/examples/contains_json_pointer.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON value
|
||||
json j =
|
||||
{
|
||||
{"number", 1}, {"string", "foo"}, {"array", {1, 2}}
|
||||
};
|
||||
|
||||
std::cout << std::boolalpha
|
||||
<< j.contains("/number"_json_pointer) << '\n'
|
||||
<< j.contains("/string"_json_pointer) << '\n'
|
||||
<< j.contains("/string"_json_pointer) << '\n'
|
||||
<< j.contains("/array"_json_pointer) << '\n'
|
||||
<< j.contains("/array/1"_json_pointer) << '\n'
|
||||
<< j.contains("/array/-"_json_pointer) << '\n'
|
||||
<< j.contains("/array/4"_json_pointer) << '\n'
|
||||
<< j.contains("/baz"_json_pointer) << std::endl;
|
||||
|
||||
// out_of_range.106
|
||||
try
|
||||
{
|
||||
// try to use an array index with leading '0'
|
||||
j.contains("/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
|
||||
j.contains("/array/one"_json_pointer);
|
||||
}
|
||||
catch (json::parse_error& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
1
doc/examples/contains_json_pointer.link
Normal file
1
doc/examples/contains_json_pointer.link
Normal file
|
@ -0,0 +1 @@
|
|||
<a target="_blank" href="https://wandbox.org/permlink/3TJ79OzHP4vmN1Nb"><b>online</b></a>
|
10
doc/examples/contains_json_pointer.output
Normal file
10
doc/examples/contains_json_pointer.output
Normal file
|
@ -0,0 +1,10 @@
|
|||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
[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
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <algorithm> // all_of
|
||||
#include <cassert> // assert
|
||||
#include <cctype> // isdigit
|
||||
#include <numeric> // accumulate
|
||||
#include <string> // string
|
||||
#include <utility> // move
|
||||
|
@ -369,7 +370,7 @@ class json_pointer
|
|||
// j which will be overwritten by a primitive value
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (result->m_type)
|
||||
switch (result->type())
|
||||
{
|
||||
case detail::value_t::null:
|
||||
{
|
||||
|
@ -446,14 +447,14 @@ class json_pointer
|
|||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
// convert null values to arrays or objects before continuing
|
||||
if (ptr->m_type == detail::value_t::null)
|
||||
if (ptr->is_null())
|
||||
{
|
||||
// check if reference token is a number
|
||||
const bool nums =
|
||||
std::all_of(reference_token.begin(), reference_token.end(),
|
||||
[](const char x)
|
||||
[](const unsigned char x)
|
||||
{
|
||||
return x >= '0' and x <= '9';
|
||||
return std::isdigit(x);
|
||||
});
|
||||
|
||||
// change value to array for numbers or "-" or to object otherwise
|
||||
|
@ -462,7 +463,7 @@ class json_pointer
|
|||
: detail::value_t::object;
|
||||
}
|
||||
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -521,7 +522,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -586,7 +587,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -645,7 +646,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -692,6 +693,77 @@ class json_pointer
|
|||
return *ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
*/
|
||||
bool contains(const BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
if (not ptr->contains(reference_token))
|
||||
{
|
||||
// we did not find the key in the object
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr = &ptr->operator[](reference_token);
|
||||
break;
|
||||
}
|
||||
|
||||
case detail::value_t::array:
|
||||
{
|
||||
if (JSON_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" always fails the range check
|
||||
return false;
|
||||
}
|
||||
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(106, 0,
|
||||
"array index '" + reference_token +
|
||||
"' must not begin with '0'"));
|
||||
}
|
||||
|
||||
JSON_TRY
|
||||
{
|
||||
const auto idx = static_cast<size_type>(array_index(reference_token));
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
// index out of range
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr = &ptr->operator[](idx);
|
||||
break;
|
||||
}
|
||||
JSON_CATCH(std::invalid_argument&)
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// we do not expect primitive values if there is still a
|
||||
// reference token to process
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no reference token left means we found a primitive value
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief split the string input to reference tokens
|
||||
|
||||
|
@ -813,7 +885,7 @@ class json_pointer
|
|||
const BasicJsonType& value,
|
||||
BasicJsonType& result)
|
||||
{
|
||||
switch (value.m_type)
|
||||
switch (value.type())
|
||||
{
|
||||
case detail::value_t::array:
|
||||
{
|
||||
|
|
|
@ -4001,15 +4001,48 @@ class basic_json
|
|||
@liveexample{The following code shows an example for `contains()`.,contains}
|
||||
|
||||
@sa @ref find(KeyT&&) -- returns an iterator to an object element
|
||||
@sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
template<typename KeyT>
|
||||
bool contains(KeyT&& key) const
|
||||
template<typename KeyT, typename std::enable_if<
|
||||
not std::is_same<KeyT, json_pointer>::value, int>::type = 0>
|
||||
bool contains(KeyT && key) const
|
||||
{
|
||||
return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief check the existence of an element in a JSON object given a JSON pointer
|
||||
|
||||
Check wehther the given JSON pointer @a ptr can be resolved in the current
|
||||
JSON value.
|
||||
|
||||
@note This method can be executed on any JSON value type.
|
||||
|
||||
@param[in] ptr JSON pointer to check its existence.
|
||||
|
||||
@return true if the JSON pointer can be resolved to a stored value, false
|
||||
otherwise.
|
||||
|
||||
@post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
|
||||
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
|
||||
@complexity Logarithmic in the size of the JSON object.
|
||||
|
||||
@liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
|
||||
|
||||
@sa @ref contains(KeyT &&) const -- checks the existence of a key
|
||||
|
||||
@since version 3.7.0
|
||||
*/
|
||||
bool contains(const json_pointer& ptr) const
|
||||
{
|
||||
return ptr.contains(this);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
|
|
@ -8445,6 +8445,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||
|
||||
#include <algorithm> // all_of
|
||||
#include <cassert> // assert
|
||||
#include <cctype> // isdigit
|
||||
#include <numeric> // accumulate
|
||||
#include <string> // string
|
||||
#include <utility> // move
|
||||
|
@ -8815,7 +8816,7 @@ class json_pointer
|
|||
// j which will be overwritten by a primitive value
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (result->m_type)
|
||||
switch (result->type())
|
||||
{
|
||||
case detail::value_t::null:
|
||||
{
|
||||
|
@ -8892,14 +8893,14 @@ class json_pointer
|
|||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
// convert null values to arrays or objects before continuing
|
||||
if (ptr->m_type == detail::value_t::null)
|
||||
if (ptr->is_null())
|
||||
{
|
||||
// check if reference token is a number
|
||||
const bool nums =
|
||||
std::all_of(reference_token.begin(), reference_token.end(),
|
||||
[](const char x)
|
||||
[](const unsigned char x)
|
||||
{
|
||||
return x >= '0' and x <= '9';
|
||||
return std::isdigit(x);
|
||||
});
|
||||
|
||||
// change value to array for numbers or "-" or to object otherwise
|
||||
|
@ -8908,7 +8909,7 @@ class json_pointer
|
|||
: detail::value_t::object;
|
||||
}
|
||||
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -8967,7 +8968,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -9032,7 +9033,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -9091,7 +9092,7 @@ class json_pointer
|
|||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->m_type)
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
|
@ -9138,6 +9139,77 @@ class json_pointer
|
|||
return *ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
*/
|
||||
bool contains(const BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
{
|
||||
case detail::value_t::object:
|
||||
{
|
||||
if (not ptr->contains(reference_token))
|
||||
{
|
||||
// we did not find the key in the object
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr = &ptr->operator[](reference_token);
|
||||
break;
|
||||
}
|
||||
|
||||
case detail::value_t::array:
|
||||
{
|
||||
if (JSON_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" always fails the range check
|
||||
return false;
|
||||
}
|
||||
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(106, 0,
|
||||
"array index '" + reference_token +
|
||||
"' must not begin with '0'"));
|
||||
}
|
||||
|
||||
JSON_TRY
|
||||
{
|
||||
const auto idx = static_cast<size_type>(array_index(reference_token));
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
// index out of range
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr = &ptr->operator[](idx);
|
||||
break;
|
||||
}
|
||||
JSON_CATCH(std::invalid_argument&)
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// we do not expect primitive values if there is still a
|
||||
// reference token to process
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no reference token left means we found a primitive value
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief split the string input to reference tokens
|
||||
|
||||
|
@ -9259,7 +9331,7 @@ class json_pointer
|
|||
const BasicJsonType& value,
|
||||
BasicJsonType& result)
|
||||
{
|
||||
switch (value.m_type)
|
||||
switch (value.type())
|
||||
{
|
||||
case detail::value_t::array:
|
||||
{
|
||||
|
@ -16802,15 +16874,48 @@ class basic_json
|
|||
@liveexample{The following code shows an example for `contains()`.,contains}
|
||||
|
||||
@sa @ref find(KeyT&&) -- returns an iterator to an object element
|
||||
@sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
template<typename KeyT>
|
||||
bool contains(KeyT&& key) const
|
||||
template<typename KeyT, typename std::enable_if<
|
||||
not std::is_same<KeyT, json_pointer>::value, int>::type = 0>
|
||||
bool contains(KeyT && key) const
|
||||
{
|
||||
return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief check the existence of an element in a JSON object given a JSON pointer
|
||||
|
||||
Check wehther the given JSON pointer @a ptr can be resolved in the current
|
||||
JSON value.
|
||||
|
||||
@note This method can be executed on any JSON value type.
|
||||
|
||||
@param[in] ptr JSON pointer to check its existence.
|
||||
|
||||
@return true if the JSON pointer can be resolved to a stored value, false
|
||||
otherwise.
|
||||
|
||||
@post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
|
||||
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
|
||||
@complexity Logarithmic in the size of the JSON object.
|
||||
|
||||
@liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
|
||||
|
||||
@sa @ref contains(KeyT &&) const -- checks the existence of a key
|
||||
|
||||
@since version 3.7.0
|
||||
*/
|
||||
bool contains(const json_pointer& ptr) const
|
||||
{
|
||||
return ptr.contains(this);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
|
|
@ -90,12 +90,18 @@ TEST_CASE("JSON pointers")
|
|||
// the whole document
|
||||
CHECK(j[json::json_pointer()] == j);
|
||||
CHECK(j[json::json_pointer("")] == j);
|
||||
CHECK(j.contains(json::json_pointer()));
|
||||
CHECK(j.contains(json::json_pointer("")));
|
||||
|
||||
// array access
|
||||
CHECK(j[json::json_pointer("/foo")] == j["foo"]);
|
||||
CHECK(j.contains(json::json_pointer("/foo")));
|
||||
CHECK(j[json::json_pointer("/foo/0")] == j["foo"][0]);
|
||||
CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
|
||||
CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
|
||||
CHECK(j.contains(json::json_pointer("/foo/0")));
|
||||
CHECK(j.contains(json::json_pointer("/foo/1")));
|
||||
CHECK(not j.contains(json::json_pointer("/foo/-")));
|
||||
|
||||
// checked array access
|
||||
CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
|
||||
|
@ -103,6 +109,8 @@ TEST_CASE("JSON pointers")
|
|||
|
||||
// empty string access
|
||||
CHECK(j[json::json_pointer("/")] == j[""]);
|
||||
CHECK(j.contains(json::json_pointer("")));
|
||||
CHECK(j.contains(json::json_pointer("/")));
|
||||
|
||||
// other cases
|
||||
CHECK(j[json::json_pointer("/ ")] == j[" "]);
|
||||
|
@ -112,6 +120,14 @@ TEST_CASE("JSON pointers")
|
|||
CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]);
|
||||
CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]);
|
||||
|
||||
// contains
|
||||
CHECK(j.contains(json::json_pointer("/ ")));
|
||||
CHECK(j.contains(json::json_pointer("/c%d")));
|
||||
CHECK(j.contains(json::json_pointer("/e^f")));
|
||||
CHECK(j.contains(json::json_pointer("/g|h")));
|
||||
CHECK(j.contains(json::json_pointer("/i\\j")));
|
||||
CHECK(j.contains(json::json_pointer("/k\"l")));
|
||||
|
||||
// checked access
|
||||
CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
|
||||
CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);
|
||||
|
@ -123,14 +139,24 @@ TEST_CASE("JSON pointers")
|
|||
// escaped access
|
||||
CHECK(j[json::json_pointer("/a~1b")] == j["a/b"]);
|
||||
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
|
||||
CHECK(j.contains(json::json_pointer("/a~1b")));
|
||||
CHECK(j.contains(json::json_pointer("/m~0n")));
|
||||
|
||||
// unescaped access
|
||||
// access to nonexisting values yield object creation
|
||||
CHECK(not j.contains(json::json_pointer("/a/b")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/b")] = 42);
|
||||
CHECK(j.contains(json::json_pointer("/a/b")));
|
||||
CHECK(j["a"]["b"] == json(42));
|
||||
|
||||
CHECK(not j.contains(json::json_pointer("/a/c/1")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/c/1")] = 42);
|
||||
CHECK(j["a"]["c"] == json({nullptr, 42}));
|
||||
CHECK(j.contains(json::json_pointer("/a/c/1")));
|
||||
|
||||
CHECK(not j.contains(json::json_pointer("/a/d/-")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/d/-")] = 42);
|
||||
CHECK(not j.contains(json::json_pointer("/a/d/-")));
|
||||
CHECK(j["a"]["d"] == json::array({42}));
|
||||
// "/a/b" works for JSON {"a": {"b": 42}}
|
||||
CHECK(json({{"a", {{"b", 42}}}})[json::json_pointer("/a/b")] == json(42));
|
||||
|
@ -143,6 +169,7 @@ TEST_CASE("JSON pointers")
|
|||
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'");
|
||||
CHECK(not j_primitive.contains(json::json_pointer("/foo")));
|
||||
}
|
||||
|
||||
SECTION("const access")
|
||||
|
@ -233,11 +260,16 @@ TEST_CASE("JSON pointers")
|
|||
|
||||
// the whole document
|
||||
CHECK(j[""_json_pointer] == j);
|
||||
CHECK(j.contains(""_json_pointer));
|
||||
|
||||
// array access
|
||||
CHECK(j["/foo"_json_pointer] == j["foo"]);
|
||||
CHECK(j["/foo/0"_json_pointer] == j["foo"][0]);
|
||||
CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
|
||||
CHECK(j.contains("/foo"_json_pointer));
|
||||
CHECK(j.contains("/foo/0"_json_pointer));
|
||||
CHECK(j.contains("/foo/1"_json_pointer));
|
||||
CHECK(not j.contains("/foo/-"_json_pointer));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +310,12 @@ TEST_CASE("JSON pointers")
|
|||
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'");
|
||||
CHECK_THROWS_AS(j.contains("/01"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.contains("/01"_json_pointer),
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
CHECK_THROWS_AS(j_const.contains("/01"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const.contains("/01"_json_pointer),
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
|
||||
// error with incorrect numbers
|
||||
CHECK_THROWS_AS(j["/one"_json_pointer] = 1, json::parse_error&);
|
||||
|
@ -294,6 +332,13 @@ TEST_CASE("JSON pointers")
|
|||
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(j.contains("/one"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.contains("/one"_json_pointer),
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
CHECK_THROWS_AS(j_const.contains("/one"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const.contains("/one"_json_pointer),
|
||||
"[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");
|
||||
|
@ -306,6 +351,7 @@ TEST_CASE("JSON pointers")
|
|||
CHECK_THROWS_AS(j_const["/-"_json_pointer], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const["/-"_json_pointer],
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
CHECK(not j_const.contains("/-"_json_pointer));
|
||||
|
||||
// error when using "-" with at
|
||||
CHECK_THROWS_AS(j.at("/-"_json_pointer), json::out_of_range&);
|
||||
|
@ -314,6 +360,7 @@ TEST_CASE("JSON pointers")
|
|||
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");
|
||||
CHECK(not j_const.contains("/-"_json_pointer));
|
||||
}
|
||||
|
||||
SECTION("const access")
|
||||
|
@ -329,11 +376,13 @@ TEST_CASE("JSON pointers")
|
|||
CHECK_THROWS_AS(j.at("/3"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/3"_json_pointer),
|
||||
"[json.exception.out_of_range.401] array index 3 is out of range");
|
||||
CHECK(not j.contains("/3"_json_pointer));
|
||||
|
||||
// assign to nonexisting index (with gap)
|
||||
CHECK_THROWS_AS(j.at("/5"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/5"_json_pointer),
|
||||
"[json.exception.out_of_range.401] array index 5 is out of range");
|
||||
CHECK(not j.contains("/5"_json_pointer));
|
||||
|
||||
// assign to "-"
|
||||
CHECK_THROWS_AS(j["/-"_json_pointer], json::out_of_range&);
|
||||
|
@ -342,8 +391,8 @@ TEST_CASE("JSON pointers")
|
|||
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");
|
||||
CHECK(not j.contains("/-"_json_pointer));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SECTION("flatten")
|
||||
|
|
Loading…
Reference in a new issue