2016-08-05 03:55:47 +08:00
/*
__ _____ _____ _____
__ | | __ | | | | JSON for Modern C + + ( test suite )
2019-03-20 07:19:07 +08:00
| | | __ | | | | | | version 3.6 .0
2016-08-05 03:55:47 +08:00
| _____ | _____ | _____ | _ | ___ | https : //github.com/nlohmann/json
Licensed under the MIT License < http : //opensource.org/licenses/MIT>.
2018-05-03 23:41:45 +08:00
SPDX - License - Identifier : MIT
2019-03-20 07:19:07 +08:00
Copyright ( c ) 2013 - 2019 Niels Lohmann < http : //nlohmann.me>.
2016-08-05 03:55:47 +08:00
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE .
*/
# include "catch.hpp"
2018-01-29 18:21:11 +08:00
# include <nlohmann/json.hpp>
2016-08-05 03:55:47 +08:00
using nlohmann : : json ;
2016-08-05 04:51:08 +08:00
TEST_CASE ( " element access 2 " )
2016-08-05 03:55:47 +08:00
{
SECTION ( " object " )
{
json j = { { " integer " , 1 } , { " unsigned " , 1u } , { " floating " , 42.23 } , { " null " , nullptr } , { " string " , " hello world " } , { " boolean " , true } , { " object " , json : : object ( ) } , { " array " , { 1 , 2 , 3 } } } ;
const json j_const = j ;
SECTION ( " access specified element with bounds checking " )
{
SECTION ( " access within bounds " )
{
CHECK ( j . at ( " integer " ) = = json ( 1 ) ) ;
CHECK ( j . at ( " unsigned " ) = = json ( 1u ) ) ;
CHECK ( j . at ( " boolean " ) = = json ( true ) ) ;
CHECK ( j . at ( " null " ) = = json ( nullptr ) ) ;
CHECK ( j . at ( " string " ) = = json ( " hello world " ) ) ;
CHECK ( j . at ( " floating " ) = = json ( 42.23 ) ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j . at ( " object " ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j . at ( " array " ) = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j_const . at ( " integer " ) = = json ( 1 ) ) ;
CHECK ( j_const . at ( " unsigned " ) = = json ( 1u ) ) ;
CHECK ( j_const . at ( " boolean " ) = = json ( true ) ) ;
CHECK ( j_const . at ( " null " ) = = json ( nullptr ) ) ;
CHECK ( j_const . at ( " string " ) = = json ( " hello world " ) ) ;
CHECK ( j_const . at ( " floating " ) = = json ( 42.23 ) ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j_const . at ( " object " ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j_const . at ( " array " ) = = json ( { 1 , 2 , 3 } ) ) ;
}
SECTION ( " access outside bounds " )
{
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j . at ( " foo " ) , json : : out_of_range & ) ;
CHECK_THROWS_AS ( j_const . at ( " foo " ) , json : : out_of_range & ) ;
2017-03-06 06:16:17 +08:00
CHECK_THROWS_WITH ( j . at ( " foo " ) ,
" [json.exception.out_of_range.403] key 'foo' not found " ) ;
CHECK_THROWS_WITH ( j_const . at ( " foo " ) ,
" [json.exception.out_of_range.403] key 'foo' not found " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " access on non-object type " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with null " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with null " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with boolean " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with boolean " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with string " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with string " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with array " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with array " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . at ( " foo " ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . at ( " foo " ) , json : : type_error & ) ;
2017-03-06 01:56:35 +08:00
CHECK_THROWS_WITH ( j_nonobject . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . at ( " foo " ) , " [json.exception.type_error.304] cannot use at() with number " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
SECTION ( " access specified element with default value " )
{
SECTION ( " given a key " )
{
SECTION ( " access existing value " )
{
CHECK ( j . value ( " integer " , 2 ) = = 1 ) ;
CHECK ( j . value ( " integer " , 1.0 ) = = Approx ( 1 ) ) ;
CHECK ( j . value ( " unsigned " , 2 ) = = 1u ) ;
CHECK ( j . value ( " unsigned " , 1.0 ) = = Approx ( 1u ) ) ;
CHECK ( j . value ( " null " , json ( 1 ) ) = = json ( ) ) ;
CHECK ( j . value ( " boolean " , false ) = = true ) ;
CHECK ( j . value ( " string " , " bar " ) = = " hello world " ) ;
CHECK ( j . value ( " string " , std : : string ( " bar " ) ) = = " hello world " ) ;
CHECK ( j . value ( " floating " , 12.34 ) = = Approx ( 42.23 ) ) ;
CHECK ( j . value ( " floating " , 12 ) = = 42 ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j . value ( " object " , json ( { { " foo " , " bar " } } ) ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j . value ( " array " , json ( { 10 , 100 } ) ) = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j_const . value ( " integer " , 2 ) = = 1 ) ;
CHECK ( j_const . value ( " integer " , 1.0 ) = = Approx ( 1 ) ) ;
CHECK ( j_const . value ( " unsigned " , 2 ) = = 1u ) ;
CHECK ( j_const . value ( " unsigned " , 1.0 ) = = Approx ( 1u ) ) ;
CHECK ( j_const . value ( " boolean " , false ) = = true ) ;
CHECK ( j_const . value ( " string " , " bar " ) = = " hello world " ) ;
CHECK ( j_const . value ( " string " , std : : string ( " bar " ) ) = = " hello world " ) ;
CHECK ( j_const . value ( " floating " , 12.34 ) = = Approx ( 42.23 ) ) ;
CHECK ( j_const . value ( " floating " , 12 ) = = 42 ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j_const . value ( " object " , json ( { { " foo " , " bar " } } ) ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j_const . value ( " array " , json ( { 10 , 100 } ) ) = = json ( { 1 , 2 , 3 } ) ) ;
}
SECTION ( " access non-existing value " )
{
CHECK ( j . value ( " _ " , 2 ) = = 2 ) ;
CHECK ( j . value ( " _ " , 2u ) = = 2u ) ;
CHECK ( j . value ( " _ " , false ) = = false ) ;
CHECK ( j . value ( " _ " , " bar " ) = = " bar " ) ;
CHECK ( j . value ( " _ " , 12.34 ) = = Approx ( 12.34 ) ) ;
CHECK ( j . value ( " _ " , json ( { { " foo " , " bar " } } ) ) = = json ( { { " foo " , " bar " } } ) ) ;
CHECK ( j . value ( " _ " , json ( { 10 , 100 } ) ) = = json ( { 10 , 100 } ) ) ;
CHECK ( j_const . value ( " _ " , 2 ) = = 2 ) ;
CHECK ( j_const . value ( " _ " , 2u ) = = 2u ) ;
CHECK ( j_const . value ( " _ " , false ) = = false ) ;
CHECK ( j_const . value ( " _ " , " bar " ) = = " bar " ) ;
CHECK ( j_const . value ( " _ " , 12.34 ) = = Approx ( 12.34 ) ) ;
CHECK ( j_const . value ( " _ " , json ( { { " foo " , " bar " } } ) ) = = json ( { { " foo " , " bar " } } ) ) ;
CHECK ( j_const . value ( " _ " , json ( { 10 , 100 } ) ) = = json ( { 10 , 100 } ) ) ;
}
SECTION ( " access on non-object type " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with null " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with null " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with boolean " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with boolean " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with string " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with string " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with array " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with array " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " foo " , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " foo " , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " foo " , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
SECTION ( " given a JSON pointer " )
{
SECTION ( " access existing value " )
{
CHECK ( j . value ( " /integer " _json_pointer , 2 ) = = 1 ) ;
CHECK ( j . value ( " /integer " _json_pointer , 1.0 ) = = Approx ( 1 ) ) ;
CHECK ( j . value ( " /unsigned " _json_pointer , 2 ) = = 1u ) ;
CHECK ( j . value ( " /unsigned " _json_pointer , 1.0 ) = = Approx ( 1u ) ) ;
CHECK ( j . value ( " /null " _json_pointer , json ( 1 ) ) = = json ( ) ) ;
CHECK ( j . value ( " /boolean " _json_pointer , false ) = = true ) ;
CHECK ( j . value ( " /string " _json_pointer , " bar " ) = = " hello world " ) ;
CHECK ( j . value ( " /string " _json_pointer , std : : string ( " bar " ) ) = = " hello world " ) ;
CHECK ( j . value ( " /floating " _json_pointer , 12.34 ) = = Approx ( 42.23 ) ) ;
CHECK ( j . value ( " /floating " _json_pointer , 12 ) = = 42 ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j . value ( " /object " _json_pointer , json ( { { " foo " , " bar " } } ) ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j . value ( " /array " _json_pointer , json ( { 10 , 100 } ) ) = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j_const . value ( " /integer " _json_pointer , 2 ) = = 1 ) ;
CHECK ( j_const . value ( " /integer " _json_pointer , 1.0 ) = = Approx ( 1 ) ) ;
CHECK ( j_const . value ( " /unsigned " _json_pointer , 2 ) = = 1u ) ;
CHECK ( j_const . value ( " /unsigned " _json_pointer , 1.0 ) = = Approx ( 1u ) ) ;
CHECK ( j_const . value ( " /boolean " _json_pointer , false ) = = true ) ;
CHECK ( j_const . value ( " /string " _json_pointer , " bar " ) = = " hello world " ) ;
CHECK ( j_const . value ( " /string " _json_pointer , std : : string ( " bar " ) ) = = " hello world " ) ;
CHECK ( j_const . value ( " /floating " _json_pointer , 12.34 ) = = Approx ( 42.23 ) ) ;
CHECK ( j_const . value ( " /floating " _json_pointer , 12 ) = = 42 ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j_const . value ( " /object " _json_pointer , json ( { { " foo " , " bar " } } ) ) = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j_const . value ( " /array " _json_pointer , json ( { 10 , 100 } ) ) = = json ( { 1 , 2 , 3 } ) ) ;
}
SECTION ( " access on non-object type " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with null " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with null " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with boolean " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
2017-03-06 02:15:56 +08:00
" [json.exception.type_error.306] cannot use value() with boolean " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with string " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
2017-03-06 02:15:56 +08:00
" [json.exception.type_error.306] cannot use value() with string " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with array " ) ;
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with array " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
2017-03-06 02:15:56 +08:00
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
2017-03-06 02:15:56 +08:00
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_nonobject_const ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) , json : : type_error & ) ;
2017-03-06 02:15:56 +08:00
CHECK_THROWS_WITH ( j_nonobject . value ( " /foo " _json_pointer , 1 ) ,
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject_const . value ( " /foo " _json_pointer , 1 ) ,
2017-03-06 02:15:56 +08:00
" [json.exception.type_error.306] cannot use value() with number " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
}
SECTION ( " front and back " )
{
// "array" is the smallest key
CHECK ( j . front ( ) = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j_const . front ( ) = = json ( { 1 , 2 , 3 } ) ) ;
// "unsigned" is the largest key
CHECK ( j . back ( ) = = json ( 1u ) ) ;
CHECK ( j_const . back ( ) = = json ( 1u ) ) ;
}
SECTION ( " access specified element " )
{
SECTION ( " access within bounds " )
{
CHECK ( j [ " integer " ] = = json ( 1 ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " integer " ) ] = = j [ " integer " ] ) ;
CHECK ( j [ " unsigned " ] = = json ( 1u ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " unsigned " ) ] = = j [ " unsigned " ] ) ;
CHECK ( j [ " boolean " ] = = json ( true ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " boolean " ) ] = = j [ " boolean " ] ) ;
CHECK ( j [ " null " ] = = json ( nullptr ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " null " ) ] = = j [ " null " ] ) ;
CHECK ( j [ " string " ] = = json ( " hello world " ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " string " ) ] = = j [ " string " ] ) ;
CHECK ( j [ " floating " ] = = json ( 42.23 ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " floating " ) ] = = j [ " floating " ] ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j [ " object " ] = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j [ json : : object_t : : key_type ( " object " ) ] = = j [ " object " ] ) ;
CHECK ( j [ " array " ] = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j [ json : : object_t : : key_type ( " array " ) ] = = j [ " array " ] ) ;
CHECK ( j_const [ " integer " ] = = json ( 1 ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " integer " ) ] = = j [ " integer " ] ) ;
CHECK ( j_const [ " boolean " ] = = json ( true ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " boolean " ) ] = = j [ " boolean " ] ) ;
CHECK ( j_const [ " null " ] = = json ( nullptr ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " null " ) ] = = j [ " null " ] ) ;
CHECK ( j_const [ " string " ] = = json ( " hello world " ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " string " ) ] = = j [ " string " ] ) ;
CHECK ( j_const [ " floating " ] = = json ( 42.23 ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " floating " ) ] = = j [ " floating " ] ) ;
2017-03-17 01:39:33 +08:00
CHECK ( j_const [ " object " ] = = json : : object ( ) ) ;
2016-08-05 03:55:47 +08:00
CHECK ( j_const [ json : : object_t : : key_type ( " object " ) ] = = j [ " object " ] ) ;
CHECK ( j_const [ " array " ] = = json ( { 1 , 2 , 3 } ) ) ;
CHECK ( j_const [ json : : object_t : : key_type ( " array " ) ] = = j [ " array " ] ) ;
}
SECTION ( " access on non-object type " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
json j_nonobject2 ( json : : value_t : : null ) ;
const json j_const_nonobject ( j_nonobject ) ;
CHECK_NOTHROW ( j_nonobject [ " foo " ] ) ;
CHECK_NOTHROW ( j_nonobject2 [ json : : object_t : : key_type ( " foo " ) ] ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2018-09-18 03:36:38 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] , " [json.exception.type_error.305] cannot use operator[] with a string argument with null " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with null " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with boolean " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with boolean " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with boolean " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with boolean " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with string " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with string " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with string " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with string " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with array " ) ;
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , " [json.exception.type_error.305] cannot use operator[] with a string argument with array " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with array " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with array " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_const_nonobject ( j_nonobject ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ " foo " ] , json : : type_error & ) ;
CHECK_THROWS_AS ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] , json : : type_error & ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2017-03-06 02:08:12 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ " foo " ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( j_const_nonobject [ json : : object_t : : key_type ( " foo " ) ] ,
2018-09-18 03:36:38 +08:00
" [json.exception.type_error.305] cannot use operator[] with a string argument with number " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
SECTION ( " remove specified element " )
{
SECTION ( " remove element by key " )
{
CHECK ( j . find ( " integer " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " integer " ) = = 1 ) ;
CHECK ( j . find ( " integer " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " integer " ) = = 0 ) ;
CHECK ( j . find ( " unsigned " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " unsigned " ) = = 1 ) ;
CHECK ( j . find ( " unsigned " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " unsigned " ) = = 0 ) ;
CHECK ( j . find ( " boolean " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " boolean " ) = = 1 ) ;
CHECK ( j . find ( " boolean " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " boolean " ) = = 0 ) ;
CHECK ( j . find ( " null " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " null " ) = = 1 ) ;
CHECK ( j . find ( " null " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " null " ) = = 0 ) ;
CHECK ( j . find ( " string " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " string " ) = = 1 ) ;
CHECK ( j . find ( " string " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " string " ) = = 0 ) ;
CHECK ( j . find ( " floating " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " floating " ) = = 1 ) ;
CHECK ( j . find ( " floating " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " floating " ) = = 0 ) ;
CHECK ( j . find ( " object " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " object " ) = = 1 ) ;
CHECK ( j . find ( " object " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " object " ) = = 0 ) ;
CHECK ( j . find ( " array " ) ! = j . end ( ) ) ;
CHECK ( j . erase ( " array " ) = = 1 ) ;
CHECK ( j . find ( " array " ) = = j . end ( ) ) ;
CHECK ( j . erase ( " array " ) = = 0 ) ;
}
SECTION ( " remove element by iterator " )
{
SECTION ( " erase(begin()) " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : iterator it2 = jobject . erase ( jobject . begin ( ) ) ;
CHECK ( jobject = = json ( { { " b " , 1 } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( 1 ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : const_iterator it2 = jobject . erase ( jobject . cbegin ( ) ) ;
CHECK ( jobject = = json ( { { " b " , 1 } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( 1 ) ) ;
}
}
SECTION ( " erase(begin(), end()) " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : iterator it2 = jobject . erase ( jobject . begin ( ) , jobject . end ( ) ) ;
CHECK ( jobject = = json : : object ( ) ) ;
CHECK ( it2 = = jobject . end ( ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : const_iterator it2 = jobject . erase ( jobject . cbegin ( ) , jobject . cend ( ) ) ;
CHECK ( jobject = = json : : object ( ) ) ;
CHECK ( it2 = = jobject . cend ( ) ) ;
}
}
SECTION ( " erase(begin(), begin()) " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : iterator it2 = jobject . erase ( jobject . begin ( ) , jobject . begin ( ) ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( " a " ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : const_iterator it2 = jobject . erase ( jobject . cbegin ( ) , jobject . cbegin ( ) ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( " a " ) ) ;
}
}
SECTION ( " erase at offset " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : iterator it = jobject . find ( " b " ) ;
json : : iterator it2 = jobject . erase ( it ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( 17 ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json : : const_iterator it = jobject . find ( " b " ) ;
json : : const_iterator it2 = jobject . erase ( it ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " c " , 17u } } ) ) ;
CHECK ( * it2 = = json ( 17 ) ) ;
}
}
SECTION ( " erase subrange " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json : : iterator it2 = jobject . erase ( jobject . find ( " b " ) , jobject . find ( " e " ) ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " e " , true } } ) ) ;
CHECK ( * it2 = = json ( true ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json : : const_iterator it2 = jobject . erase ( jobject . find ( " b " ) , jobject . find ( " e " ) ) ;
CHECK ( jobject = = json ( { { " a " , " a " } , { " e " , true } } ) ) ;
CHECK ( * it2 = = json ( true ) ) ;
}
}
SECTION ( " different objects " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json jobject2 = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( jobject . erase ( jobject2 . begin ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject . begin ( ) , jobject2 . end ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject2 . begin ( ) , jobject . end ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject2 . begin ( ) , jobject2 . end ( ) ) , json : : invalid_iterator & ) ;
2017-03-03 20:19:45 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . begin ( ) ) ,
" [json.exception.invalid_iterator.202] iterator does not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject . begin ( ) , jobject2 . end ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . begin ( ) , jobject . end ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . begin ( ) , jobject2 . end ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json jobject2 = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( jobject . erase ( jobject2 . cbegin ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject . cbegin ( ) , jobject2 . cend ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject2 . cbegin ( ) , jobject . cend ( ) ) , json : : invalid_iterator & ) ;
CHECK_THROWS_AS ( jobject . erase ( jobject2 . cbegin ( ) , jobject2 . cend ( ) ) , json : : invalid_iterator & ) ;
2017-03-03 20:19:45 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . cbegin ( ) ) ,
" [json.exception.invalid_iterator.202] iterator does not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject . cbegin ( ) , jobject2 . cend ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . cbegin ( ) , jobject . cend ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
CHECK_THROWS_WITH ( jobject . erase ( jobject2 . cbegin ( ) , jobject2 . cend ( ) ) ,
2017-03-03 20:38:14 +08:00
" [json.exception.invalid_iterator.203] iterators do not fit current value " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
SECTION ( " remove element by key in non-object type " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with null " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with boolean " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with string " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with array " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with number " ) ;
2016-08-05 03:55:47 +08:00
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
2017-07-08 04:41:22 +08:00
CHECK_THROWS_AS ( j_nonobject . erase ( " foo " ) , json : : type_error & ) ;
2017-03-06 02:26:44 +08:00
CHECK_THROWS_WITH ( j_nonobject . erase ( " foo " ) ,
" [json.exception.type_error.307] cannot use erase() with number " ) ;
2016-08-05 03:55:47 +08:00
}
}
}
SECTION ( " find an element in an object " )
{
SECTION ( " existing element " )
{
for ( auto key :
{ " integer " , " unsigned " , " floating " , " null " , " string " , " boolean " , " object " , " array "
} )
{
CHECK ( j . find ( key ) ! = j . end ( ) ) ;
CHECK ( * j . find ( key ) = = j . at ( key ) ) ;
CHECK ( j_const . find ( key ) ! = j_const . end ( ) ) ;
CHECK ( * j_const . find ( key ) = = j_const . at ( key ) ) ;
}
}
SECTION ( " nonexisting element " )
{
CHECK ( j . find ( " foo " ) = = j . end ( ) ) ;
CHECK ( j_const . find ( " foo " ) = = j_const . end ( ) ) ;
}
SECTION ( " all types " )
{
SECTION ( " null " )
{
json j_nonarray ( json : : value_t : : null ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " string " )
{
json j_nonarray ( json : : value_t : : string ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " object " )
{
json j_nonarray ( json : : value_t : : object ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " array " )
{
json j_nonarray ( json : : value_t : : array ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " boolean " )
{
json j_nonarray ( json : : value_t : : boolean ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " number (integer) " )
{
json j_nonarray ( json : : value_t : : number_integer ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " number (unsigned) " )
{
json j_nonarray ( json : : value_t : : number_unsigned ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
SECTION ( " number (floating-point) " )
{
json j_nonarray ( json : : value_t : : number_float ) ;
const json j_nonarray_const ( j_nonarray ) ;
CHECK ( j_nonarray . find ( " foo " ) = = j_nonarray . end ( ) ) ;
CHECK ( j_nonarray_const . find ( " foo " ) = = j_nonarray_const . end ( ) ) ;
}
}
}
SECTION ( " count keys in an object " )
{
SECTION ( " existing element " )
{
for ( auto key :
{ " integer " , " unsigned " , " floating " , " null " , " string " , " boolean " , " object " , " array "
} )
{
CHECK ( j . count ( key ) = = 1 ) ;
CHECK ( j_const . count ( key ) = = 1 ) ;
}
}
SECTION ( " nonexisting element " )
{
CHECK ( j . count ( " foo " ) = = 0 ) ;
CHECK ( j_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " all types " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " object " )
{
json j_nonobject ( json : : value_t : : object ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . count ( " foo " ) = = 0 ) ;
CHECK ( j_nonobject_const . count ( " foo " ) = = 0 ) ;
}
}
}
2019-02-10 21:12:01 +08:00
SECTION ( " check existence of key in an object " )
{
SECTION ( " existing element " )
{
for ( auto key :
{ " integer " , " unsigned " , " floating " , " null " , " string " , " boolean " , " object " , " array "
} )
{
CHECK ( j . contains ( key ) = = true ) ;
CHECK ( j_const . contains ( key ) = = true ) ;
}
}
SECTION ( " nonexisting element " )
{
CHECK ( j . contains ( " foo " ) = = false ) ;
CHECK ( j_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " all types " )
{
SECTION ( " null " )
{
json j_nonobject ( json : : value_t : : null ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " string " )
{
json j_nonobject ( json : : value_t : : string ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " object " )
{
json j_nonobject ( json : : value_t : : object ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " array " )
{
json j_nonobject ( json : : value_t : : array ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " boolean " )
{
json j_nonobject ( json : : value_t : : boolean ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " number (integer) " )
{
json j_nonobject ( json : : value_t : : number_integer ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " number (unsigned) " )
{
json j_nonobject ( json : : value_t : : number_unsigned ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
SECTION ( " number (floating-point) " )
{
json j_nonobject ( json : : value_t : : number_float ) ;
const json j_nonobject_const ( j_nonobject ) ;
CHECK ( j_nonobject . contains ( " foo " ) = = false ) ;
CHECK ( j_nonobject_const . contains ( " foo " ) = = false ) ;
}
}
}
2016-08-05 03:55:47 +08:00
}
}
2017-01-17 05:11:07 +08:00
TEST_CASE ( " element access 2 (throwing tests) " , " [!throws] " )
{
SECTION ( " object " )
{
json j = { { " integer " , 1 } , { " unsigned " , 1u } , { " floating " , 42.23 } , { " null " , nullptr } , { " string " , " hello world " } , { " boolean " , true } , { " object " , json : : object ( ) } , { " array " , { 1 , 2 , 3 } } } ;
const json j_const = j ;
SECTION ( " access specified element with default value " )
{
SECTION ( " given a JSON pointer " )
{
SECTION ( " access non-existing value " )
{
CHECK ( j . value ( " /not/existing " _json_pointer , 2 ) = = 2 ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , 2u ) = = 2u ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , false ) = = false ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , " bar " ) = = " bar " ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , 12.34 ) = = Approx ( 12.34 ) ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , json ( { { " foo " , " bar " } } ) ) = = json ( { { " foo " , " bar " } } ) ) ;
CHECK ( j . value ( " /not/existing " _json_pointer , json ( { 10 , 100 } ) ) = = json ( { 10 , 100 } ) ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , 2 ) = = 2 ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , 2u ) = = 2u ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , false ) = = false ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , " bar " ) = = " bar " ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , 12.34 ) = = Approx ( 12.34 ) ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , json ( { { " foo " , " bar " } } ) ) = = json ( { { " foo " , " bar " } } ) ) ;
CHECK ( j_const . value ( " /not/existing " _json_pointer , json ( { 10 , 100 } ) ) = = json ( { 10 , 100 } ) ) ;
}
}
}
}
}