2016-08-04 22:55:47 +03:00
/*
__ _____ _____ _____
__ | | __ | | | | JSON for Modern C + + ( test suite )
2022-01-03 00:35:35 +03:00
| | | __ | | | | | | version 3.10 .5
2016-08-04 22:55:47 +03:00
| _____ | _____ | _____ | _ | ___ | https : //github.com/nlohmann/json
Licensed under the MIT License < http : //opensource.org/licenses/MIT>.
2018-05-03 18:41:45 +03:00
SPDX - License - Identifier : MIT
2022-01-03 00:35:35 +03:00
Copyright ( c ) 2013 - 2022 Niels Lohmann < http : //nlohmann.me>.
2016-08-04 22:55:47 +03: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 19:41:21 +03:00
# include "doctest_compatibility.h"
2016-08-04 22:55:47 +03:00
2020-08-12 14:30:06 +03:00
# define JSON_TESTS_PRIVATE
2018-01-29 13:21:11 +03:00
# include <nlohmann/json.hpp>
2016-08-04 22:55:47 +03:00
using nlohmann : : json ;
# include <deque>
# include <forward_list>
# include <fstream>
# include <list>
2019-01-13 19:41:21 +03:00
# include <set>
2016-08-04 22:55:47 +03:00
# include <unordered_map>
# include <unordered_set>
2017-08-23 00:28:23 +03:00
# include <valarray>
2016-08-04 22:55:47 +03:00
TEST_CASE ( " constructors " )
{
SECTION ( " create an empty value with a given type " )
{
SECTION ( " null " )
{
auto t = json : : value_t : : null ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
}
SECTION ( " discarded " )
{
auto t = json : : value_t : : discarded ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
}
SECTION ( " object " )
{
auto t = json : : value_t : : object ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
}
SECTION ( " array " )
{
auto t = json : : value_t : : array ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
}
SECTION ( " boolean " )
{
auto t = json : : value_t : : boolean ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2017-10-22 09:53:27 +03:00
CHECK ( j = = false ) ;
2016-08-04 22:55:47 +03:00
}
SECTION ( " string " )
{
auto t = json : : value_t : : string ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2017-10-22 09:53:27 +03:00
CHECK ( j = = " " ) ;
2016-08-04 22:55:47 +03:00
}
SECTION ( " number_integer " )
{
auto t = json : : value_t : : number_integer ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2017-10-22 09:53:27 +03:00
CHECK ( j = = 0 ) ;
2016-08-04 22:55:47 +03:00
}
SECTION ( " number_unsigned " )
{
auto t = json : : value_t : : number_unsigned ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2017-10-22 09:53:27 +03:00
CHECK ( j = = 0 ) ;
2016-08-04 22:55:47 +03:00
}
SECTION ( " number_float " )
{
auto t = json : : value_t : : number_float ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2017-10-22 09:53:27 +03:00
CHECK ( j = = 0.0 ) ;
2016-08-04 22:55:47 +03:00
}
2020-05-09 14:46:24 +03:00
SECTION ( " binary " )
{
auto t = json : : value_t : : binary ;
json j ( t ) ;
CHECK ( j . type ( ) = = t ) ;
2020-05-19 14:30:22 +03:00
CHECK ( j = = json : : binary ( { } ) ) ;
2020-05-09 14:46:24 +03:00
}
2016-08-04 22:55:47 +03:00
}
SECTION ( " create a null object (implicitly) " )
{
SECTION ( " no parameter " )
{
json j { } ;
CHECK ( j . type ( ) = = json : : value_t : : null ) ;
}
}
SECTION ( " create a null object (explicitly) " )
{
SECTION ( " parameter " )
{
json j ( nullptr ) ;
CHECK ( j . type ( ) = = json : : value_t : : null ) ;
}
}
SECTION ( " create an object (explicit) " )
{
SECTION ( " empty object " )
{
json : : object_t o ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
SECTION ( " filled object " )
{
json : : object_t o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
}
SECTION ( " create an object (implicit) " )
{
// reference object
json : : object_t o_reference { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j_reference ( o_reference ) ;
SECTION ( " std::map<json::string_t, json> " )
{
std : : map < json : : string_t , json > o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
2017-06-06 15:18:32 +03:00
SECTION ( " std::map<std::string, std::string> #600 " )
{
std : : map < std : : string , std : : string > m ;
m [ " a " ] = " b " ;
m [ " c " ] = " d " ;
m [ " e " ] = " f " ;
json j ( m ) ;
CHECK ( ( j . get < decltype ( m ) > ( ) = = m ) ) ;
2017-06-06 14:44:35 +03:00
}
2016-08-04 22:55:47 +03:00
SECTION ( " std::map<const char*, json> " )
{
std : : map < const char * , json > o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
2017-06-06 14:44:35 +03:00
2016-08-04 22:55:47 +03:00
SECTION ( " std::multimap<json::string_t, json> " )
{
std : : multimap < json : : string_t , json > o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " std::unordered_map<json::string_t, json> " )
{
std : : unordered_map < json : : string_t , json > o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " std::unordered_multimap<json::string_t, json> " )
{
std : : unordered_multimap < json : : string_t , json > o { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ;
json j ( o ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " associative container literal " )
{
json j ( { { " a " , json ( 1 ) } , { " b " , json ( 1u ) } , { " c " , json ( 2.2 ) } , { " d " , json ( false ) } , { " e " , json ( " string " ) } , { " f " , json ( ) } } ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
CHECK ( j = = j_reference ) ;
}
}
SECTION ( " create an array (explicit) " )
{
SECTION ( " empty array " )
{
json : : array_t a ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " filled array " )
{
json : : array_t a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " create an array (implicit) " )
{
// reference array
json : : array_t a_reference { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j_reference ( a_reference ) ;
SECTION ( " std::list<json> " )
{
std : : list < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
}
2017-06-17 15:24:07 +03:00
SECTION ( " std::pair " )
{
2017-10-17 09:23:55 +03:00
std : : pair < float , std : : string > p { 1.0f , " string " } ;
2017-06-17 15:24:07 +03:00
json j ( p ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
2017-08-23 00:40:10 +03:00
CHECK ( j . get < decltype ( p ) > ( ) = = p ) ;
2017-06-17 15:24:07 +03:00
REQUIRE ( j . size ( ) = = 2 ) ;
CHECK ( j [ 0 ] = = std : : get < 0 > ( p ) ) ;
CHECK ( j [ 1 ] = = std : : get < 1 > ( p ) ) ;
}
SECTION ( " std::pair with discarded values " )
{
json j { 1 , 2.0 , " string " } ;
const auto p = j . get < std : : pair < int , float > > ( ) ;
CHECK ( p . first = = j [ 0 ] ) ;
CHECK ( p . second = = j [ 1 ] ) ;
}
SECTION ( " std::tuple " )
{
2017-08-23 00:40:10 +03:00
const auto t = std : : make_tuple ( 1.0 , std : : string { " string " } , 42 , std : : vector < int > { 0 , 1 } ) ;
2017-06-17 15:24:07 +03:00
json j ( t ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
REQUIRE ( j . size ( ) = = 4 ) ;
2017-08-23 00:40:10 +03:00
CHECK ( j . get < decltype ( t ) > ( ) = = t ) ;
2017-06-17 15:24:07 +03:00
CHECK ( j [ 0 ] = = std : : get < 0 > ( t ) ) ;
CHECK ( j [ 1 ] = = std : : get < 1 > ( t ) ) ;
CHECK ( j [ 2 ] = = std : : get < 2 > ( t ) ) ;
CHECK ( j [ 3 ] [ 0 ] = = 0 ) ;
CHECK ( j [ 3 ] [ 1 ] = = 1 ) ;
}
SECTION ( " std::tuple with discarded values " )
{
json j { 1 , 2.0 , " string " , 42 } ;
const auto t = j . get < std : : tuple < int , float , std : : string > > ( ) ;
CHECK ( std : : get < 0 > ( t ) = = j [ 0 ] ) ;
CHECK ( std : : get < 1 > ( t ) = = j [ 1 ] ) ;
CHECK ( std : : get < 2 > ( t ) = = j [ 2 ] ) ;
}
2017-06-19 13:03:38 +03:00
SECTION ( " std::pair/tuple/array failures " )
2017-06-17 15:24:07 +03:00
{
json j { 1 } ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( ( j . get < std : : pair < int , int > > ( ) ) , " [json.exception.out_of_range.401] array index 1 is out of range " , json : : out_of_range & ) ;
CHECK_THROWS_WITH_AS ( ( j . get < std : : tuple < int , int > > ( ) ) , " [json.exception.out_of_range.401] array index 1 is out of range " , json : : out_of_range & ) ;
CHECK_THROWS_WITH_AS ( ( j . get < std : : array < int , 3 > > ( ) ) , " [json.exception.out_of_range.401] array index 1 is out of range " , json : : out_of_range & ) ;
2017-06-17 15:24:07 +03:00
}
2016-08-04 22:55:47 +03:00
SECTION ( " std::forward_list<json> " )
{
std : : forward_list < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
}
2017-06-19 13:03:38 +03:00
SECTION ( " std::array<json, 6> " )
2016-08-04 22:55:47 +03:00
{
std : : array < json , 6 > a { { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
2017-06-19 13:03:38 +03:00
const auto a2 = j . get < std : : array < json , 6 > > ( ) ;
CHECK ( a2 = = a ) ;
2016-08-04 22:55:47 +03:00
}
2017-08-23 00:28:23 +03:00
SECTION ( " std::valarray<int> " )
{
std : : valarray < int > va = { 1 , 2 , 3 , 4 , 5 } ;
json j ( va ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1 , 2 , 3 , 4 , 5 } ) ) ;
2020-07-16 12:11:35 +03:00
auto jva = j . get < std : : valarray < int > > ( ) ;
2017-08-23 00:28:23 +03:00
CHECK ( jva . size ( ) = = va . size ( ) ) ;
for ( size_t i = 0 ; i < jva . size ( ) ; + + i )
{
CHECK ( va [ i ] = = jva [ i ] ) ;
}
}
SECTION ( " std::valarray<double> " )
{
std : : valarray < double > va = { 1.2 , 2.3 , 3.4 , 4.5 , 5.6 } ;
json j ( va ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = json ( { 1.2 , 2.3 , 3.4 , 4.5 , 5.6 } ) ) ;
2020-07-16 12:11:35 +03:00
auto jva = j . get < std : : valarray < double > > ( ) ;
2017-08-23 00:28:23 +03:00
CHECK ( jva . size ( ) = = va . size ( ) ) ;
for ( size_t i = 0 ; i < jva . size ( ) ; + + i )
{
CHECK ( va [ i ] = = jva [ i ] ) ;
}
}
2016-08-04 22:55:47 +03:00
SECTION ( " std::vector<json> " )
{
std : : vector < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " std::deque<json> " )
{
std : : deque < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " std::set<json> " )
{
std : : set < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
// we cannot really check for equality here
}
SECTION ( " std::unordered_set<json> " )
{
std : : unordered_set < json > a { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ;
json j ( a ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
// we cannot really check for equality here
}
SECTION ( " sequence container literal " )
{
json j ( { json ( 1 ) , json ( 1u ) , json ( 2.2 ) , json ( false ) , json ( " string " ) , json ( ) } ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
CHECK ( j = = j_reference ) ;
}
}
SECTION ( " create a string (explicit) " )
{
SECTION ( " empty string " )
{
json : : string_t s ;
json j ( s ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
}
SECTION ( " filled string " )
{
json : : string_t s { " Hello world " } ;
json j ( s ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
}
}
SECTION ( " create a string (implicit) " )
{
// reference string
json : : string_t s_reference { " Hello world " } ;
json j_reference ( s_reference ) ;
SECTION ( " std::string " )
{
std : : string s { " Hello world " } ;
json j ( s ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " char[] " )
{
2021-03-24 09:15:18 +03:00
char s [ ] { " Hello world " } ; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
2016-08-04 22:55:47 +03:00
json j ( s ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " const char* " )
{
const char * s { " Hello world " } ;
json j ( s ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " string literal " )
{
json j ( " Hello world " ) ;
CHECK ( j . type ( ) = = json : : value_t : : string ) ;
CHECK ( j = = j_reference ) ;
}
}
SECTION ( " create a boolean (explicit) " )
{
SECTION ( " empty boolean " )
{
json : : boolean_t b { } ;
json j ( b ) ;
CHECK ( j . type ( ) = = json : : value_t : : boolean ) ;
}
SECTION ( " filled boolean (true) " )
{
json j ( true ) ;
CHECK ( j . type ( ) = = json : : value_t : : boolean ) ;
}
SECTION ( " filled boolean (false) " )
{
json j ( false ) ;
CHECK ( j . type ( ) = = json : : value_t : : boolean ) ;
}
2022-06-13 14:21:55 +03:00
SECTION ( " from std::vector<bool>::refrence " )
{
std : : vector < bool > v { true } ;
json j ( v [ 0 ] ) ;
CHECK ( j . type ( ) = = json : : value_t : : boolean ) ;
}
2016-08-04 22:55:47 +03:00
}
2020-05-15 15:12:32 +03:00
SECTION ( " create a binary (explicit) " )
{
SECTION ( " empty binary " )
{
2020-05-17 23:50:27 +03:00
json : : binary_t b { } ;
2020-05-15 15:12:32 +03:00
json j ( b ) ;
CHECK ( j . type ( ) = = json : : value_t : : binary ) ;
}
SECTION ( " filled binary " )
{
2020-05-17 23:50:27 +03:00
json : : binary_t b ( { 1 , 2 , 3 } ) ;
2020-05-15 15:12:32 +03:00
json j ( b ) ;
CHECK ( j . type ( ) = = json : : value_t : : binary ) ;
}
}
2016-08-04 22:55:47 +03:00
SECTION ( " create an integer number (explicit) " )
{
SECTION ( " uninitialized value " )
{
json : : number_integer_t n { } ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
}
SECTION ( " initialized value " )
{
json : : number_integer_t n ( 42 ) ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
}
}
SECTION ( " create an integer number (implicit) " )
{
// reference objects
json : : number_integer_t n_reference = 42 ;
json j_reference ( n_reference ) ;
json : : number_unsigned_t n_unsigned_reference = 42 ;
json j_unsigned_reference ( n_unsigned_reference ) ;
SECTION ( " short " )
{
short n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " unsigned short " )
{
unsigned short n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " int " )
{
int n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " unsigned int " )
{
unsigned int n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " long " )
{
long n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " unsigned long " )
{
unsigned long n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " long long " )
{
long long n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " unsigned long long " )
{
unsigned long long n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " int8_t " )
{
int8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int16_t " )
{
int16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int32_t " )
{
int32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int64_t " )
{
int64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_fast8_t " )
{
int_fast8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_fast16_t " )
{
int_fast16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_fast32_t " )
{
int_fast32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_fast64_t " )
{
int_fast64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_least8_t " )
{
int_least8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_least16_t " )
{
int_least16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_least32_t " )
{
int_least32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " int_least64_t " )
{
int_least64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " uint8_t " )
{
uint8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint16_t " )
{
uint16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint32_t " )
{
uint32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint64_t " )
{
uint64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_fast8_t " )
{
uint_fast8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_fast16_t " )
{
uint_fast16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_fast32_t " )
{
uint_fast32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_fast64_t " )
{
uint_fast64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_least8_t " )
{
uint_least8_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_least16_t " )
{
uint_least16_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_least32_t " )
{
uint_least32_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " uint_least64_t " )
{
uint_least64_t n = 42 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " integer literal without suffix " )
{
json j ( 42 ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " integer literal with u suffix " )
{
json j ( 42u ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " integer literal with l suffix " )
{
2021-03-24 09:15:18 +03:00
json j ( 42L ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " integer literal with ul suffix " )
{
json j ( 42ul ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
SECTION ( " integer literal with ll suffix " )
{
2021-03-24 09:15:18 +03:00
json j ( 42LL ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : number_integer ) ;
CHECK ( j = = j_reference ) ;
}
SECTION ( " integer literal with ull suffix " )
{
json j ( 42ull ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_unsigned ) ;
CHECK ( j = = j_unsigned_reference ) ;
}
}
SECTION ( " create a floating-point number (explicit) " )
{
SECTION ( " uninitialized value " )
{
json : : number_float_t n { } ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
}
SECTION ( " initialized value " )
{
json : : number_float_t n ( 42.23 ) ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
}
2017-02-26 13:50:52 +03:00
2020-04-16 05:23:21 +03:00
SECTION ( " NaN " )
{
// NaN is stored properly, but serialized to null
json : : number_float_t n ( std : : numeric_limits < json : : number_float_t > : : quiet_NaN ( ) ) ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
// check round trip of NaN
2020-07-16 12:11:35 +03:00
json : : number_float_t d { j } ;
2020-06-03 22:22:07 +03:00
CHECK ( ( std : : isnan ( d ) & & std : : isnan ( n ) ) = = true ) ;
2020-04-16 05:23:21 +03:00
// check that NaN is serialized to null
CHECK ( j . dump ( ) = = " null " ) ;
2020-04-27 15:43:49 +03:00
}
2020-04-16 05:23:21 +03:00
2017-02-26 13:50:52 +03:00
SECTION ( " infinity " )
{
2017-03-12 20:38:05 +03:00
// infinity is stored properly, but serialized to null
2017-02-26 13:50:52 +03:00
json : : number_float_t n ( std : : numeric_limits < json : : number_float_t > : : infinity ( ) ) ;
json j ( n ) ;
2017-03-12 20:38:05 +03:00
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
// check round trip of infinity
2020-07-16 12:11:35 +03:00
json : : number_float_t d { j } ;
2017-03-12 20:38:05 +03:00
CHECK ( d = = n ) ;
// check that inf is serialized to null
CHECK ( j . dump ( ) = = " null " ) ;
2017-02-26 13:50:52 +03:00
}
2016-08-04 22:55:47 +03:00
}
SECTION ( " create a floating-point number (implicit) " )
{
// reference object
json : : number_float_t n_reference = 42.23 ;
json j_reference ( n_reference ) ;
SECTION ( " float " )
{
2016-08-25 01:24:33 +03:00
float n = 42.23f ;
2016-08-04 22:55:47 +03:00
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
SECTION ( " double " )
{
double n = 42.23 ;
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
SECTION ( " long double " )
{
2021-03-24 09:15:18 +03:00
long double n = 42.23 L ;
2016-08-04 22:55:47 +03:00
json j ( n ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
SECTION ( " floating-point literal without suffix " )
{
json j ( 42.23 ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
SECTION ( " integer literal with f suffix " )
{
json j ( 42.23f ) ;
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
SECTION ( " integer literal with l suffix " )
{
2021-03-24 09:15:18 +03:00
json j ( 42.23 L ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : number_float ) ;
CHECK ( j . m_value . number_float = = Approx ( j_reference . m_value . number_float ) ) ;
}
}
SECTION ( " create a container (array or object) from an initializer list " )
{
SECTION ( " empty initializer list " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
SECTION ( " implicit " )
{
json j { } ;
CHECK ( j . type ( ) = = json : : value_t : : null ) ;
}
}
SECTION ( " one element " )
{
SECTION ( " array " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( json : : array_t ( ) ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { json : : array_t ( ) } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " object " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( json : : object_t ( ) ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { json : : object_t ( ) } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " string " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( " Hello world " ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { " Hello world " } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " boolean " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( true ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { true } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " number (integer) " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( 1 ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { 1 } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " number (unsigned) " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( 1u ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { 1u } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " number (floating-point) " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { json ( 42.23 ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { 42.23 } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
}
SECTION ( " more elements " )
{
SECTION ( " explicit " )
{
2017-07-23 23:59:34 +03:00
json j ( json : : initializer_list_t { 1 , 1u , 42.23 , true , nullptr , json : : object_t ( ) , json : : array_t ( ) } ) ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " implicit " )
{
json j { 1 , 1u , 42.23 , true , nullptr , json : : object_t ( ) , json : : array_t ( ) } ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " implicit type deduction " )
{
SECTION ( " object " )
{
json j { { " one " , 1 } , { " two " , 1u } , { " three " , 2.2 } , { " four " , false } } ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
SECTION ( " array " )
{
2017-01-03 23:33:23 +03:00
json j { { " one " , 1 } , { " two " , 1u } , { " three " , 2.2 } , { " four " , false } , 13 } ;
2016-08-04 22:55:47 +03:00
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
SECTION ( " explicit type deduction " )
{
SECTION ( " empty object " )
{
json j = json : : object ( ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
SECTION ( " object " )
{
json j = json : : object ( { { " one " , 1 } , { " two " , 1u } , { " three " , 2.2 } , { " four " , false } } ) ;
CHECK ( j . type ( ) = = json : : value_t : : object ) ;
}
SECTION ( " object with error " )
{
2019-07-02 22:06:42 +03:00
json _ ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( _ = json : : object ( { { " one " , 1 } , { " two " , 1u } , { " three " , 2.2 } , { " four " , false } , 13 } ) , " [json.exception.type_error.301] cannot create object from initializer list " , json : : type_error & ) ;
2016-08-04 22:55:47 +03:00
}
SECTION ( " empty array " )
{
json j = json : : array ( ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
SECTION ( " array " )
{
json j = json : : array ( { { " one " , 1 } , { " two " , 1u } , { " three " , 2.2 } , { " four " , false } } ) ;
CHECK ( j . type ( ) = = json : : value_t : : array ) ;
}
}
2017-07-23 23:47:15 +03:00
SECTION ( " move from initializer_list " )
{
SECTION ( " string " )
{
SECTION ( " constructor with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
// This should break through any short string optimization in std::string
std : : string source ( 1024 , ' ! ' ) ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j = { std : : move ( source ) } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ 0 ] . get_ref < std : : string const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
SECTION ( " constructor with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
// This should break through any short string optimization in std::string
std : : string source ( 1024 , ' ! ' ) ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j = { { " key " , std : : move ( source ) } } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ " key " ] . get_ref < std : : string const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
SECTION ( " constructor with implicit types (object key) " )
{
2021-03-24 09:15:18 +03:00
// This should break through any short string optimization in std::string
std : : string source ( 1024 , ' ! ' ) ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j = { { std : : move ( source ) , 42 } } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j . get_ref < json : : object_t & > ( ) . begin ( ) - > first . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
}
SECTION ( " array " )
{
SECTION ( " constructor with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json : : array_t source = { 1 , 2 , 3 } ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j { std : : move ( source ) } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ 0 ] . get_ref < json : : array_t const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
SECTION ( " constructor with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json : : array_t source = { 1 , 2 , 3 } ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j { { " key " , std : : move ( source ) } } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ " key " ] . get_ref < json : : array_t const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
SECTION ( " assignment with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json : : array_t source = { 1 , 2 , 3 } ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j = { std : : move ( source ) } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ 0 ] . get_ref < json : : array_t const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
SECTION ( " assignment with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json : : array_t source = { 1 , 2 , 3 } ;
const auto * source_addr = source . data ( ) ;
2017-07-23 23:47:15 +03:00
json j = { { " key " , std : : move ( source ) } } ;
2021-03-24 09:15:18 +03:00
const auto * target_addr = j [ " key " ] . get_ref < json : : array_t const & > ( ) . data ( ) ;
const bool success = ( target_addr = = source_addr ) ;
CHECK ( success ) ;
2017-07-23 23:47:15 +03:00
}
}
SECTION ( " object " )
{
SECTION ( " constructor with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json : : object_t source = { { " hello " , " world " } } ;
const json * source_addr = & source . at ( " hello " ) ;
2017-07-23 23:47:15 +03:00
json j { std : : move ( source ) } ;
CHECK ( & ( j [ 0 ] . get_ref < json : : object_t const & > ( ) . at ( " hello " ) ) = = source_addr ) ;
}
SECTION ( " constructor with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json : : object_t source = { { " hello " , " world " } } ;
const json * source_addr = & source . at ( " hello " ) ;
2017-07-23 23:47:15 +03:00
json j { { " key " , std : : move ( source ) } } ;
CHECK ( & ( j [ " key " ] . get_ref < json : : object_t const & > ( ) . at ( " hello " ) ) = = source_addr ) ;
}
SECTION ( " assignment with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json : : object_t source = { { " hello " , " world " } } ;
const json * source_addr = & source . at ( " hello " ) ;
2017-07-23 23:47:15 +03:00
json j = { std : : move ( source ) } ;
CHECK ( & ( j [ 0 ] . get_ref < json : : object_t const & > ( ) . at ( " hello " ) ) = = source_addr ) ;
}
SECTION ( " assignment with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json : : object_t source = { { " hello " , " world " } } ;
const json * source_addr = & source . at ( " hello " ) ;
2017-07-23 23:47:15 +03:00
json j = { { " key " , std : : move ( source ) } } ;
CHECK ( & ( j [ " key " ] . get_ref < json : : object_t const & > ( ) . at ( " hello " ) ) = = source_addr ) ;
}
}
SECTION ( " json " )
{
SECTION ( " constructor with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json source { 1 , 2 , 3 } ;
const json * source_addr = & source [ 0 ] ;
2017-07-24 01:02:03 +03:00
json j { std : : move ( source ) , { } } ;
2017-07-23 23:47:15 +03:00
CHECK ( & j [ 0 ] [ 0 ] = = source_addr ) ;
}
SECTION ( " constructor with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json source { 1 , 2 , 3 } ;
const json * source_addr = & source [ 0 ] ;
2017-07-23 23:47:15 +03:00
json j { { " key " , std : : move ( source ) } } ;
CHECK ( & j [ " key " ] [ 0 ] = = source_addr ) ;
}
SECTION ( " assignment with implicit types (array) " )
{
2021-03-24 09:15:18 +03:00
json source { 1 , 2 , 3 } ;
const json * source_addr = & source [ 0 ] ;
2017-07-24 01:02:03 +03:00
json j = { std : : move ( source ) , { } } ;
2017-07-23 23:47:15 +03:00
CHECK ( & j [ 0 ] [ 0 ] = = source_addr ) ;
}
SECTION ( " assignment with implicit types (object) " )
{
2021-03-24 09:15:18 +03:00
json source { 1 , 2 , 3 } ;
const json * source_addr = & source [ 0 ] ;
2017-07-23 23:47:15 +03:00
json j = { { " key " , std : : move ( source ) } } ;
CHECK ( & j [ " key " ] [ 0 ] = = source_addr ) ;
}
}
}
2016-08-04 22:55:47 +03:00
}
SECTION ( " create an array of n copies of a given value " )
{
2017-08-30 00:46:26 +03:00
SECTION ( " cnt = 0 " )
2016-08-04 22:55:47 +03:00
{
2017-08-30 00:46:26 +03:00
json v = { 1 , " foo " , 34.23 , { 1 , 2 , 3 } , { { " A " , 1 } , { " B " , 2u } } } ;
json arr ( 0 , v ) ;
CHECK ( arr . size ( ) = = 0 ) ;
}
SECTION ( " cnt = 1 " )
{
json v = { 1 , " foo " , 34.23 , { 1 , 2 , 3 } , { { " A " , 1 } , { " B " , 2u } } } ;
json arr ( 1 , v ) ;
CHECK ( arr . size ( ) = = 1 ) ;
for ( auto & x : arr )
{
CHECK ( x = = v ) ;
}
}
SECTION ( " cnt = 3 " )
{
json v = { 1 , " foo " , 34.23 , { 1 , 2 , 3 } , { { " A " , 1 } , { " B " , 2u } } } ;
json arr ( 3 , v ) ;
CHECK ( arr . size ( ) = = 3 ) ;
for ( auto & x : arr )
{
CHECK ( x = = v ) ;
}
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " create a JSON container from an iterator range " )
{
SECTION ( " object " )
{
SECTION ( " json(begin(), end()) " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json j_new ( jobject . begin ( ) , jobject . end ( ) ) ;
CHECK ( j_new = = jobject ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json j_new ( jobject . cbegin ( ) , jobject . cend ( ) ) ;
CHECK ( j_new = = jobject ) ;
}
}
SECTION ( " json(begin(), begin()) " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json j_new ( jobject . begin ( ) , jobject . begin ( ) ) ;
CHECK ( j_new = = json : : object ( ) ) ;
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
json j_new ( jobject . cbegin ( ) , jobject . cbegin ( ) ) ;
CHECK ( j_new = = json : : object ( ) ) ;
}
}
SECTION ( " construct from subrange " )
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json j_new ( jobject . find ( " b " ) , jobject . find ( " e " ) ) ;
CHECK ( j_new = = json ( { { " b " , 1 } , { " c " , 17u } , { " d " , false } } ) ) ;
}
SECTION ( " incompatible iterators " )
{
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json jobject2 = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( jobject . begin ( ) , jobject2 . end ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( jobject2 . begin ( ) , jobject . end ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json jobject = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } , { " d " , false } , { " e " , true } } ;
json jobject2 = { { " a " , " a " } , { " b " , 1 } , { " c " , 17u } } ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( jobject . cbegin ( ) , jobject2 . cend ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( jobject2 . cbegin ( ) , jobject . cend ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
}
SECTION ( " array " )
{
SECTION ( " json(begin(), end()) " )
{
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . begin ( ) , jarray . end ( ) ) ;
CHECK ( j_new = = jarray ) ;
}
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . cbegin ( ) , jarray . cend ( ) ) ;
CHECK ( j_new = = jarray ) ;
}
}
SECTION ( " json(begin(), begin()) " )
{
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . begin ( ) , jarray . begin ( ) ) ;
CHECK ( j_new = = json : : array ( ) ) ;
}
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . cbegin ( ) , jarray . cbegin ( ) ) ;
CHECK ( j_new = = json : : array ( ) ) ;
}
}
SECTION ( " construct from subrange " )
{
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . begin ( ) + 1 , jarray . begin ( ) + 3 ) ;
CHECK ( j_new = = json ( { 2 , 3 } ) ) ;
}
{
json jarray = { 1 , 2 , 3 , 4 , 5 } ;
json j_new ( jarray . cbegin ( ) + 1 , jarray . cbegin ( ) + 3 ) ;
CHECK ( j_new = = json ( { 2 , 3 } ) ) ;
}
}
SECTION ( " incompatible iterators " )
{
{
json jarray = { 1 , 2 , 3 , 4 } ;
json jarray2 = { 2 , 3 , 4 , 5 } ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( jarray . begin ( ) , jarray2 . end ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( jarray2 . begin ( ) , jarray . end ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json jarray = { 1 , 2 , 3 , 4 } ;
json jarray2 = { 2 , 3 , 4 , 5 } ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( jarray . cbegin ( ) , jarray2 . cend ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( jarray2 . cbegin ( ) , jarray . cend ( ) ) , " [json.exception.invalid_iterator.201] iterators are not compatible " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
}
SECTION ( " other values " )
{
SECTION ( " construct with two valid iterators " )
{
SECTION ( " null " )
{
{
json j ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.206] cannot construct with iterators from null " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.206] cannot construct with iterators from null " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " string " )
{
{
json j = " foo " ;
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( j = = j_new ) ;
}
{
json j = " bar " ;
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( j = = j_new ) ;
}
}
SECTION ( " number (boolean) " )
{
{
json j = false ;
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( j = = j_new ) ;
}
{
json j = true ;
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( j = = j_new ) ;
}
}
SECTION ( " number (integer) " )
{
{
json j = 17 ;
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( j = = j_new ) ;
}
{
json j = 17 ;
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( j = = j_new ) ;
}
}
SECTION ( " number (unsigned) " )
{
{
json j = 17u ;
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( j = = j_new ) ;
}
{
json j = 17u ;
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( j = = j_new ) ;
}
}
SECTION ( " number (floating point) " )
{
{
json j = 23.42 ;
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( j = = j_new ) ;
}
{
json j = 23.42 ;
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( j = = j_new ) ;
}
}
2020-05-09 15:16:57 +03:00
SECTION ( " binary " )
{
{
2020-05-19 14:30:22 +03:00
json j = json : : binary ( { 1 , 2 , 3 } ) ;
2020-05-09 15:16:57 +03:00
json j_new ( j . begin ( ) , j . end ( ) ) ;
CHECK ( ( j = = j_new ) ) ;
}
{
2020-05-19 14:30:22 +03:00
json j = json : : binary ( { 1 , 2 , 3 } ) ;
2020-05-09 15:16:57 +03:00
json j_new ( j . cbegin ( ) , j . cend ( ) ) ;
CHECK ( ( j = = j_new ) ) ;
}
}
2016-08-04 22:55:47 +03:00
}
SECTION ( " construct with two invalid iterators " )
{
SECTION ( " string " )
{
{
json j = " foo " ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . end ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . begin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j = " bar " ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cend ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cbegin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " number (boolean) " )
{
{
json j = false ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . end ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . begin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j = true ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cend ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cbegin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " number (integer) " )
{
{
json j = 17 ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . end ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . begin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j = 17 ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cend ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cbegin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " number (integer) " )
{
{
json j = 17u ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . end ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . begin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j = 17u ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cend ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cbegin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
SECTION ( " number (floating point) " )
{
{
json j = 23.42 ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . end ( ) , j . end ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . begin ( ) , j . begin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
{
json j = 23.42 ;
2022-03-24 17:55:35 +03:00
CHECK_THROWS_WITH_AS ( json ( j . cend ( ) , j . cend ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
CHECK_THROWS_WITH_AS ( json ( j . cbegin ( ) , j . cbegin ( ) ) , " [json.exception.invalid_iterator.204] iterators out of range " , json : : invalid_iterator & ) ;
2016-08-04 22:55:47 +03:00
}
}
}
}
}
}