2016-08-04 21:55:47 +02:00
/*
__ _____ _____ _____
__ | | __ | | | | JSON for Modern C + + ( test suite )
2022-01-02 22:35:35 +01:00
| | | __ | | | | | | version 3.10 .5
2016-08-04 21:55:47 +02:00
| _____ | _____ | _____ | _ | ___ | https : //github.com/nlohmann/json
Licensed under the MIT License < http : //opensource.org/licenses/MIT>.
2018-05-03 17:41:45 +02:00
SPDX - License - Identifier : MIT
2022-01-02 22:35:35 +01:00
Copyright ( c ) 2013 - 2022 Niels Lohmann < http : //nlohmann.me>.
2016-08-04 21:55:47 +02: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 .
*/
2019-01-13 17:41:21 +01:00
# include "doctest_compatibility.h"
2016-08-04 21:55:47 +02:00
2018-01-29 11:21:11 +01:00
# include <nlohmann/json.hpp>
2016-08-04 21:55:47 +02:00
using nlohmann : : json ;
TEST_CASE ( " modifiers " )
{
SECTION ( " clear() " )
{
SECTION ( " boolean " )
{
json j = true ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : boolean ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " string " )
{
json j = " hello world " ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : string ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " array " )
{
SECTION ( " empty array " )
{
json j = json : : array ( ) ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j . empty ( ) ) ;
CHECK ( j = = json ( json : : value_t : : array ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " filled array " )
{
json j = { 1 , 2 , 3 } ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j . empty ( ) ) ;
CHECK ( j = = json ( json : : value_t : : array ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " object " )
{
SECTION ( " empty object " )
{
json j = json : : object ( ) ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j . empty ( ) ) ;
CHECK ( j = = json ( json : : value_t : : object ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " filled object " )
{
json j = { { " one " , 1 } , { " two " , 2 } , { " three " , 3 } } ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j . empty ( ) ) ;
CHECK ( j = = json ( json : : value_t : : object ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
}
2020-05-04 22:07:50 +02:00
SECTION ( " binary " )
{
SECTION ( " empty binary " )
{
2020-05-19 13:30:22 +02:00
json j = json : : binary ( { } ) ;
2020-05-04 22:07:50 +02:00
json k = j ;
j . clear ( ) ;
2020-06-03 21:22:07 +02:00
CHECK ( ! j . empty ( ) ) ;
2020-05-04 22:07:50 +02:00
CHECK ( j = = json ( json : : value_t : : binary ) ) ;
CHECK ( j = = json ( k . type ( ) ) ) ;
}
SECTION ( " filled binary " )
{
2020-05-19 13:30:22 +02:00
json j = json : : binary ( { 1 , 2 , 3 , 4 , 5 } ) ;
2020-05-04 22:07:50 +02:00
json k = j ;
j . clear ( ) ;
2020-06-03 21:22:07 +02:00
CHECK ( ! j . empty ( ) ) ;
2020-05-04 22:07:50 +02:00
CHECK ( j = = json ( json : : value_t : : binary ) ) ;
CHECK ( j = = json ( k . type ( ) ) ) ;
}
}
2016-08-04 21:55:47 +02:00
SECTION ( " number (integer) " )
{
json j = 23 ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : number_integer ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " number (unsigned) " )
{
json j = 23u ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : number_integer ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " number (float) " )
{
json j = 23.42 ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : number_float ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " null " )
{
json j = nullptr ;
2017-08-29 23:46:26 +02:00
json k = j ;
2016-08-04 21:55:47 +02:00
j . clear ( ) ;
CHECK ( j = = json ( json : : value_t : : null ) ) ;
2017-08-29 23:46:26 +02:00
CHECK ( j = = json ( k . type ( ) ) ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " push_back() " )
{
SECTION ( " to array " )
{
SECTION ( " json&& " )
{
SECTION ( " null " )
{
json j ;
j . push_back ( 1 ) ;
j . push_back ( 2 ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
j . push_back ( " Hello " ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , " Hello " } ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . push_back ( " Hello " ) , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " const json& " )
{
SECTION ( " null " )
{
json j ;
json k ( 1 ) ;
j . push_back ( k ) ;
j . push_back ( k ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 1 } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
json k ( " Hello " ) ;
j . push_back ( k ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , " Hello " } ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
json k ( " Hello " ) ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . push_back ( k ) , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
}
SECTION ( " to object " )
{
SECTION ( " null " )
{
json j ;
j . push_back ( json : : object_t : : value_type ( { " one " , 1 } ) ) ;
j . push_back ( json : : object_t : : value_type ( { " two " , 2 } ) ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j . size ( ) = = 2 ) ;
CHECK ( j [ " one " ] = = json ( 1 ) ) ;
CHECK ( j [ " two " ] = = json ( 2 ) ) ;
}
SECTION ( " object " )
{
json j ( json : : value_t : : object ) ;
j . push_back ( json : : object_t : : value_type ( { " one " , 1 } ) ) ;
j . push_back ( json : : object_t : : value_type ( { " two " , 2 } ) ) ;
CHECK ( j . size ( ) = = 2 ) ;
CHECK ( j [ " one " ] = = json ( 1 ) ) ;
CHECK ( j [ " two " ] = = json ( 2 ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
json k ( " Hello " ) ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . push_back ( json : : object_t : : value_type ( { " one " , 1 } ) ) , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " with initializer_list " )
{
SECTION ( " null " )
{
json j ;
j . push_back ( { " foo " , " bar " } ) ;
CHECK ( j = = json : : array ( { { " foo " , " bar " } } ) ) ;
json k ;
k . push_back ( { 1 , 2 , 3 } ) ;
CHECK ( k = = json : : array ( { { 1 , 2 , 3 } } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
j . push_back ( { " foo " , " bar " } ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , { " foo " , " bar " } } ) ) ;
json k = { 1 , 2 , 3 } ;
k . push_back ( { 1 , 2 , 3 } ) ;
CHECK ( k = = json ( { 1 , 2 , 3 , { 1 , 2 , 3 } } ) ) ;
}
SECTION ( " object " )
{
json j = { { " key1 " , 1 } } ;
j . push_back ( { " key2 " , " bar " } ) ;
CHECK ( j = = json ( { { " key1 " , 1 } , { " key2 " , " bar " } } ) ) ;
2017-10-22 08:53:27 +02:00
// invalid values (no string/val pair)
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . push_back ( { 1 } ) , " [json.exception.type_error.308] cannot use push_back() with object " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j . push_back ( { 1 , 2 } ) , " [json.exception.type_error.308] cannot use push_back() with object " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j . push_back ( { 1 , 2 , 3 , 4 } ) , " [json.exception.type_error.308] cannot use push_back() with object " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
}
2016-11-11 19:29:14 +01:00
SECTION ( " emplace_back() " )
{
SECTION ( " to array " )
{
SECTION ( " null " )
{
json j ;
2019-06-30 12:19:41 +02:00
auto & x1 = j . emplace_back ( 1 ) ;
CHECK ( x1 = = 1 ) ;
auto & x2 = j . emplace_back ( 2 ) ;
CHECK ( x2 = = 2 ) ;
2016-11-11 19:29:14 +01:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
2019-06-30 12:19:41 +02:00
auto & x = j . emplace_back ( " Hello " ) ;
CHECK ( x = = " Hello " ) ;
2016-11-11 19:29:14 +01:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , " Hello " } ) ) ;
}
SECTION ( " multiple values " )
{
json j ;
2019-06-30 12:19:41 +02:00
auto & x = j . emplace_back ( 3 , " foo " ) ;
CHECK ( x = = json ( { " foo " , " foo " , " foo " } ) ) ;
2016-11-11 19:29:14 +01:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { { " foo " , " foo " , " foo " } } ) ) ;
}
}
SECTION ( " other type " )
{
json j = 1 ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . emplace_back ( " Hello " ) , " [json.exception.type_error.311] cannot use emplace_back() with number " , json : : type_error & ) ;
2016-11-11 19:29:14 +01:00
}
}
SECTION ( " emplace() " )
{
SECTION ( " to object " )
{
SECTION ( " null " )
{
2016-11-28 18:33:46 +01:00
// start with a null value
2016-11-11 19:29:14 +01:00
json j ;
2016-11-28 18:33:46 +01:00
// add a new key
auto res1 = j . emplace ( " foo " , " bar " ) ;
CHECK ( res1 . second = = true ) ;
CHECK ( * res1 . first = = " bar " ) ;
// the null value is changed to an object
2016-11-11 19:29:14 +01:00
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
2016-11-28 18:33:46 +01:00
// add a new key
auto res2 = j . emplace ( " baz " , " bam " ) ;
CHECK ( res2 . second = = true ) ;
CHECK ( * res2 . first = = " bam " ) ;
// we try to insert at given key - no change
auto res3 = j . emplace ( " baz " , " bad " ) ;
CHECK ( res3 . second = = false ) ;
CHECK ( * res3 . first = = " bam " ) ;
// the final object
2016-11-11 19:29:14 +01:00
CHECK ( j = = json ( { { " baz " , " bam " } , { " foo " , " bar " } } ) ) ;
}
SECTION ( " object " )
{
2016-11-28 18:33:46 +01:00
// start with an object
2016-11-11 19:29:14 +01:00
json j = { { " foo " , " bar " } } ;
2016-11-28 18:33:46 +01:00
// add a new key
auto res1 = j . emplace ( " baz " , " bam " ) ;
CHECK ( res1 . second = = true ) ;
CHECK ( * res1 . first = = " bam " ) ;
// add an existing key
auto res2 = j . emplace ( " foo " , " bad " ) ;
CHECK ( res2 . second = = false ) ;
CHECK ( * res2 . first = = " bar " ) ;
// check final object
2016-11-11 19:29:14 +01:00
CHECK ( j = = json ( { { " baz " , " bam " } , { " foo " , " bar " } } ) ) ;
}
}
SECTION ( " other type " )
{
json j = 1 ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . emplace ( " foo " , " bar " ) , " [json.exception.type_error.311] cannot use emplace() with number " , json : : type_error & ) ;
2016-11-11 19:29:14 +01:00
}
}
2016-08-04 21:55:47 +02:00
SECTION ( " operator+= " )
{
SECTION ( " to array " )
{
SECTION ( " json&& " )
{
SECTION ( " null " )
{
json j ;
j + = 1 ;
j + = 2 ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
j + = " Hello " ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , " Hello " } ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j + = " Hello " , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " const json& " )
{
SECTION ( " null " )
{
json j ;
json k ( 1 ) ;
j + = k ;
j + = k ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 1 } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
json k ( " Hello " ) ;
j + = k ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , " Hello " } ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
json k ( " Hello " ) ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j + = k , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
}
SECTION ( " to object " )
{
SECTION ( " null " )
{
json j ;
j + = json : : object_t : : value_type ( { " one " , 1 } ) ;
j + = json : : object_t : : value_type ( { " two " , 2 } ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j . size ( ) = = 2 ) ;
CHECK ( j [ " one " ] = = json ( 1 ) ) ;
CHECK ( j [ " two " ] = = json ( 2 ) ) ;
}
SECTION ( " object " )
{
json j ( json : : value_t : : object ) ;
j + = json : : object_t : : value_type ( { " one " , 1 } ) ;
j + = json : : object_t : : value_type ( { " two " , 2 } ) ;
CHECK ( j . size ( ) = = 2 ) ;
CHECK ( j [ " one " ] = = json ( 1 ) ) ;
CHECK ( j [ " two " ] = = json ( 2 ) ) ;
}
SECTION ( " other type " )
{
json j = 1 ;
json k ( " Hello " ) ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j + = json : : object_t : : value_type ( { " one " , 1 } ) , " [json.exception.type_error.308] cannot use push_back() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " with initializer_list " )
{
SECTION ( " null " )
{
json j ;
j + = { " foo " , " bar " } ;
CHECK ( j = = json : : array ( { { " foo " , " bar " } } ) ) ;
json k ;
k + = { 1 , 2 , 3 } ;
CHECK ( k = = json : : array ( { { 1 , 2 , 3 } } ) ) ;
}
SECTION ( " array " )
{
json j = { 1 , 2 , 3 } ;
j + = { " foo " , " bar " } ;
CHECK ( j = = json ( { 1 , 2 , 3 , { " foo " , " bar " } } ) ) ;
json k = { 1 , 2 , 3 } ;
k + = { 1 , 2 , 3 } ;
CHECK ( k = = json ( { 1 , 2 , 3 , { 1 , 2 , 3 } } ) ) ;
}
SECTION ( " object " )
{
json j = { { " key1 " , 1 } } ;
j + = { " key2 " , " bar " } ;
CHECK ( j = = json ( { { " key1 " , 1 } , { " key2 " , " bar " } } ) ) ;
json k = { { " key1 " , 1 } } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( ( k + = { 1 , 2 , 3 , 4 } ) , " [json.exception.type_error.308] cannot use push_back() with object " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
}
2017-08-02 22:44:58 +02:00
SECTION ( " insert() " )
2016-08-04 21:55:47 +02:00
{
json j_array = { 1 , 2 , 3 , 4 } ;
json j_value = 5 ;
SECTION ( " value at position " )
{
SECTION ( " insert before begin() " )
{
auto it = j_array . insert ( j_array . begin ( ) , j_value ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( j_array . begin ( ) = = it ) ;
CHECK ( j_array = = json ( { 5 , 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " insert in the middle " )
{
auto it = j_array . insert ( j_array . begin ( ) + 2 , j_value ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( it - j_array . begin ( ) ) = = 2 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 5 , 3 , 4 } ) ) ;
}
SECTION ( " insert before end() " )
{
auto it = j_array . insert ( j_array . end ( ) , j_value ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( j_array . end ( ) - it ) = = 1 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 , 5 } ) ) ;
}
}
SECTION ( " rvalue at position " )
{
SECTION ( " insert before begin() " )
{
auto it = j_array . insert ( j_array . begin ( ) , 5 ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( j_array . begin ( ) = = it ) ;
CHECK ( j_array = = json ( { 5 , 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " insert in the middle " )
{
auto it = j_array . insert ( j_array . begin ( ) + 2 , 5 ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( it - j_array . begin ( ) ) = = 2 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 5 , 3 , 4 } ) ) ;
}
SECTION ( " insert before end() " )
{
auto it = j_array . insert ( j_array . end ( ) , 5 ) ;
CHECK ( j_array . size ( ) = = 5 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( j_array . end ( ) - it ) = = 1 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 , 5 } ) ) ;
}
}
SECTION ( " copies at position " )
{
SECTION ( " insert before begin() " )
{
auto it = j_array . insert ( j_array . begin ( ) , 3 , 5 ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( j_array . begin ( ) = = it ) ;
CHECK ( j_array = = json ( { 5 , 5 , 5 , 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " insert in the middle " )
{
auto it = j_array . insert ( j_array . begin ( ) + 2 , 3 , 5 ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( it - j_array . begin ( ) ) = = 2 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 5 , 5 , 5 , 3 , 4 } ) ) ;
}
SECTION ( " insert before end() " )
{
auto it = j_array . insert ( j_array . end ( ) , 3 , 5 ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = j_value ) ;
CHECK ( ( j_array . end ( ) - it ) = = 3 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 , 5 , 5 , 5 } ) ) ;
}
SECTION ( " insert nothing (count = 0) " )
{
auto it = j_array . insert ( j_array . end ( ) , 0 , 5 ) ;
CHECK ( j_array . size ( ) = = 4 ) ;
2017-03-09 18:20:26 +01:00
// the returned iterator points to the first inserted element;
// there were 4 elements, so it should point to the 5th
CHECK ( it = = j_array . begin ( ) + 4 ) ;
2016-08-04 21:55:47 +02:00
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 } ) ) ;
}
}
2017-04-07 18:29:09 +02:00
SECTION ( " range for array " )
2016-08-04 21:55:47 +02:00
{
json j_other_array = { " first " , " second " } ;
SECTION ( " proper usage " )
{
auto it = j_array . insert ( j_array . end ( ) , j_other_array . begin ( ) , j_other_array . end ( ) ) ;
CHECK ( j_array . size ( ) = = 6 ) ;
CHECK ( * it = = * j_other_array . begin ( ) ) ;
CHECK ( ( j_array . end ( ) - it ) = = 2 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 , " first " , " second " } ) ) ;
}
SECTION ( " empty range " )
{
auto it = j_array . insert ( j_array . end ( ) , j_other_array . begin ( ) , j_other_array . begin ( ) ) ;
CHECK ( j_array . size ( ) = = 4 ) ;
CHECK ( it = = j_array . end ( ) ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " invalid iterators " )
{
json j_other_array2 = { " first " , " second " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_array . insert ( j_array . end ( ) , j_array . begin ( ) , j_array . end ( ) ) , " [json.exception.invalid_iterator.211] passed iterators may not belong to container " ,
json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_array . insert ( j_array . end ( ) , j_other_array . begin ( ) , j_other_array2 . end ( ) ) , " [json.exception.invalid_iterator.210] iterators do not fit " ,
json : : invalid_iterator & ) ;
2016-08-04 21:55:47 +02:00
}
}
2017-04-07 18:29:09 +02:00
SECTION ( " range for object " )
{
json j_object1 = { { " one " , " eins " } , { " two " , " zwei " } } ;
json j_object2 = { { " eleven " , " elf " } , { " seventeen " , " siebzehn " } } ;
SECTION ( " proper usage " )
{
j_object1 . insert ( j_object2 . begin ( ) , j_object2 . end ( ) ) ;
CHECK ( j_object1 . size ( ) = = 4 ) ;
}
SECTION ( " empty range " )
{
j_object1 . insert ( j_object2 . begin ( ) , j_object2 . begin ( ) ) ;
CHECK ( j_object1 . size ( ) = = 2 ) ;
}
SECTION ( " invalid iterators " )
{
json j_other_array2 = { " first " , " second " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_array . insert ( j_object2 . begin ( ) , j_object2 . end ( ) ) , " [json.exception.type_error.309] cannot use insert() with array " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_object1 . insert ( j_object1 . begin ( ) , j_object2 . end ( ) ) , " [json.exception.invalid_iterator.210] iterators do not fit " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_object1 . insert ( j_array . begin ( ) , j_array . end ( ) ) , " [json.exception.invalid_iterator.202] iterators first and last must point to objects " , json : : invalid_iterator & ) ;
2017-04-07 18:29:09 +02:00
}
}
2016-08-04 21:55:47 +02:00
SECTION ( " initializer list at position " )
{
SECTION ( " insert before begin() " )
{
auto it = j_array . insert ( j_array . begin ( ) , { 7 , 8 , 9 } ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = json ( 7 ) ) ;
CHECK ( j_array . begin ( ) = = it ) ;
CHECK ( j_array = = json ( { 7 , 8 , 9 , 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " insert in the middle " )
{
auto it = j_array . insert ( j_array . begin ( ) + 2 , { 7 , 8 , 9 } ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = json ( 7 ) ) ;
CHECK ( ( it - j_array . begin ( ) ) = = 2 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 7 , 8 , 9 , 3 , 4 } ) ) ;
}
SECTION ( " insert before end() " )
{
auto it = j_array . insert ( j_array . end ( ) , { 7 , 8 , 9 } ) ;
CHECK ( j_array . size ( ) = = 7 ) ;
CHECK ( * it = = json ( 7 ) ) ;
CHECK ( ( j_array . end ( ) - it ) = = 3 ) ;
CHECK ( j_array = = json ( { 1 , 2 , 3 , 4 , 7 , 8 , 9 } ) ) ;
}
}
SECTION ( " invalid iterator " )
{
// pass iterator to a different array
json j_another_array = { 1 , 2 } ;
json j_yet_another_array = { " first " , " second " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_array . insert ( j_another_array . end ( ) , 10 ) , " [json.exception.invalid_iterator.202] iterator does not fit current value " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_array . insert ( j_another_array . end ( ) , j_value ) , " [json.exception.invalid_iterator.202] iterator does not fit current value " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_array . insert ( j_another_array . end ( ) , 10 , 11 ) , " [json.exception.invalid_iterator.202] iterator does not fit current value " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_array . insert ( j_another_array . end ( ) , j_yet_another_array . begin ( ) , j_yet_another_array . end ( ) ) , " [json.exception.invalid_iterator.202] iterator does not fit current value " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_array . insert ( j_another_array . end ( ) , { 1 , 2 , 3 , 4 } ) , " [json.exception.invalid_iterator.202] iterator does not fit current value " , json : : invalid_iterator & ) ;
2016-08-04 21:55:47 +02:00
}
SECTION ( " non-array type " )
{
// call insert on a non-array type
json j_nonarray = 3 ;
json j_yet_another_array = { " first " , " second " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_nonarray . insert ( j_nonarray . end ( ) , 10 ) , " [json.exception.type_error.309] cannot use insert() with number " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_nonarray . insert ( j_nonarray . end ( ) , j_value ) , " [json.exception.type_error.309] cannot use insert() with number " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_nonarray . insert ( j_nonarray . end ( ) , 10 , 11 ) , " [json.exception.type_error.309] cannot use insert() with number " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_nonarray . insert ( j_nonarray . end ( ) , j_yet_another_array . begin ( ) , j_yet_another_array . end ( ) ) , " [json.exception.type_error.309] cannot use insert() with number " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_nonarray . insert ( j_nonarray . end ( ) , { 1 , 2 , 3 , 4 } ) , " [json.exception.type_error.309] cannot use insert() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
2017-08-02 22:44:58 +02:00
SECTION ( " update() " )
{
2021-11-03 13:52:20 +01:00
SECTION ( " non-recursive (default) " )
2017-08-02 22:44:58 +02:00
{
2021-11-03 13:52:20 +01:00
json j_object1 = { { " one " , " eins " } , { " two " , " zwei " } } ;
json j_object2 = { { " three " , " drei " } , { " two " , " zwo " } } ;
json j_array = { 1 , 2 , 3 , 4 } ;
SECTION ( " const reference " )
2017-08-02 22:44:58 +02:00
{
2021-11-03 13:52:20 +01:00
SECTION ( " proper usage " )
{
j_object1 . update ( j_object2 ) ;
CHECK ( j_object1 = = json ( { { " one " , " eins " } , { " two " , " zwo " } , { " three " , " drei " } } ) ) ;
2017-08-03 17:47:42 +02:00
2021-11-03 13:52:20 +01:00
json j_null ;
j_null . update ( j_object2 ) ;
CHECK ( j_null = = j_object2 ) ;
}
2017-08-03 17:47:42 +02:00
2021-11-03 13:52:20 +01:00
SECTION ( " wrong types " )
{
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_array . update ( j_object1 ) , " [json.exception.type_error.312] cannot use update() with array " , json : : type_error & ) ;
2017-08-03 17:47:42 +02:00
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_object1 . update ( j_array ) , " [json.exception.type_error.312] cannot use update() with array " , json : : type_error & ) ;
2021-11-03 13:52:20 +01:00
}
2017-08-02 22:44:58 +02:00
}
2021-11-03 13:52:20 +01:00
SECTION ( " iterator range " )
2017-08-02 22:44:58 +02:00
{
2021-11-03 13:52:20 +01:00
SECTION ( " proper usage " )
{
j_object1 . update ( j_object2 . begin ( ) , j_object2 . end ( ) ) ;
CHECK ( j_object1 = = json ( { { " one " , " eins " } , { " two " , " zwo " } , { " three " , " drei " } } ) ) ;
2017-08-03 17:47:42 +02:00
2021-11-03 13:52:20 +01:00
json j_null ;
j_null . update ( j_object2 . begin ( ) , j_object2 . end ( ) ) ;
CHECK ( j_null = = j_object2 ) ;
}
2017-08-02 22:44:58 +02:00
2021-11-03 13:52:20 +01:00
SECTION ( " empty range " )
{
j_object1 . update ( j_object2 . begin ( ) , j_object2 . begin ( ) ) ;
CHECK ( j_object1 = = json ( { { " one " , " eins " } , { " two " , " zwei " } } ) ) ;
}
SECTION ( " invalid iterators " )
{
json j_other_array2 = { " first " , " second " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j_array . update ( j_object2 . begin ( ) , j_object2 . end ( ) ) , " [json.exception.type_error.312] cannot use update() with array " , json : : type_error & ) ;
CHECK_THROWS_WITH_AS ( j_object1 . update ( j_object1 . begin ( ) , j_object2 . end ( ) ) , " [json.exception.invalid_iterator.210] iterators do not fit " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( j_object1 . update ( j_array . begin ( ) , j_array . end ( ) ) , " [json.exception.type_error.312] cannot use update() with array " , json : : type_error & ) ;
2021-11-03 13:52:20 +01:00
}
2017-08-02 22:44:58 +02:00
}
2021-11-03 13:52:20 +01:00
}
2017-08-02 22:44:58 +02:00
2021-11-03 13:52:20 +01:00
SECTION ( " recursive " )
{
SECTION ( " const reference " )
2017-08-02 22:44:58 +02:00
{
2021-11-03 13:52:20 +01:00
SECTION ( " extend object " )
{
json j1 = { { " string " , " s " } , { " numbers " , { { " one " , 1 } } } } ;
json j2 = { { " string " , " t " } , { " numbers " , { { " two " , 2 } } } } ;
j1 . update ( j2 , true ) ;
CHECK ( j1 = = json ( { { " string " , " t " } , { " numbers " , { { " one " , 1 } , { " two " , 2 } } } } ) ) ;
}
2017-08-02 22:44:58 +02:00
2021-11-03 13:52:20 +01:00
SECTION ( " replace object " )
{
json j1 = { { " string " , " s " } , { " numbers " , { { " one " , 1 } } } } ;
json j2 = { { " string " , " t " } , { " numbers " , 1 } } ;
j1 . update ( j2 , true ) ;
CHECK ( j1 = = json ( { { " string " , " t " } , { " numbers " , 1 } } ) ) ;
}
2017-08-02 22:44:58 +02:00
}
}
}
2016-08-04 21:55:47 +02:00
SECTION ( " swap() " )
{
SECTION ( " json " )
{
SECTION ( " member swap " )
{
json j ( " hello world " ) ;
json k ( 42.23 ) ;
j . swap ( k ) ;
CHECK ( j = = json ( 42.23 ) ) ;
CHECK ( k = = json ( " hello world " ) ) ;
}
SECTION ( " nonmember swap " )
{
json j ( " hello world " ) ;
json k ( 42.23 ) ;
2020-06-06 18:28:52 +02:00
using std : : swap ;
swap ( j , k ) ;
2016-08-04 21:55:47 +02:00
CHECK ( j = = json ( 42.23 ) ) ;
CHECK ( k = = json ( " hello world " ) ) ;
}
}
SECTION ( " array_t " )
{
SECTION ( " array_t type " )
{
json j = { 1 , 2 , 3 , 4 } ;
json : : array_t a = { " foo " , " bar " , " baz " } ;
j . swap ( a ) ;
CHECK ( j = = json ( { " foo " , " bar " , " baz " } ) ) ;
j . swap ( a ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , 4 } ) ) ;
}
SECTION ( " non-array_t type " )
{
json j = 17 ;
json : : array_t a = { " foo " , " bar " , " baz " } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . swap ( a ) , " [json.exception.type_error.310] cannot use swap() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " object_t " )
{
SECTION ( " object_t type " )
{
json j = { { " one " , 1 } , { " two " , 2 } } ;
json : : object_t o = { { " cow " , " Kuh " } , { " chicken " , " Huhn " } } ;
j . swap ( o ) ;
CHECK ( j = = json ( { { " cow " , " Kuh " } , { " chicken " , " Huhn " } } ) ) ;
j . swap ( o ) ;
CHECK ( j = = json ( { { " one " , 1 } , { " two " , 2 } } ) ) ;
}
SECTION ( " non-object_t type " )
{
json j = 17 ;
json : : object_t o = { { " cow " , " Kuh " } , { " chicken " , " Huhn " } } ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . swap ( o ) , " [json.exception.type_error.310] cannot use swap() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
SECTION ( " string_t " )
{
SECTION ( " string_t type " )
{
json j = " Hello world " ;
json : : string_t s = " Hallo Welt " ;
j . swap ( s ) ;
CHECK ( j = = json ( " Hallo Welt " ) ) ;
j . swap ( s ) ;
CHECK ( j = = json ( " Hello world " ) ) ;
}
SECTION ( " non-string_t type " )
{
json j = 17 ;
json : : string_t s = " Hallo Welt " ;
2022-03-24 15:55:35 +01:00
CHECK_THROWS_WITH_AS ( j . swap ( s ) , " [json.exception.type_error.310] cannot use swap() with number " , json : : type_error & ) ;
2016-08-04 21:55:47 +02:00
}
}
2020-05-04 22:07:50 +02:00
SECTION ( " binary_t " )
{
SECTION ( " binary_t type " )
{
2020-05-19 13:30:22 +02:00
json j = json : : binary ( { 1 , 2 , 3 , 4 } ) ;
2020-05-17 22:50:27 +02:00
json : : binary_t s = { { 5 , 6 , 7 , 8 } } ;
j . swap ( s ) ;
2020-05-19 13:30:22 +02:00
CHECK ( j = = json : : binary ( { 5 , 6 , 7 , 8 } ) ) ;
2020-05-04 22:07:50 +02:00
j . swap ( s ) ;
2020-05-19 13:30:22 +02:00
CHECK ( j = = json : : binary ( { 1 , 2 , 3 , 4 } ) ) ;
2020-05-17 22:50:27 +02:00
}
SECTION ( " binary_t::container_type type " )
{
2020-05-19 13:30:22 +02:00
json j = json : : binary ( { 1 , 2 , 3 , 4 } ) ;
2020-05-17 22:50:27 +02:00
std : : vector < std : : uint8_t > s = { { 5 , 6 , 7 , 8 } } ;
j . swap ( s ) ;
2020-05-19 13:30:22 +02:00
CHECK ( j = = json : : binary ( { 5 , 6 , 7 , 8 } ) ) ;
2020-05-04 22:07:50 +02:00
j . swap ( s ) ;
2020-05-19 13:30:22 +02:00
CHECK ( j = = json : : binary ( { 1 , 2 , 3 , 4 } ) ) ;
2020-05-04 22:07:50 +02:00
}
2020-05-17 22:50:27 +02:00
SECTION ( " non-binary_t type " )
2020-05-04 22:07:50 +02:00
{
json j = 17 ;
2020-05-18 12:33:26 +02:00
json : : binary_t s1 = { { 1 , 2 , 3 , 4 } } ;
std : : vector < std : : uint8_t > s2 = { { 5 , 6 , 7 , 8 } } ;
2020-05-04 22:07:50 +02:00
2020-05-18 12:33:26 +02:00
CHECK_THROWS_WITH_AS ( j . swap ( s1 ) , " [json.exception.type_error.310] cannot use swap() with number " , json : : type_error ) ;
CHECK_THROWS_WITH_AS ( j . swap ( s2 ) , " [json.exception.type_error.310] cannot use swap() with number " , json : : type_error ) ;
2020-05-04 22:07:50 +02:00
}
}
2016-08-04 21:55:47 +02:00
}
}