2015-05-03 21:37:12 +08:00
// Tencent is pleased to support the open source community by making RapidJSON available.
//
2020-10-09 10:04:07 +01:00
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
2021-05-20 17:44:34 +01:00
// Portions (C) Copyright IBM Corporation 2021
2015-04-10 14:54:13 +08:00
//
2015-05-03 21:37:12 +08:00
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
2015-04-10 14:54:13 +08:00
//
2015-05-03 21:37:12 +08:00
// http://opensource.org/licenses/MIT
2015-04-10 14:54:13 +08:00
//
2015-05-03 21:37:12 +08:00
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
2015-04-10 14:54:13 +08:00
# include "unittest.h"
# include "rapidjson/pointer.h"
# include "rapidjson/stringbuffer.h"
2018-12-11 00:19:13 +01:00
# include "rapidjson/ostreamwrapper.h"
2015-04-10 14:54:13 +08:00
# include <sstream>
2018-12-12 22:32:56 +01:00
# include <map>
2018-12-17 14:42:09 +01:00
# include <algorithm>
2015-04-10 14:54:13 +08:00
using namespace rapidjson ;
2015-04-10 17:43:11 +08:00
static const char kJson [ ] = " { \n "
2015-04-10 14:54:13 +08:00
" \" foo \" :[ \" bar \" , \" baz \" ], \n "
" \" \" : 0, \n "
" \" a/b \" : 1, \n "
" \" c%d \" : 2, \n "
" \" e^f \" : 3, \n "
" \" g|h \" : 4, \n "
" \" i \\ \\ j \" : 5, \n "
" \" k \\ \" l \" : 6, \n "
" \" \" : 7, \n "
" \" m~n \" : 8 \n "
" } " ;
2015-05-08 18:39:26 +08:00
TEST ( Pointer , DefaultConstructor ) {
Pointer p ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokenCount ( ) ) ;
}
2015-04-10 14:54:13 +08:00
TEST ( Pointer , Parse ) {
{
Pointer p ( " " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , p . GetTokenCount ( ) ) ;
2015-04-10 14:54:13 +08:00
}
2015-05-08 21:26:56 +08:00
{
Pointer p ( " / " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
}
2015-04-10 14:54:13 +08:00
{
Pointer p ( " /foo " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-05-08 21:26:56 +08:00
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
2015-04-10 14:54:13 +08:00
}
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
{
Pointer p ( std : : string ( " /foo " ) ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-05-08 21:26:56 +08:00
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
2015-05-03 18:55:55 +08:00
}
# endif
2015-04-10 14:54:13 +08:00
{
Pointer p ( " /foo/0 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-05-08 21:26:56 +08:00
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " 0 " , p . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 1 ] . index ) ;
2015-04-10 14:54:13 +08:00
}
{
// Unescape ~1
Pointer p ( " /a~1b " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " a/b " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// Unescape ~0
Pointer p ( " /m~0n " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " m~n " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// empty name
Pointer p ( " / " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// empty and non-empty name
Pointer p ( " //a " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " a " , p . GetTokens ( ) [ 1 ] . name ) ;
}
{
// Null characters
Pointer p ( " / \0 \0 " , 3 ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 2u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 14:54:13 +08:00
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 0 ] ) ;
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 1 ] ) ;
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 2 ] ) ;
}
{
// Valid index
Pointer p ( " /123 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " 123 " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:43:46 +08:00
EXPECT_EQ ( 123u , p . GetTokens ( ) [ 0 ] . index ) ;
2015-04-10 14:54:13 +08:00
}
{
// Invalid index (with leading zero)
Pointer p ( " /01 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " 01 " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-04-11 14:48:33 +08:00
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
2015-04-10 14:54:13 +08:00
}
2015-04-10 17:43:11 +08:00
if ( sizeof ( SizeType ) = = 4 ) {
2015-04-10 14:54:13 +08:00
// Invalid index (overflow)
Pointer p ( " /4294967296 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( " 4294967296 " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-04-11 14:48:33 +08:00
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
2015-04-10 14:54:13 +08:00
}
2015-05-02 20:44:30 +08:00
{
// kPointerParseErrorTokenMustBeginWithSolidus
Pointer p ( " " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorTokenMustBeginWithSolidus , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 0u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorInvalidEscape
Pointer p ( " /~ " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidEscape , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorInvalidEscape
Pointer p ( " /~2 " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidEscape , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
}
2015-04-10 14:54:13 +08:00
}
2015-05-03 09:51:15 +08:00
TEST ( Pointer , Parse_URIFragment ) {
{
Pointer p ( " # " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokenCount ( ) ) ;
}
{
Pointer p ( " #/foo " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
Pointer p ( " #/foo/0 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
EXPECT_STREQ ( " 0 " , p . GetTokens ( ) [ 1 ] . name ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 1 ] . index ) ;
}
{
// Unescape ~1
Pointer p ( " #/a~1b " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " a/b " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// Unescape ~0
Pointer p ( " #/m~0n " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " m~n " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// empty name
Pointer p ( " #/ " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// empty and non-empty name
Pointer p ( " #//a " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
EXPECT_STREQ ( " a " , p . GetTokens ( ) [ 1 ] . name ) ;
}
{
// Null characters
Pointer p ( " #/%00%00 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 2u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 0 ] ) ;
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 1 ] ) ;
EXPECT_EQ ( ' \0 ' , p . GetTokens ( ) [ 0 ] . name [ 2 ] ) ;
}
{
// Percentage Escapes
EXPECT_STREQ ( " c%d " , Pointer ( " #/c%25d " ) . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_STREQ ( " e^f " , Pointer ( " #/e%5Ef " ) . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_STREQ ( " g|h " , Pointer ( " #/g%7Ch " ) . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_STREQ ( " i \\ j " , Pointer ( " #/i%5Cj " ) . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_STREQ ( " k \" l " , Pointer ( " #/k%22l " ) . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_STREQ ( " " , Pointer ( " #/%20 " ) . GetTokens ( ) [ 0 ] . name ) ;
}
{
// Valid index
Pointer p ( " #/123 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_STREQ ( " 123 " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 123u , p . GetTokens ( ) [ 0 ] . index ) ;
}
{
// Invalid index (with leading zero)
Pointer p ( " #/01 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_STREQ ( " 01 " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
}
if ( sizeof ( SizeType ) = = 4 ) {
// Invalid index (overflow)
Pointer p ( " #/4294967296 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_STREQ ( " 4294967296 " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( kPointerInvalidIndex , p . GetTokens ( ) [ 0 ] . index ) ;
}
2015-05-03 14:14:05 +08:00
{
// Decode UTF-8 perecent encoding to UTF-8
Pointer p ( " #/%C2%A2 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
EXPECT_STREQ ( " \xC2 \xA2 " , p . GetTokens ( ) [ 0 ] . name ) ;
}
{
// Decode UTF-8 perecent encoding to UTF-16
GenericPointer < GenericValue < UTF16 < > > > p ( L " #/%C2%A2 " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
2015-12-18 18:34:04 +08:00
EXPECT_EQ ( static_cast < UTF16 < > : : Ch > ( 0x00A2 ) , p . GetTokens ( ) [ 0 ] . name [ 0 ] ) ;
2015-05-03 20:11:55 +08:00
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-05-03 14:14:05 +08:00
}
{
// Decode UTF-8 perecent encoding to UTF-16
GenericPointer < GenericValue < UTF16 < > > > p ( L " #/%E2%82%AC " ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 1u , p . GetTokenCount ( ) ) ;
2015-12-18 18:34:04 +08:00
EXPECT_EQ ( static_cast < UTF16 < > : : Ch > ( 0x20AC ) , p . GetTokens ( ) [ 0 ] . name [ 0 ] ) ;
2015-05-03 20:11:55 +08:00
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-05-03 14:14:05 +08:00
}
2015-05-03 09:51:15 +08:00
{
// kPointerParseErrorTokenMustBeginWithSolidus
Pointer p ( " # " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorTokenMustBeginWithSolidus , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 1u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorInvalidEscape
Pointer p ( " #/~ " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidEscape , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 3u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorInvalidEscape
Pointer p ( " #/~2 " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidEscape , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 3u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorInvalidPercentEncoding
Pointer p ( " #/% " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidPercentEncoding , p . GetParseErrorCode ( ) ) ;
2015-05-03 14:14:05 +08:00
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
2015-05-03 09:51:15 +08:00
}
{
2015-05-03 21:58:55 +08:00
// kPointerParseErrorInvalidPercentEncoding (invalid hex)
2015-05-03 09:51:15 +08:00
Pointer p ( " #/%g0 " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidPercentEncoding , p . GetParseErrorCode ( ) ) ;
2015-05-03 14:14:05 +08:00
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
2015-05-03 09:51:15 +08:00
}
{
2015-05-03 21:58:55 +08:00
// kPointerParseErrorInvalidPercentEncoding (invalid hex)
2015-05-03 09:51:15 +08:00
Pointer p ( " #/%0g " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidPercentEncoding , p . GetParseErrorCode ( ) ) ;
2015-05-03 14:14:05 +08:00
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
2015-05-03 09:51:15 +08:00
}
2015-05-03 21:58:55 +08:00
{
// kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
Pointer p ( " #/%C2 " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorInvalidPercentEncoding , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
}
2015-05-03 09:51:15 +08:00
{
// kPointerParseErrorCharacterMustPercentEncode
Pointer p ( " #/ " ) ;
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorCharacterMustPercentEncode , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
}
{
// kPointerParseErrorCharacterMustPercentEncode
2015-05-03 14:14:05 +08:00
Pointer p ( " #/ \n " ) ;
2015-05-03 09:51:15 +08:00
EXPECT_FALSE ( p . IsValid ( ) ) ;
EXPECT_EQ ( kPointerParseErrorCharacterMustPercentEncode , p . GetParseErrorCode ( ) ) ;
EXPECT_EQ ( 2u , p . GetParseErrorOffset ( ) ) ;
}
}
2015-04-10 14:54:13 +08:00
TEST ( Pointer , Stringify ) {
// Test by roundtrip
const char * sources [ ] = {
" " ,
" /foo " ,
" /foo/0 " ,
" / " ,
" /a~1b " ,
" /c%d " ,
" /e^f " ,
" /g|h " ,
" /i \\ j " ,
" /k \" l " ,
" / " ,
2015-05-03 14:14:05 +08:00
" /m~0n " ,
" / \xC2 \xA2 " ,
" / \xE2 \x82 \xAC " ,
" / \xF0 \x9D \x84 \x9E "
2015-04-10 14:54:13 +08:00
} ;
for ( size_t i = 0 ; i < sizeof ( sources ) / sizeof ( sources [ 0 ] ) ; i + + ) {
Pointer p ( sources [ i ] ) ;
StringBuffer s ;
2015-05-03 21:58:55 +08:00
EXPECT_TRUE ( p . Stringify ( s ) ) ;
2015-04-10 14:54:13 +08:00
EXPECT_STREQ ( sources [ i ] , s . GetString ( ) ) ;
2015-05-03 14:14:05 +08:00
// Stringify to URI fragment
StringBuffer s2 ;
2015-05-03 21:58:55 +08:00
EXPECT_TRUE ( p . StringifyUriFragment ( s2 ) ) ;
2015-05-03 14:14:05 +08:00
Pointer p2 ( s2 . GetString ( ) , s2 . GetSize ( ) ) ;
EXPECT_TRUE ( p2 . IsValid ( ) ) ;
EXPECT_TRUE ( p = = p2 ) ;
2015-04-10 14:54:13 +08:00
}
2015-05-03 21:58:55 +08:00
{
// Strigify to URI fragment with an invalid UTF-8 sequence
Pointer p ( " / \xC2 " ) ;
StringBuffer s ;
EXPECT_FALSE ( p . StringifyUriFragment ( s ) ) ;
}
2015-04-10 14:54:13 +08:00
}
2015-04-10 17:43:11 +08:00
2015-04-10 18:25:02 +08:00
// Construct a Pointer with static tokens, no dynamic allocation involved.
2017-05-12 10:32:41 +08:00
# define NAME(s) { s, static_cast<SizeType>(sizeof(s) / sizeof(s[0]) - 1), kPointerInvalidIndex }
# define INDEX(i) { #i, static_cast<SizeType>(sizeof(#i) - 1), i }
2015-04-10 18:25:02 +08:00
static const Pointer : : Token kTokens [ ] = { NAME ( " foo " ) , INDEX ( 0 ) } ; // equivalent to "/foo/0"
# undef NAME
# undef INDEX
TEST ( Pointer , ConstructorWithToken ) {
Pointer p ( kTokens , sizeof ( kTokens ) / sizeof ( kTokens [ 0 ] ) ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " 0 " , p . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 1 ] . index ) ;
2015-04-10 18:25:02 +08:00
}
TEST ( Pointer , CopyConstructor ) {
{
2017-11-27 10:38:01 +01:00
CrtAllocator allocator ;
Pointer p ( " /foo/0 " , & allocator ) ;
2015-04-10 18:25:02 +08:00
Pointer q ( p ) ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2017-11-27 10:38:01 +01:00
EXPECT_EQ ( & p . GetAllocator ( ) , & q . GetAllocator ( ) ) ;
2015-04-10 18:25:02 +08:00
}
// Static tokens
{
Pointer p ( kTokens , sizeof ( kTokens ) / sizeof ( kTokens [ 0 ] ) ) ;
Pointer q ( p ) ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2015-04-10 18:25:02 +08:00
}
}
TEST ( Pointer , Assignment ) {
{
2017-11-27 10:38:01 +01:00
CrtAllocator allocator ;
Pointer p ( " /foo/0 " , & allocator ) ;
2015-04-10 18:25:02 +08:00
Pointer q ;
q = p ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2017-11-27 10:38:01 +01:00
EXPECT_NE ( & p . GetAllocator ( ) , & q . GetAllocator ( ) ) ;
2018-10-31 20:31:04 -07:00
q = static_cast < const Pointer & > ( q ) ;
2015-05-08 21:26:56 +08:00
EXPECT_TRUE ( q . IsValid ( ) ) ;
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2017-11-27 10:38:01 +01:00
EXPECT_NE ( & p . GetAllocator ( ) , & q . GetAllocator ( ) ) ;
2015-04-10 18:25:02 +08:00
}
// Static tokens
{
Pointer p ( kTokens , sizeof ( kTokens ) / sizeof ( kTokens [ 0 ] ) ) ;
Pointer q ;
q = p ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
2015-04-10 18:25:02 +08:00
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
2015-04-10 22:12:59 +08:00
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2015-04-10 18:25:02 +08:00
}
}
2018-12-17 14:33:32 +01:00
TEST ( Pointer , Swap ) {
2018-12-17 14:42:09 +01:00
Pointer p ( " /foo/0 " ) ;
Pointer q ( & p . GetAllocator ( ) ) ;
q . Swap ( p ) ;
EXPECT_EQ ( & q . GetAllocator ( ) , & p . GetAllocator ( ) ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
EXPECT_EQ ( 0u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 2u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , q . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , q . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 1u , q . GetTokens ( ) [ 1 ] . length ) ;
EXPECT_STREQ ( " 0 " , q . GetTokens ( ) [ 1 ] . name ) ;
EXPECT_EQ ( 0u , q . GetTokens ( ) [ 1 ] . index ) ;
2018-12-17 14:33:32 +01:00
// std::swap compatibility
2018-12-17 14:42:09 +01:00
std : : swap ( p , q ) ;
EXPECT_EQ ( & p . GetAllocator ( ) , & q . GetAllocator ( ) ) ;
EXPECT_TRUE ( q . IsValid ( ) ) ;
EXPECT_TRUE ( p . IsValid ( ) ) ;
EXPECT_EQ ( 0u , q . GetTokenCount ( ) ) ;
EXPECT_EQ ( 2u , p . GetTokenCount ( ) ) ;
EXPECT_EQ ( 3u , p . GetTokens ( ) [ 0 ] . length ) ;
EXPECT_STREQ ( " foo " , p . GetTokens ( ) [ 0 ] . name ) ;
EXPECT_EQ ( 1u , p . GetTokens ( ) [ 1 ] . length ) ;
EXPECT_STREQ ( " 0 " , p . GetTokens ( ) [ 1 ] . name ) ;
EXPECT_EQ ( 0u , p . GetTokens ( ) [ 1 ] . index ) ;
2018-12-17 14:33:32 +01:00
}
2015-05-08 21:26:56 +08:00
TEST ( Pointer , Append ) {
{
Pointer p ;
Pointer q = p . Append ( " foo " ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) = = q ) ;
2015-05-08 22:18:46 +08:00
q = q . Append ( 1234 ) ;
EXPECT_TRUE ( Pointer ( " /foo/1234 " ) = = q ) ;
2015-05-08 21:26:56 +08:00
q = q . Append ( " " ) ;
2015-05-08 22:18:46 +08:00
EXPECT_TRUE ( Pointer ( " /foo/1234/ " ) = = q ) ;
}
{
Pointer p ;
Pointer q = p . Append ( Value ( " foo " ) . Move ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) = = q ) ;
q = q . Append ( Value ( 1234 ) . Move ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/1234 " ) = = q ) ;
q = q . Append ( Value ( kStringType ) . Move ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/1234/ " ) = = q ) ;
2015-05-08 21:26:56 +08:00
}
# if RAPIDJSON_HAS_STDSTRING
{
Pointer p ;
Pointer q = p . Append ( std : : string ( " foo " ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) = = q ) ;
}
# endif
}
2015-05-03 14:14:05 +08:00
TEST ( Pointer , Equality ) {
EXPECT_TRUE ( Pointer ( " /foo/0 " ) = = Pointer ( " /foo/0 " ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/0 " ) = = Pointer ( " /foo/1 " ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/0 " ) = = Pointer ( " /foo/0/1 " ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/0 " ) = = Pointer ( " a " ) ) ;
EXPECT_FALSE ( Pointer ( " a " ) = = Pointer ( " a " ) ) ; // Invalid always not equal
}
TEST ( Pointer , Inequality ) {
EXPECT_FALSE ( Pointer ( " /foo/0 " ) ! = Pointer ( " /foo/0 " ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/0 " ) ! = Pointer ( " /foo/1 " ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/0 " ) ! = Pointer ( " /foo/0/1 " ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/0 " ) ! = Pointer ( " a " ) ) ;
EXPECT_TRUE ( Pointer ( " a " ) ! = Pointer ( " a " ) ) ; // Invalid always not equal
}
2015-04-10 17:43:11 +08:00
TEST ( Pointer , Create ) {
Document d ;
2015-04-10 19:28:12 +08:00
{
Value * v = & Pointer ( " " ) . Create ( d , d . GetAllocator ( ) ) ;
EXPECT_EQ ( & d , v ) ;
}
{
Value * v = & Pointer ( " /foo " ) . Create ( d , d . GetAllocator ( ) ) ;
EXPECT_EQ ( & d [ " foo " ] , v ) ;
}
{
Value * v = & Pointer ( " /foo/0 " ) . Create ( d , d . GetAllocator ( ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , v ) ;
}
2015-05-02 21:30:40 +08:00
{
Value * v = & Pointer ( " /foo/- " ) . Create ( d , d . GetAllocator ( ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 1 ] , v ) ;
}
2015-05-04 15:02:43 +08:00
2015-05-02 21:30:40 +08:00
{
Value * v = & Pointer ( " /foo/-/- " ) . Create ( d , d . GetAllocator ( ) ) ;
2015-05-04 15:02:43 +08:00
// "foo/-" is a newly created null value x.
// "foo/-/-" finds that x is not an array, it converts x to empty object
// and treats - as "-" member name
EXPECT_EQ ( & d [ " foo " ] [ 2 ] [ " - " ] , v ) ;
2015-05-02 21:30:40 +08:00
}
2015-05-02 22:46:30 +08:00
{
// Document with no allocator
Value * v = & Pointer ( " /foo/- " ) . Create ( d ) ;
EXPECT_EQ ( & d [ " foo " ] [ 3 ] , v ) ;
}
{
// Value (not document) must give allocator
Value * v = & Pointer ( " /- " ) . Create ( d [ " foo " ] , d . GetAllocator ( ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 4 ] , v ) ;
}
2015-04-10 17:43:11 +08:00
}
2021-03-11 14:49:28 +00:00
static const char kJsonIds [ ] = " { \n "
" \" id \" : \" /root/ \" , "
" \" foo \" :[ \" bar \" , \" baz \" , { \" id \" : \" inarray \" , \" child \" : 1}], \n "
" \" int \" : 2, \n "
" \" str \" : \" val \" , \n "
" \" obj \" : { \" id \" : \" inobj \" , \" child \" : 3}, \n "
" \" jbo \" : { \" id \" : true, \" child \" : 4} \n "
" } " ;
TEST ( Pointer , GetUri ) {
typedef std : : basic_string < Value : : Ch > String ;
Document d ;
d . Parse ( kJsonIds ) ;
String doc = String ( " http://doc " ) ;
EXPECT_TRUE ( ( Pointer ( " " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = doc ) ;
EXPECT_TRUE ( ( Pointer ( " /foo " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /foo/0 " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /foo/2 " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /foo/2/child " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/inarray " ) ;
EXPECT_TRUE ( ( Pointer ( " /int " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /str " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /obj " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /obj/child " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/inobj " ) ;
EXPECT_TRUE ( ( Pointer ( " /jbo " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
EXPECT_TRUE ( ( Pointer ( " /jbo/child " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ; // id not string
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( ( Pointer ( " /abc " ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = Pointer : : UriType ( ) . Get ( ) ) ; // Out of boundary
2021-03-11 14:49:28 +00:00
size_t unresolvedTokenIndex ;
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( ( Pointer ( " /foo/3 " ) . GetUri ( d , Pointer : : UriType ( doc ) , & unresolvedTokenIndex ) . Get ( ) ) = = Pointer : : UriType ( ) . Get ( ) ) ; // Out of boundary
2021-03-11 14:49:28 +00:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( ( Pointer ( " /foo/a " ) . GetUri ( d , Pointer : : UriType ( doc ) , & unresolvedTokenIndex ) . Get ( ) ) = = Pointer : : UriType ( ) . Get ( ) ) ; // "/foo" is an array, cannot query by "a"
2021-03-11 14:49:28 +00:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( ( Pointer ( " /foo/0/0 " ) . GetUri ( d , Pointer : : UriType ( doc ) , & unresolvedTokenIndex ) . Get ( ) ) = = Pointer : : UriType ( ) . Get ( ) ) ; // "/foo/0" is an string, cannot further query
2021-03-11 14:49:28 +00:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( ( Pointer ( " /foo/0/a " ) . GetUri ( d , Pointer : : UriType ( doc ) , & unresolvedTokenIndex ) . Get ( ) ) = = Pointer : : UriType ( ) . Get ( ) ) ; // "/foo/0" is an string, cannot further query
2021-03-11 14:49:28 +00:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
Pointer : : Token tokens [ ] = { { " foo ... " , 3 , kPointerInvalidIndex } } ;
EXPECT_TRUE ( ( Pointer ( tokens , 1 ) . GetUri ( d , Pointer : : UriType ( doc ) ) . Get ( ) ) = = " http://doc/root/ " ) ;
}
2015-04-10 17:43:11 +08:00
TEST ( Pointer , Get ) {
Document d ;
d . Parse ( kJson ) ;
EXPECT_EQ ( & d , Pointer ( " " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " foo " ] , Pointer ( " /foo " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , Pointer ( " /foo/0 " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " " ] , Pointer ( " / " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " a/b " ] , Pointer ( " /a~1b " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " c%d " ] , Pointer ( " /c%d " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " e^f " ] , Pointer ( " /e^f " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " g|h " ] , Pointer ( " /g|h " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " i \\ j " ] , Pointer ( " /i \\ j " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " k \" l " ] , Pointer ( " /k \" l " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " " ] , Pointer ( " / " ) . Get ( d ) ) ;
EXPECT_EQ ( & d [ " m~n " ] , Pointer ( " /m~0n " ) . Get ( d ) ) ;
2021-05-20 17:44:34 +01:00
EXPECT_TRUE ( Pointer ( " /abc " ) . Get ( d ) = = 0 ) ; // Out of boundary
2016-02-09 12:09:47 +08:00
size_t unresolvedTokenIndex ;
EXPECT_TRUE ( Pointer ( " /foo/2 " ) . Get ( d , & unresolvedTokenIndex ) = = 0 ) ; // Out of boundary
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( Pointer ( " /foo/a " ) . Get ( d , & unresolvedTokenIndex ) = = 0 ) ; // "/foo" is an array, cannot query by "a"
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( Pointer ( " /foo/0/0 " ) . Get ( d , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( Pointer ( " /foo/0/a " ) . Get ( d , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2019-09-12 08:12:06 +01:00
Pointer : : Token tokens [ ] = { { " foo ... " , 3 , kPointerInvalidIndex } } ;
EXPECT_EQ ( & d [ " foo " ] , Pointer ( tokens , 1 ) . Get ( d ) ) ;
2015-04-10 17:43:11 +08:00
}
TEST ( Pointer , GetWithDefault ) {
Document d ;
d . Parse ( kJson ) ;
2015-05-02 21:52:49 +08:00
// Value version
2015-04-10 17:43:11 +08:00
Document : : AllocatorType & a = d . GetAllocator ( ) ;
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = Pointer ( " /foo/0 " ) . GetWithDefault ( d , v , a ) ) ;
EXPECT_TRUE ( Value ( " baz " ) = = Pointer ( " /foo/1 " ) . GetWithDefault ( d , v , a ) ) ;
EXPECT_TRUE ( Value ( " qux " ) = = Pointer ( " /foo/2 " ) . GetWithDefault ( d , v , a ) ) ;
2015-05-02 21:30:40 +08:00
EXPECT_TRUE ( Value ( " last " ) = = Pointer ( " /foo/- " ) . GetWithDefault ( d , Value ( " last " ) . Move ( ) , a ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
2015-05-02 21:52:49 +08:00
EXPECT_TRUE ( Pointer ( " /foo/null " ) . GetWithDefault ( d , Value ( ) . Move ( ) , a ) . IsNull ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/null " ) . GetWithDefault ( d , " x " , a ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , Pointer ( " /foo/int " ) . GetWithDefault ( d , - 1 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , Pointer ( " /foo/int " ) . GetWithDefault ( d , - 2 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , Pointer ( " /foo/uint " ) . GetWithDefault ( d , 0x87654321 , a ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , Pointer ( " /foo/uint " ) . GetWithDefault ( d , 0x12345678 , a ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , Pointer ( " /foo/int64 " ) . GetWithDefault ( d , i64 , a ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , Pointer ( " /foo/int64 " ) . GetWithDefault ( d , i64 + 1 , a ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , Pointer ( " /foo/uint64 " ) . GetWithDefault ( d , u64 , a ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , Pointer ( " /foo/uint64 " ) . GetWithDefault ( d , u64 - 1 , a ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/true " ) . GetWithDefault ( d , true , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/true " ) . GetWithDefault ( d , false , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/false " ) . GetWithDefault ( d , false , a ) . IsFalse ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/false " ) . GetWithDefault ( d , true , a ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , Pointer ( " /foo/hello " ) . GetWithDefault ( d , " Hello " , a ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , Pointer ( " /foo/world " ) . GetWithDefault ( d , buffer , a ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , Pointer ( " /foo/C++ " ) . GetWithDefault ( d , std : : string ( " C++ " ) , a ) . GetString ( ) ) ;
# endif
2015-04-10 17:43:11 +08:00
}
2015-05-02 22:46:30 +08:00
TEST ( Pointer , GetWithDefault_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
// Value version
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = Pointer ( " /foo/0 " ) . GetWithDefault ( d , v ) ) ;
EXPECT_TRUE ( Value ( " baz " ) = = Pointer ( " /foo/1 " ) . GetWithDefault ( d , v ) ) ;
EXPECT_TRUE ( Value ( " qux " ) = = Pointer ( " /foo/2 " ) . GetWithDefault ( d , v ) ) ;
EXPECT_TRUE ( Value ( " last " ) = = Pointer ( " /foo/- " ) . GetWithDefault ( d , Value ( " last " ) . Move ( ) ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/null " ) . GetWithDefault ( d , Value ( ) . Move ( ) ) . IsNull ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/null " ) . GetWithDefault ( d , " x " ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , Pointer ( " /foo/int " ) . GetWithDefault ( d , - 1 ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , Pointer ( " /foo/int " ) . GetWithDefault ( d , - 2 ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , Pointer ( " /foo/uint " ) . GetWithDefault ( d , 0x87654321 ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , Pointer ( " /foo/uint " ) . GetWithDefault ( d , 0x12345678 ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , Pointer ( " /foo/int64 " ) . GetWithDefault ( d , i64 ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , Pointer ( " /foo/int64 " ) . GetWithDefault ( d , i64 + 1 ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , Pointer ( " /foo/uint64 " ) . GetWithDefault ( d , u64 ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , Pointer ( " /foo/uint64 " ) . GetWithDefault ( d , u64 - 1 ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/true " ) . GetWithDefault ( d , true ) . IsTrue ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/true " ) . GetWithDefault ( d , false ) . IsTrue ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/false " ) . GetWithDefault ( d , false ) . IsFalse ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/false " ) . GetWithDefault ( d , true ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , Pointer ( " /foo/hello " ) . GetWithDefault ( d , " Hello " ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , Pointer ( " /foo/world " ) . GetWithDefault ( d , buffer ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , Pointer ( " /foo/C++ " ) . GetWithDefault ( d , std : : string ( " C++ " ) ) . GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
2015-04-10 17:43:11 +08:00
TEST ( Pointer , Set ) {
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
2015-05-02 20:07:50 +08:00
// Value version
2015-04-10 17:43:11 +08:00
Pointer ( " /foo/0 " ) . Set ( d , Value ( 123 ) . Move ( ) , a ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
2015-05-02 21:30:40 +08:00
Pointer ( " /foo/- " ) . Set ( d , Value ( 456 ) . Move ( ) , a ) ;
EXPECT_EQ ( 456 , d [ " foo " ] [ 2 ] . GetInt ( ) ) ;
2015-05-02 20:07:50 +08:00
Pointer ( " /foo/null " ) . Set ( d , Value ( ) . Move ( ) , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , a ) ;
Pointer ( " /clone " ) . Set ( d , foo , a ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 20:07:50 +08:00
// Generic version
Pointer ( " /foo/int " ) . Set ( d , - 1 , a ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
Pointer ( " /foo/uint " ) . Set ( d , 0x87654321 , a ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
Pointer ( " /foo/int64 " ) . Set ( d , i64 , a ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
Pointer ( " /foo/uint64 " ) . Set ( d , u64 , a ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
Pointer ( " /foo/true " ) . Set ( d , true , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
Pointer ( " /foo/false " ) . Set ( d , false , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
Pointer ( " /foo/hello " ) . Set ( d , " Hello " , a ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
Pointer ( " /foo/world " ) . Set ( d , buffer , a ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
Pointer ( " /foo/c++ " ) . Set ( d , std : : string ( " C++ " ) , a ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-04-10 17:43:11 +08:00
}
2015-05-02 22:46:30 +08:00
TEST ( Pointer , Set_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
// Value version
Pointer ( " /foo/0 " ) . Set ( d , Value ( 123 ) . Move ( ) ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
Pointer ( " /foo/- " ) . Set ( d , Value ( 456 ) . Move ( ) ) ;
EXPECT_EQ ( 456 , d [ " foo " ] [ 2 ] . GetInt ( ) ) ;
Pointer ( " /foo/null " ) . Set ( d , Value ( ) . Move ( ) ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , d . GetAllocator ( ) ) ;
Pointer ( " /clone " ) . Set ( d , foo ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 22:46:30 +08:00
// Generic version
Pointer ( " /foo/int " ) . Set ( d , - 1 ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
Pointer ( " /foo/uint " ) . Set ( d , 0x87654321 ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
Pointer ( " /foo/int64 " ) . Set ( d , i64 ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
Pointer ( " /foo/uint64 " ) . Set ( d , u64 ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
Pointer ( " /foo/true " ) . Set ( d , true ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
Pointer ( " /foo/false " ) . Set ( d , false ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
Pointer ( " /foo/hello " ) . Set ( d , " Hello " ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
Pointer ( " /foo/world " ) . Set ( d , buffer ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
Pointer ( " /foo/c++ " ) . Set ( d , std : : string ( " C++ " ) ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
2018-12-17 14:33:32 +01:00
TEST ( Pointer , Swap_Value ) {
2015-04-10 17:43:11 +08:00
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
Pointer ( " /foo/0 " ) . Swap ( d , * Pointer ( " /foo/1 " ) . Get ( d ) , a ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
}
2015-04-10 19:28:12 +08:00
2018-12-17 14:33:32 +01:00
TEST ( Pointer , Swap_Value_NoAllocator ) {
2015-05-02 22:58:41 +08:00
Document d ;
d . Parse ( kJson ) ;
Pointer ( " /foo/0 " ) . Swap ( d , * Pointer ( " /foo/1 " ) . Get ( d ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
}
2015-05-04 21:50:26 +08:00
TEST ( Pointer , Erase ) {
Document d ;
d . Parse ( kJson ) ;
EXPECT_FALSE ( Pointer ( " " ) . Erase ( d ) ) ;
2015-05-21 13:25:37 +08:00
EXPECT_FALSE ( Pointer ( " /nonexist " ) . Erase ( d ) ) ;
2015-05-21 17:02:27 +08:00
EXPECT_FALSE ( Pointer ( " /nonexist/nonexist " ) . Erase ( d ) ) ;
2015-05-04 21:50:26 +08:00
EXPECT_FALSE ( Pointer ( " /foo/nonexist " ) . Erase ( d ) ) ;
2015-05-21 16:45:39 +08:00
EXPECT_FALSE ( Pointer ( " /foo/nonexist/nonexist " ) . Erase ( d ) ) ;
2015-05-21 13:25:37 +08:00
EXPECT_FALSE ( Pointer ( " /foo/0/nonexist " ) . Erase ( d ) ) ;
2015-05-21 16:45:39 +08:00
EXPECT_FALSE ( Pointer ( " /foo/0/nonexist/nonexist " ) . Erase ( d ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/2/nonexist " ) . Erase ( d ) ) ;
2015-05-04 21:50:26 +08:00
EXPECT_TRUE ( Pointer ( " /foo/0 " ) . Erase ( d ) ) ;
EXPECT_EQ ( 1u , d [ " foo " ] . Size ( ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo/0 " ) . Erase ( d ) ) ;
EXPECT_TRUE ( d [ " foo " ] . Empty ( ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) . Erase ( d ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) . Get ( d ) = = 0 ) ;
2015-05-21 13:25:37 +08:00
Pointer ( " /a/0/b/0 " ) . Create ( d ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b/0 " ) . Get ( d ) ! = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b/0 " ) . Erase ( d ) ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b/0 " ) . Get ( d ) = = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b " ) . Get ( d ) ! = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b " ) . Erase ( d ) ) ;
EXPECT_TRUE ( Pointer ( " /a/0/b " ) . Get ( d ) = = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a/0 " ) . Get ( d ) ! = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a/0 " ) . Erase ( d ) ) ;
EXPECT_TRUE ( Pointer ( " /a/0 " ) . Get ( d ) = = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a " ) . Get ( d ) ! = 0 ) ;
EXPECT_TRUE ( Pointer ( " /a " ) . Erase ( d ) ) ;
EXPECT_TRUE ( Pointer ( " /a " ) . Get ( d ) = = 0 ) ;
2015-05-04 21:50:26 +08:00
}
2015-04-10 19:28:12 +08:00
TEST ( Pointer , CreateValueByPointer ) {
Document d ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
{
Value & v = CreateValueByPointer ( d , Pointer ( " /foo/0 " ) , a ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , & v ) ;
}
{
Value & v = CreateValueByPointer ( d , " /foo/1 " , a ) ;
EXPECT_EQ ( & d [ " foo " ] [ 1 ] , & v ) ;
}
}
2015-05-02 22:46:30 +08:00
TEST ( Pointer , CreateValueByPointer_NoAllocator ) {
Document d ;
{
Value & v = CreateValueByPointer ( d , Pointer ( " /foo/0 " ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , & v ) ;
}
{
Value & v = CreateValueByPointer ( d , " /foo/1 " ) ;
EXPECT_EQ ( & d [ " foo " ] [ 1 ] , & v ) ;
}
}
2015-04-10 19:28:12 +08:00
TEST ( Pointer , GetValueByPointer ) {
Document d ;
d . Parse ( kJson ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , GetValueByPointer ( d , Pointer ( " /foo/0 " ) ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , GetValueByPointer ( d , " /foo/0 " ) ) ;
2016-02-09 12:09:47 +08:00
size_t unresolvedTokenIndex ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/2 " , & unresolvedTokenIndex ) = = 0 ) ; // Out of boundary
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/a " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo" is an array, cannot query by "a"
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/0/0 " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/0/a " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
2015-04-10 19:28:12 +08:00
// const version
const Value & v = d ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , GetValueByPointer ( v , Pointer ( " /foo/0 " ) ) ) ;
EXPECT_EQ ( & d [ " foo " ] [ 0 ] , GetValueByPointer ( v , " /foo/0 " ) ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( v , " /foo/2 " , & unresolvedTokenIndex ) = = 0 ) ; // Out of boundary
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( v , " /foo/a " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo" is an array, cannot query by "a"
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 1u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( v , " /foo/0/0 " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
EXPECT_TRUE ( GetValueByPointer ( v , " /foo/0/a " , & unresolvedTokenIndex ) = = 0 ) ; // "/foo/0" is an string, cannot further query
2018-07-16 16:03:02 -07:00
EXPECT_EQ ( 2u , unresolvedTokenIndex ) ;
2016-02-09 12:09:47 +08:00
2015-04-10 19:28:12 +08:00
}
2015-05-02 22:08:03 +08:00
TEST ( Pointer , GetValueByPointerWithDefault_Pointer ) {
2015-04-10 19:28:12 +08:00
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/0 " ) , v , a ) ) ;
2015-05-02 22:08:03 +08:00
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/0 " ) , v , a ) ) ;
EXPECT_TRUE ( Value ( " baz " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/1 " ) , v , a ) ) ;
EXPECT_TRUE ( Value ( " qux " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/2 " ) , v , a ) ) ;
EXPECT_TRUE ( Value ( " last " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/- " ) , Value ( " last " ) . Move ( ) , a ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/null " ) , Value ( ) . Move ( ) , a ) . IsNull ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/null " ) , " x " , a ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int " ) , - 1 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int " ) , - 2 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint " ) , 0x87654321 , a ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint " ) , 0x12345678 , a ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int64 " ) , i64 , a ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int64 " ) , i64 + 1 , a ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint64 " ) , u64 , a ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint64 " ) , u64 - 1 , a ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/true " ) , true , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/true " ) , false , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/false " ) , false , a ) . IsFalse ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/false " ) , true , a ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/hello " ) , " Hello " , a ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/world " ) , buffer , a ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , Pointer ( " /foo/world " ) ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/C++ " ) , std : : string ( " C++ " ) , a ) . GetString ( ) ) ;
# endif
2015-05-02 22:08:03 +08:00
}
TEST ( Pointer , GetValueByPointerWithDefault_String ) {
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , " /foo/0 " , v , a ) ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , " /foo/0 " , v , a ) ) ;
2015-04-10 19:28:12 +08:00
EXPECT_TRUE ( Value ( " baz " ) = = GetValueByPointerWithDefault ( d , " /foo/1 " , v , a ) ) ;
2015-05-02 22:08:03 +08:00
EXPECT_TRUE ( Value ( " qux " ) = = GetValueByPointerWithDefault ( d , " /foo/2 " , v , a ) ) ;
EXPECT_TRUE ( Value ( " last " ) = = GetValueByPointerWithDefault ( d , " /foo/- " , Value ( " last " ) . Move ( ) , a ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/null " , Value ( ) . Move ( ) , a ) . IsNull ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/null " , " x " , a ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , " /foo/int " , - 1 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , " /foo/int " , - 2 , a ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , " /foo/uint " , 0x87654321 , a ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , " /foo/uint " , 0x12345678 , a ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , " /foo/int64 " , i64 , a ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , " /foo/int64 " , i64 + 1 , a ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , " /foo/uint64 " , u64 , a ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , " /foo/uint64 " , u64 - 1 , a ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/true " , true , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/true " , false , a ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/false " , false , a ) . IsFalse ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/false " , true , a ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , GetValueByPointerWithDefault ( d , " /foo/hello " , " Hello " , a ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , GetValueByPointerWithDefault ( d , " /foo/world " , buffer , a ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , GetValueByPointerWithDefault ( d , " /foo/C++ " , std : : string ( " C++ " ) , a ) . GetString ( ) ) ;
# endif
2015-04-10 19:28:12 +08:00
}
2015-05-02 22:46:30 +08:00
TEST ( Pointer , GetValueByPointerWithDefault_Pointer_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/0 " ) , v ) ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/0 " ) , v ) ) ;
EXPECT_TRUE ( Value ( " baz " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/1 " ) , v ) ) ;
EXPECT_TRUE ( Value ( " qux " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/2 " ) , v ) ) ;
EXPECT_TRUE ( Value ( " last " ) = = GetValueByPointerWithDefault ( d , Pointer ( " /foo/- " ) , Value ( " last " ) . Move ( ) ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/null " ) , Value ( ) . Move ( ) ) . IsNull ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/null " ) , " x " ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int " ) , - 1 ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int " ) , - 2 ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint " ) , 0x87654321 ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint " ) , 0x12345678 ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int64 " ) , i64 ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/int64 " ) , i64 + 1 ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint64 " ) , u64 ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , Pointer ( " /foo/uint64 " ) , u64 - 1 ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/true " ) , true ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/true " ) , false ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/false " ) , false ) . IsFalse ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , Pointer ( " /foo/false " ) , true ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/hello " ) , " Hello " ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/world " ) , buffer ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , Pointer ( " /foo/world " ) ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/C++ " ) , std : : string ( " C++ " ) ) . GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
TEST ( Pointer , GetValueByPointerWithDefault_String_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
const Value v ( " qux " ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , " /foo/0 " , v ) ) ;
EXPECT_TRUE ( Value ( " bar " ) = = GetValueByPointerWithDefault ( d , " /foo/0 " , v ) ) ;
EXPECT_TRUE ( Value ( " baz " ) = = GetValueByPointerWithDefault ( d , " /foo/1 " , v ) ) ;
EXPECT_TRUE ( Value ( " qux " ) = = GetValueByPointerWithDefault ( d , " /foo/2 " , v ) ) ;
EXPECT_TRUE ( Value ( " last " ) = = GetValueByPointerWithDefault ( d , " /foo/- " , Value ( " last " ) . Move ( ) ) ) ;
EXPECT_STREQ ( " last " , d [ " foo " ] [ 3 ] . GetString ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/null " , Value ( ) . Move ( ) ) . IsNull ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/null " , " x " ) . IsNull ( ) ) ;
// Generic version
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , " /foo/int " , - 1 ) . GetInt ( ) ) ;
EXPECT_EQ ( - 1 , GetValueByPointerWithDefault ( d , " /foo/int " , - 2 ) . GetInt ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , " /foo/uint " , 0x87654321 ) . GetUint ( ) ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointerWithDefault ( d , " /foo/uint " , 0x12345678 ) . GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , " /foo/int64 " , i64 ) . GetInt64 ( ) ) ;
EXPECT_EQ ( i64 , GetValueByPointerWithDefault ( d , " /foo/int64 " , i64 + 1 ) . GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , " /foo/uint64 " , u64 ) . GetUint64 ( ) ) ;
EXPECT_EQ ( u64 , GetValueByPointerWithDefault ( d , " /foo/uint64 " , u64 - 1 ) . GetUint64 ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/true " , true ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/true " , false ) . IsTrue ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/false " , false ) . IsFalse ( ) ) ;
EXPECT_TRUE ( GetValueByPointerWithDefault ( d , " /foo/false " , true ) . IsFalse ( ) ) ;
// StringRef version
EXPECT_STREQ ( " Hello " , GetValueByPointerWithDefault ( d , " /foo/hello " , " Hello " ) . GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
EXPECT_STREQ ( " World " , GetValueByPointerWithDefault ( d , " /foo/world " , buffer ) . GetString ( ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ ( " C++ " , GetValueByPointerWithDefault ( d , Pointer ( " /foo/C++ " ) , std : : string ( " C++ " ) ) . GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
2015-05-02 20:07:50 +08:00
TEST ( Pointer , SetValueByPointer_Pointer ) {
2015-04-10 19:28:12 +08:00
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
2015-05-02 20:07:50 +08:00
// Value version
2015-04-10 19:28:12 +08:00
SetValueByPointer ( d , Pointer ( " /foo/0 " ) , Value ( 123 ) . Move ( ) , a ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
2015-05-02 20:07:50 +08:00
SetValueByPointer ( d , Pointer ( " /foo/null " ) , Value ( ) . Move ( ) , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , d . GetAllocator ( ) ) ;
SetValueByPointer ( d , Pointer ( " /clone " ) , foo , a ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 20:07:50 +08:00
// Generic version
SetValueByPointer ( d , Pointer ( " /foo/int " ) , - 1 , a ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/uint " ) , 0x87654321 , a ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/int64 " ) , i64 , a ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
SetValueByPointer ( d , Pointer ( " /foo/uint64 " ) , u64 , a ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/true " ) , true , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/false " ) , false , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
SetValueByPointer ( d , Pointer ( " /foo/hello " ) , " Hello " , a ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
SetValueByPointer ( d , Pointer ( " /foo/world " ) , buffer , a ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
SetValueByPointer ( d , Pointer ( " /foo/c++ " ) , std : : string ( " C++ " ) , a ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-05-02 20:07:50 +08:00
}
TEST ( Pointer , SetValueByPointer_String ) {
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
// Value version
SetValueByPointer ( d , " /foo/0 " , Value ( 123 ) . Move ( ) , a ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
SetValueByPointer ( d , " /foo/null " , Value ( ) . Move ( ) , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , d . GetAllocator ( ) ) ;
SetValueByPointer ( d , " /clone " , foo , a ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 20:07:50 +08:00
// Generic version
SetValueByPointer ( d , " /foo/int " , - 1 , a ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
SetValueByPointer ( d , " /foo/uint " , 0x87654321 , a ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
SetValueByPointer ( d , " /foo/int64 " , i64 , a ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
SetValueByPointer ( d , " /foo/uint64 " , u64 , a ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
SetValueByPointer ( d , " /foo/true " , true , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
SetValueByPointer ( d , " /foo/false " , false , a ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
SetValueByPointer ( d , " /foo/hello " , " Hello " , a ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
SetValueByPointer ( d , " /foo/world " , buffer , a ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
SetValueByPointer ( d , " /foo/c++ " , std : : string ( " C++ " ) , a ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-04-10 19:28:12 +08:00
}
2015-05-02 22:46:30 +08:00
TEST ( Pointer , SetValueByPointer_Pointer_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
// Value version
SetValueByPointer ( d , Pointer ( " /foo/0 " ) , Value ( 123 ) . Move ( ) ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/null " ) , Value ( ) . Move ( ) ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , d . GetAllocator ( ) ) ;
SetValueByPointer ( d , Pointer ( " /clone " ) , foo ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 22:46:30 +08:00
// Generic version
SetValueByPointer ( d , Pointer ( " /foo/int " ) , - 1 ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/uint " ) , 0x87654321 ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/int64 " ) , i64 ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
SetValueByPointer ( d , Pointer ( " /foo/uint64 " ) , u64 ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/true " ) , true ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
SetValueByPointer ( d , Pointer ( " /foo/false " ) , false ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
SetValueByPointer ( d , Pointer ( " /foo/hello " ) , " Hello " ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
SetValueByPointer ( d , Pointer ( " /foo/world " ) , buffer ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
SetValueByPointer ( d , Pointer ( " /foo/c++ " ) , std : : string ( " C++ " ) ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
TEST ( Pointer , SetValueByPointer_String_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
// Value version
SetValueByPointer ( d , " /foo/0 " , Value ( 123 ) . Move ( ) ) ;
EXPECT_EQ ( 123 , d [ " foo " ] [ 0 ] . GetInt ( ) ) ;
SetValueByPointer ( d , " /foo/null " , Value ( ) . Move ( ) ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/null " ) - > IsNull ( ) ) ;
2015-05-04 10:06:31 +08:00
// Const Value version
const Value foo ( d [ " foo " ] , d . GetAllocator ( ) ) ;
SetValueByPointer ( d , " /clone " , foo ) ;
EXPECT_EQ ( foo , * GetValueByPointer ( d , " /clone " ) ) ;
2015-05-02 22:46:30 +08:00
// Generic version
SetValueByPointer ( d , " /foo/int " , - 1 ) ;
EXPECT_EQ ( - 1 , GetValueByPointer ( d , " /foo/int " ) - > GetInt ( ) ) ;
SetValueByPointer ( d , " /foo/uint " , 0x87654321 ) ;
EXPECT_EQ ( 0x87654321 , GetValueByPointer ( d , " /foo/uint " ) - > GetUint ( ) ) ;
const int64_t i64 = static_cast < int64_t > ( RAPIDJSON_UINT64_C2 ( 0x80000000 , 0 ) ) ;
SetValueByPointer ( d , " /foo/int64 " , i64 ) ;
EXPECT_EQ ( i64 , GetValueByPointer ( d , " /foo/int64 " ) - > GetInt64 ( ) ) ;
const uint64_t u64 = RAPIDJSON_UINT64_C2 ( 0xFFFFFFFFF , 0xFFFFFFFFF ) ;
SetValueByPointer ( d , " /foo/uint64 " , u64 ) ;
EXPECT_EQ ( u64 , GetValueByPointer ( d , " /foo/uint64 " ) - > GetUint64 ( ) ) ;
SetValueByPointer ( d , " /foo/true " , true ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/true " ) - > IsTrue ( ) ) ;
SetValueByPointer ( d , " /foo/false " , false ) ;
EXPECT_TRUE ( GetValueByPointer ( d , " /foo/false " ) - > IsFalse ( ) ) ;
// StringRef version
SetValueByPointer ( d , " /foo/hello " , " Hello " ) ;
EXPECT_STREQ ( " Hello " , GetValueByPointer ( d , " /foo/hello " ) - > GetString ( ) ) ;
// Copy string version
{
char buffer [ 256 ] ;
strcpy ( buffer , " World " ) ;
SetValueByPointer ( d , " /foo/world " , buffer ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
}
EXPECT_STREQ ( " World " , GetValueByPointer ( d , " /foo/world " ) - > GetString ( ) ) ;
2015-05-03 18:55:55 +08:00
# if RAPIDJSON_HAS_STDSTRING
SetValueByPointer ( d , " /foo/c++ " , std : : string ( " C++ " ) ) ;
EXPECT_STREQ ( " C++ " , GetValueByPointer ( d , " /foo/c++ " ) - > GetString ( ) ) ;
# endif
2015-05-02 22:46:30 +08:00
}
2015-04-10 19:28:12 +08:00
TEST ( Pointer , SwapValueByPointer ) {
Document d ;
d . Parse ( kJson ) ;
Document : : AllocatorType & a = d . GetAllocator ( ) ;
SwapValueByPointer ( d , Pointer ( " /foo/0 " ) , * GetValueByPointer ( d , " /foo/1 " ) , a ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
SwapValueByPointer ( d , " /foo/0 " , * GetValueByPointer ( d , " /foo/1 " ) , a ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
}
2015-05-02 22:58:41 +08:00
TEST ( Pointer , SwapValueByPointer_NoAllocator ) {
Document d ;
d . Parse ( kJson ) ;
SwapValueByPointer ( d , Pointer ( " /foo/0 " ) , * GetValueByPointer ( d , " /foo/1 " ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
SwapValueByPointer ( d , " /foo/0 " , * GetValueByPointer ( d , " /foo/1 " ) ) ;
EXPECT_STREQ ( " bar " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 1 ] . GetString ( ) ) ;
}
2015-05-04 15:02:43 +08:00
2015-05-04 21:50:26 +08:00
TEST ( Pointer , EraseValueByPointer_Pointer ) {
Document d ;
d . Parse ( kJson ) ;
EXPECT_FALSE ( EraseValueByPointer ( d , Pointer ( " " ) ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/nonexist " ) . Erase ( d ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , Pointer ( " /foo/0 " ) ) ) ;
EXPECT_EQ ( 1u , d [ " foo " ] . Size ( ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , Pointer ( " /foo/0 " ) ) ) ;
EXPECT_TRUE ( d [ " foo " ] . Empty ( ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , Pointer ( " /foo " ) ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) . Get ( d ) = = 0 ) ;
}
TEST ( Pointer , EraseValueByPointer_String ) {
Document d ;
d . Parse ( kJson ) ;
EXPECT_FALSE ( EraseValueByPointer ( d , " " ) ) ;
EXPECT_FALSE ( Pointer ( " /foo/nonexist " ) . Erase ( d ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , " /foo/0 " ) ) ;
EXPECT_EQ ( 1u , d [ " foo " ] . Size ( ) ) ;
EXPECT_STREQ ( " baz " , d [ " foo " ] [ 0 ] . GetString ( ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , " /foo/0 " ) ) ;
EXPECT_TRUE ( d [ " foo " ] . Empty ( ) ) ;
EXPECT_TRUE ( EraseValueByPointer ( d , " /foo " ) ) ;
EXPECT_TRUE ( Pointer ( " /foo " ) . Get ( d ) = = 0 ) ;
}
2015-05-04 15:02:43 +08:00
TEST ( Pointer , Ambiguity ) {
{
Document d ;
d . Parse ( " { \" 0 \" : [123]} " ) ;
EXPECT_EQ ( 123 , Pointer ( " /0/0 " ) . Get ( d ) - > GetInt ( ) ) ;
Pointer ( " /0/a " ) . Set ( d , 456 ) ; // Change array [123] to object {456}
EXPECT_EQ ( 456 , Pointer ( " /0/a " ) . Get ( d ) - > GetInt ( ) ) ;
}
{
Document d ;
EXPECT_FALSE ( d . Parse ( " [{ \" 0 \" : 123}] " ) . HasParseError ( ) ) ;
EXPECT_EQ ( 123 , Pointer ( " /0/0 " ) . Get ( d ) - > GetInt ( ) ) ;
Pointer ( " /0/1 " ) . Set ( d , 456 ) ; // 1 is treated as "1" to index object
EXPECT_EQ ( 123 , Pointer ( " /0/0 " ) . Get ( d ) - > GetInt ( ) ) ;
EXPECT_EQ ( 456 , Pointer ( " /0/1 " ) . Get ( d ) - > GetInt ( ) ) ;
}
}
2015-11-30 17:22:06 +08:00
2021-01-05 14:20:57 +01:00
TEST ( Pointer , ResolveOnObject ) {
Document d ;
EXPECT_FALSE ( d . Parse ( " { \" a \" : 123} " ) . HasParseError ( ) ) ;
{
Value : : ConstObject o = static_cast < const Document & > ( d ) . GetObject ( ) ;
EXPECT_EQ ( 123 , Pointer ( " /a " ) . Get ( o ) - > GetInt ( ) ) ;
}
{
Value : : Object o = d . GetObject ( ) ;
Pointer ( " /a " ) . Set ( o , 456 , d . GetAllocator ( ) ) ;
EXPECT_EQ ( 456 , Pointer ( " /a " ) . Get ( o ) - > GetInt ( ) ) ;
}
}
TEST ( Pointer , ResolveOnArray ) {
Document d ;
EXPECT_FALSE ( d . Parse ( " [1, 2, 3] " ) . HasParseError ( ) ) ;
{
Value : : ConstArray a = static_cast < const Document & > ( d ) . GetArray ( ) ;
EXPECT_EQ ( 2 , Pointer ( " /1 " ) . Get ( a ) - > GetInt ( ) ) ;
}
{
Value : : Array a = d . GetArray ( ) ;
Pointer ( " /1 " ) . Set ( a , 123 , d . GetAllocator ( ) ) ;
EXPECT_EQ ( 123 , Pointer ( " /1 " ) . Get ( a ) - > GetInt ( ) ) ;
}
}
2018-12-11 00:19:13 +01:00
TEST ( Pointer , LessThan ) {
2018-12-12 22:32:56 +01:00
static const struct {
const char * str ;
bool valid ;
} pointers [ ] = {
{ " /a/b " , true } ,
{ " /a " , true } ,
{ " /d/1 " , true } ,
{ " /d/2/z " , true } ,
{ " /d/2/3 " , true } ,
{ " /d/2 " , true } ,
{ " /a/c " , true } ,
{ " /e/f~g " , false } ,
{ " /d/2/zz " , true } ,
{ " /d/1 " , true } ,
{ " /d/2/z " , true } ,
{ " /e/f~~g " , false } ,
{ " /e/f~0g " , true } ,
{ " /e/f~1g " , true } ,
{ " /e/f.g " , true } ,
{ " " , true }
} ;
static const char * ordered_pointers [ ] = {
" " ,
" /a " ,
2018-12-11 00:19:13 +01:00
" /a/b " ,
" /a/c " ,
" /d/1 " ,
" /d/1 " ,
2018-12-12 22:32:56 +01:00
" /d/2 " ,
2018-12-11 00:19:13 +01:00
" /e/f.g " ,
2018-12-12 22:32:56 +01:00
" /e/f~1g " ,
" /e/f~0g " ,
" /d/2/3 " ,
" /d/2/z " ,
" /d/2/z " ,
" /d/2/zz " ,
NULL , // was invalid "/e/f~g"
NULL // was invalid "/e/f~~g"
2018-12-11 00:19:13 +01:00
} ;
2018-12-11 00:40:05 +01:00
typedef MemoryPoolAllocator < > AllocatorType ;
typedef GenericPointer < Value , AllocatorType > PointerType ;
2018-12-12 22:32:56 +01:00
typedef std : : multimap < PointerType , size_t > PointerMap ;
PointerMap map ;
PointerMap : : iterator it ;
2018-12-11 00:40:05 +01:00
AllocatorType allocator ;
2018-12-11 00:19:13 +01:00
size_t i ;
2018-12-11 00:40:05 +01:00
EXPECT_EQ ( sizeof ( pointers ) / sizeof ( pointers [ 0 ] ) ,
sizeof ( ordered_pointers ) / sizeof ( ordered_pointers [ 0 ] ) ) ;
for ( i = 0 ; i < sizeof ( pointers ) / sizeof ( pointers [ 0 ] ) ; + + i ) {
2018-12-12 22:32:56 +01:00
it = map . insert ( PointerMap : : value_type ( PointerType ( pointers [ i ] . str , & allocator ) , i ) ) ;
if ( ! it - > first . IsValid ( ) ) {
EXPECT_EQ ( + + it , map . end ( ) ) ;
}
2018-12-11 00:19:13 +01:00
}
2018-12-12 22:32:56 +01:00
for ( i = 0 , it = map . begin ( ) ; it ! = map . end ( ) ; + + it , + + i ) {
EXPECT_TRUE ( it - > second < sizeof ( pointers ) / sizeof ( pointers [ 0 ] ) ) ;
EXPECT_EQ ( it - > first . IsValid ( ) , pointers [ it - > second ] . valid ) ;
2018-12-11 00:40:05 +01:00
EXPECT_TRUE ( i < sizeof ( ordered_pointers ) / sizeof ( ordered_pointers [ 0 ] ) ) ;
2018-12-12 22:32:56 +01:00
EXPECT_EQ ( it - > first . IsValid ( ) , ! ! ordered_pointers [ i ] ) ;
if ( it - > first . IsValid ( ) ) {
2018-12-11 00:19:13 +01:00
std : : stringstream ss ;
OStreamWrapper os ( ss ) ;
2018-12-12 22:32:56 +01:00
EXPECT_TRUE ( it - > first . Stringify ( os ) ) ;
EXPECT_EQ ( ss . str ( ) , pointers [ it - > second ] . str ) ;
EXPECT_EQ ( ss . str ( ) , ordered_pointers [ i ] ) ;
2018-12-11 00:19:13 +01:00
}
}
}
2017-09-13 17:03:23 +08:00
// https://github.com/Tencent/rapidjson/issues/483
2015-11-30 17:22:06 +08:00
namespace myjson {
class MyAllocator
{
public :
static const bool kNeedFree = true ;
void * Malloc ( size_t _size ) { return malloc ( _size ) ; }
void * Realloc ( void * _org_p , size_t _org_size , size_t _new_size ) { ( void ) _org_size ; return realloc ( _org_p , _new_size ) ; }
static void Free ( void * _p ) { return free ( _p ) ; }
} ;
typedef rapidjson : : GenericDocument <
rapidjson : : UTF8 < > ,
rapidjson : : MemoryPoolAllocator < MyAllocator > ,
MyAllocator
> Document ;
typedef rapidjson : : GenericPointer <
: : myjson : : Document : : ValueType ,
MyAllocator
> Pointer ;
typedef : : myjson : : Document : : ValueType Value ;
}
TEST ( Pointer , Issue483 ) {
std : : string mystr , path ;
myjson : : Document document ;
myjson : : Value value ( rapidjson : : kStringType ) ;
2015-12-18 18:34:04 +08:00
value . SetString ( mystr . c_str ( ) , static_cast < SizeType > ( mystr . length ( ) ) , document . GetAllocator ( ) ) ;
2015-11-30 17:22:06 +08:00
myjson : : Pointer ( path . c_str ( ) ) . Set ( document , value , document . GetAllocator ( ) ) ;
}