Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
json
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
json
Commits
104c5c19
Unverified
Commit
104c5c19
authored
6 years ago
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/json_pointer_contains' into develop
parents
7a23aa1c
258fa798
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
338 additions
and
23 deletions
+338
-23
doc/examples/contains_json_pointer.cpp
doc/examples/contains_json_pointer.cpp
+45
-0
doc/examples/contains_json_pointer.link
doc/examples/contains_json_pointer.link
+1
-0
doc/examples/contains_json_pointer.output
doc/examples/contains_json_pointer.output
+10
-0
include/nlohmann/detail/json_pointer.hpp
include/nlohmann/detail/json_pointer.hpp
+81
-9
include/nlohmann/json.hpp
include/nlohmann/json.hpp
+35
-2
single_include/nlohmann/json.hpp
single_include/nlohmann/json.hpp
+116
-11
test/src/unit-json_pointer.cpp
test/src/unit-json_pointer.cpp
+50
-1
No files found.
doc/examples/contains_json_pointer.cpp
0 → 100644
View file @
104c5c19
#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'
;
}
}
This diff is collapsed.
Click to expand it.
doc/examples/contains_json_pointer.link
0 → 100644
View file @
104c5c19
<a target="_blank" href="https://wandbox.org/permlink/3TJ79OzHP4vmN1Nb"><b>online</b></a>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
doc/examples/contains_json_pointer.output
0 → 100644
View file @
104c5c19
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
This diff is collapsed.
Click to expand it.
include/nlohmann/detail/json_pointer.hpp
View file @
104c5c19
...
...
@@ -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
:
{
...
...
This diff is collapsed.
Click to expand it.
include/nlohmann/json.hpp
View file @
104c5c19
...
...
@@ -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
);
}
/// @}
...
...
This diff is collapsed.
Click to expand it.
single_include/nlohmann/json.hpp
View file @
104c5c19
...
...
@@ -8455,6 +8455,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
...
...
@@ -8825,7 +8826,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:
{
...
...
@@ -8902,14 +8903,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
...
...
@@ -8918,7 +8919,7 @@ class json_pointer
: detail::value_t::object;
}
switch (ptr->
m_type
)
switch (ptr->
type()
)
{
case detail::value_t::object:
{
...
...
@@ -8977,7 +8978,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:
{
...
...
@@ -9042,7 +9043,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:
{
...
...
@@ -9101,7 +9102,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:
{
...
...
@@ -9148,6 +9149,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
...
...
@@ -9269,7 +9341,7 @@ class json_pointer
const BasicJsonType& value,
BasicJsonType& result)
{
switch (value.
m_type
)
switch (value.
type()
)
{
case detail::value_t::array:
{
...
...
@@ -16812,15 +16884,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);
}
/// @}
...
...
This diff is collapsed.
Click to expand it.
test/src/unit-json_pointer.cpp
View file @
104c5c19
...
...
@@ -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"
)
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment