first commit
This commit is contained in:
46
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/CMakeLists.txt
vendored
Normal file
46
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
set(UNITTEST_SOURCES
|
||||
bigintegertest.cpp
|
||||
documenttest.cpp
|
||||
encodedstreamtest.cpp
|
||||
encodingstest.cpp
|
||||
filestreamtest.cpp
|
||||
jsoncheckertest.cpp
|
||||
namespacetest.cpp
|
||||
readertest.cpp
|
||||
stringbuffertest.cpp
|
||||
strtodtest.cpp
|
||||
unittest.cpp
|
||||
valuetest.cpp
|
||||
writertest.cpp)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Weffc++ -Wswitch-default")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Weffc++ -Wswitch-default")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
endif()
|
||||
|
||||
add_library(namespacetest STATIC namespacetest.cpp)
|
||||
|
||||
add_executable(unittest ${UNITTEST_SOURCES})
|
||||
target_link_libraries(unittest ${TEST_LIBRARIES} namespacetest)
|
||||
|
||||
add_dependencies(tests unittest)
|
||||
|
||||
add_test(NAME unittest
|
||||
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_test(NAME valgrind_unittest
|
||||
COMMAND valgrind --leak-check=full --error-exitcode=1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_test(NAME symbol_check
|
||||
COMMAND sh -c "objdump -t -C libnamespacetest.a | grep rapidjson ; test $? -ne 0"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
endif(NOT MSVC)
|
||||
139
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/bigintegertest.cpp
vendored
Normal file
139
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/bigintegertest.cpp
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
#include "rapidjson/internal/biginteger.h"
|
||||
|
||||
using namespace rapidjson::internal;
|
||||
|
||||
#define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
|
||||
|
||||
static const BigInteger kZero(0);
|
||||
static const BigInteger kOne(1);
|
||||
static const BigInteger kUint64Max = BIGINTEGER_LITERAL("18446744073709551615");
|
||||
static const BigInteger kTwo64 = BIGINTEGER_LITERAL("18446744073709551616");
|
||||
|
||||
TEST(BigInteger, Constructor) {
|
||||
EXPECT_TRUE(kZero.IsZero());
|
||||
EXPECT_TRUE(kZero == kZero);
|
||||
EXPECT_TRUE(kZero == BIGINTEGER_LITERAL("0"));
|
||||
EXPECT_TRUE(kZero == BIGINTEGER_LITERAL("00"));
|
||||
|
||||
const BigInteger a(123);
|
||||
EXPECT_TRUE(a == a);
|
||||
EXPECT_TRUE(a == BIGINTEGER_LITERAL("123"));
|
||||
EXPECT_TRUE(a == BIGINTEGER_LITERAL("0123"));
|
||||
|
||||
EXPECT_EQ(2u, kTwo64.GetCount());
|
||||
EXPECT_EQ(0u, kTwo64.GetDigit(0));
|
||||
EXPECT_EQ(1u, kTwo64.GetDigit(1));
|
||||
}
|
||||
|
||||
TEST(BigInteger, AddUint64) {
|
||||
BigInteger a = kZero;
|
||||
a += 0u;
|
||||
EXPECT_TRUE(kZero == a);
|
||||
|
||||
a += 1u;
|
||||
EXPECT_TRUE(kOne == a);
|
||||
|
||||
a += 1u;
|
||||
EXPECT_TRUE(BigInteger(2) == a);
|
||||
|
||||
EXPECT_TRUE(BigInteger(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)) == kUint64Max);
|
||||
BigInteger b = kUint64Max;
|
||||
b += 1u;
|
||||
EXPECT_TRUE(kTwo64 == b);
|
||||
b += RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("36893488147419103231") == b);
|
||||
}
|
||||
|
||||
TEST(BigInteger, MultiplyUint64) {
|
||||
BigInteger a = kZero;
|
||||
a *= static_cast <uint64_t>(0);
|
||||
EXPECT_TRUE(kZero == a);
|
||||
a *= static_cast <uint64_t>(123);
|
||||
EXPECT_TRUE(kZero == a);
|
||||
|
||||
BigInteger b = kOne;
|
||||
b *= static_cast<uint64_t>(1);
|
||||
EXPECT_TRUE(kOne == b);
|
||||
b *= static_cast<uint64_t>(0);
|
||||
EXPECT_TRUE(kZero == b);
|
||||
|
||||
BigInteger c(123);
|
||||
c *= static_cast<uint64_t>(456u);
|
||||
EXPECT_TRUE(BigInteger(123u * 456u) == c);
|
||||
c *= RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("1034640981606221330982120") == c);
|
||||
c *= RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("19085757395861596536664473018420572782123800") == c);
|
||||
}
|
||||
|
||||
TEST(BigInteger, MultiplyUint32) {
|
||||
BigInteger a = kZero;
|
||||
a *= static_cast <uint32_t>(0);
|
||||
EXPECT_TRUE(kZero == a);
|
||||
a *= static_cast <uint32_t>(123);
|
||||
EXPECT_TRUE(kZero == a);
|
||||
|
||||
BigInteger b = kOne;
|
||||
b *= static_cast<uint32_t>(1);
|
||||
EXPECT_TRUE(kOne == b);
|
||||
b *= static_cast<uint32_t>(0);
|
||||
EXPECT_TRUE(kZero == b);
|
||||
|
||||
BigInteger c(123);
|
||||
c *= static_cast<uint32_t>(456u);
|
||||
EXPECT_TRUE(BigInteger(123u * 456u) == c);
|
||||
c *= 0xFFFFFFFFu;
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("240896125641960") == c);
|
||||
c *= 0xFFFFFFFFu;
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("1034640981124429079698200") == c);
|
||||
}
|
||||
|
||||
TEST(BigInteger, LeftShift) {
|
||||
BigInteger a = kZero;
|
||||
a <<= 1;
|
||||
EXPECT_TRUE(kZero == a);
|
||||
a <<= 64;
|
||||
EXPECT_TRUE(kZero == a);
|
||||
|
||||
a = BigInteger(123);
|
||||
a <<= 0;
|
||||
EXPECT_TRUE(BigInteger(123) == a);
|
||||
a <<= 1;
|
||||
EXPECT_TRUE(BigInteger(246) == a);
|
||||
a <<= 64;
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("4537899042132549697536") == a);
|
||||
a <<= 99;
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("2876235222267216943024851750785644982682875244576768") == a);
|
||||
}
|
||||
|
||||
TEST(BigInteger, Compare) {
|
||||
EXPECT_EQ(0, kZero.Compare(kZero));
|
||||
EXPECT_EQ(1, kOne.Compare(kZero));
|
||||
EXPECT_EQ(-1, kZero.Compare(kOne));
|
||||
EXPECT_EQ(0, kUint64Max.Compare(kUint64Max));
|
||||
EXPECT_EQ(0, kTwo64.Compare(kTwo64));
|
||||
EXPECT_EQ(-1, kUint64Max.Compare(kTwo64));
|
||||
EXPECT_EQ(1, kTwo64.Compare(kUint64Max));
|
||||
}
|
||||
488
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/documenttest.cpp
vendored
Normal file
488
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/documenttest.cpp
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "rapidjson/encodedstream.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
template <typename Allocator, typename StackAllocator>
|
||||
void ParseTest() {
|
||||
typedef GenericDocument<UTF8<>, Allocator, StackAllocator> DocumentType;
|
||||
typedef typename DocumentType::ValueType ValueType;
|
||||
DocumentType doc;
|
||||
|
||||
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
|
||||
EXPECT_TRUE(doc.IsObject());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("hello"));
|
||||
const ValueType& hello = doc["hello"];
|
||||
EXPECT_TRUE(hello.IsString());
|
||||
EXPECT_STREQ("world", hello.GetString());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("t"));
|
||||
const ValueType& t = doc["t"];
|
||||
EXPECT_TRUE(t.IsTrue());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("f"));
|
||||
const ValueType& f = doc["f"];
|
||||
EXPECT_TRUE(f.IsFalse());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("n"));
|
||||
const ValueType& n = doc["n"];
|
||||
EXPECT_TRUE(n.IsNull());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("i"));
|
||||
const ValueType& i = doc["i"];
|
||||
EXPECT_TRUE(i.IsNumber());
|
||||
EXPECT_EQ(123, i.GetInt());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("pi"));
|
||||
const ValueType& pi = doc["pi"];
|
||||
EXPECT_TRUE(pi.IsNumber());
|
||||
EXPECT_EQ(3.1416, pi.GetDouble());
|
||||
|
||||
EXPECT_TRUE(doc.HasMember("a"));
|
||||
const ValueType& a = doc["a"];
|
||||
EXPECT_TRUE(a.IsArray());
|
||||
EXPECT_EQ(4u, a.Size());
|
||||
for (SizeType i = 0; i < 4; i++)
|
||||
EXPECT_EQ(i + 1, a[i].GetUint());
|
||||
}
|
||||
|
||||
TEST(Document, Parse) {
|
||||
ParseTest<MemoryPoolAllocator<>, CrtAllocator>();
|
||||
ParseTest<MemoryPoolAllocator<>, MemoryPoolAllocator<> >();
|
||||
ParseTest<CrtAllocator, MemoryPoolAllocator<> >();
|
||||
ParseTest<CrtAllocator, CrtAllocator>();
|
||||
}
|
||||
|
||||
static FILE* OpenEncodedFile(const char* filename) {
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "encodings/%s", filename);
|
||||
FILE *fp = fopen(buffer, "rb");
|
||||
if (!fp) {
|
||||
sprintf(buffer, "../../bin/encodings/%s", filename);
|
||||
fp = fopen(buffer, "rb");
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
TEST(Document, ParseStream_EncodedInputStream) {
|
||||
// UTF8 -> UTF16
|
||||
FILE* fp = OpenEncodedFile("utf8.json");
|
||||
char buffer[256];
|
||||
FileReadStream bis(fp, buffer, sizeof(buffer));
|
||||
EncodedInputStream<UTF8<>, FileReadStream> eis(bis);
|
||||
|
||||
GenericDocument<UTF16<> > d;
|
||||
d.ParseStream<0, UTF8<> >(eis);
|
||||
EXPECT_FALSE(d.HasParseError());
|
||||
|
||||
fclose(fp);
|
||||
|
||||
wchar_t expected[] = L"I can eat glass and it doesn't hurt me.";
|
||||
GenericValue<UTF16<> >& v = d[L"en"];
|
||||
EXPECT_TRUE(v.IsString());
|
||||
EXPECT_EQ(sizeof(expected) / sizeof(wchar_t) - 1, v.GetStringLength());
|
||||
EXPECT_EQ(0, StrCmp(expected, v.GetString()));
|
||||
|
||||
// UTF16 -> UTF8 in memory
|
||||
StringBuffer bos;
|
||||
typedef EncodedOutputStream<UTF8<>, StringBuffer> OutputStream;
|
||||
OutputStream eos(bos, false); // Not writing BOM
|
||||
Writer<OutputStream, UTF16<>, UTF8<> > writer(eos);
|
||||
d.Accept(writer);
|
||||
|
||||
{
|
||||
// Condense the original file and compare.
|
||||
FILE *fp = OpenEncodedFile("utf8.json");
|
||||
FileReadStream is(fp, buffer, sizeof(buffer));
|
||||
Reader reader;
|
||||
StringBuffer bos2;
|
||||
Writer<StringBuffer> writer(bos2);
|
||||
reader.Parse(is, writer);
|
||||
|
||||
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
|
||||
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Document, ParseStream_AutoUTFInputStream) {
|
||||
// Any -> UTF8
|
||||
FILE* fp = OpenEncodedFile("utf32be.json");
|
||||
char buffer[256];
|
||||
FileReadStream bis(fp, buffer, sizeof(buffer));
|
||||
AutoUTFInputStream<unsigned, FileReadStream> eis(bis);
|
||||
|
||||
Document d;
|
||||
d.ParseStream<0, AutoUTF<unsigned> >(eis);
|
||||
EXPECT_FALSE(d.HasParseError());
|
||||
|
||||
fclose(fp);
|
||||
|
||||
char expected[] = "I can eat glass and it doesn't hurt me.";
|
||||
Value& v = d["en"];
|
||||
EXPECT_TRUE(v.IsString());
|
||||
EXPECT_EQ(sizeof(expected) - 1, v.GetStringLength());
|
||||
EXPECT_EQ(0, StrCmp(expected, v.GetString()));
|
||||
|
||||
// UTF8 -> UTF8 in memory
|
||||
StringBuffer bos;
|
||||
Writer<StringBuffer> writer(bos);
|
||||
d.Accept(writer);
|
||||
|
||||
{
|
||||
// Condense the original file and compare.
|
||||
FILE *fp = OpenEncodedFile("utf8.json");
|
||||
FileReadStream is(fp, buffer, sizeof(buffer));
|
||||
Reader reader;
|
||||
StringBuffer bos2;
|
||||
Writer<StringBuffer> writer(bos2);
|
||||
reader.Parse(is, writer);
|
||||
|
||||
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
|
||||
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Document, Swap) {
|
||||
Document d1;
|
||||
Document::AllocatorType& a = d1.GetAllocator();
|
||||
|
||||
d1.SetArray().PushBack(1, a).PushBack(2, a);
|
||||
|
||||
Value o;
|
||||
o.SetObject().AddMember("a", 1, a);
|
||||
|
||||
// Swap between Document and Value
|
||||
d1.Swap(o);
|
||||
EXPECT_TRUE(d1.IsObject());
|
||||
EXPECT_TRUE(o.IsArray());
|
||||
|
||||
// Swap between Document and Document
|
||||
Document d2;
|
||||
d2.SetArray().PushBack(3, a);
|
||||
d1.Swap(d2);
|
||||
EXPECT_TRUE(d1.IsArray());
|
||||
EXPECT_TRUE(d2.IsObject());
|
||||
}
|
||||
|
||||
// This should be slow due to assignment in inner-loop.
|
||||
struct OutputStringStream : public std::ostringstream {
|
||||
typedef char Ch;
|
||||
|
||||
void Put(char c) {
|
||||
put(c);
|
||||
}
|
||||
void Flush() {}
|
||||
};
|
||||
|
||||
TEST(Document, AcceptWriter) {
|
||||
Document doc;
|
||||
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
|
||||
OutputStringStream os;
|
||||
Writer<OutputStringStream> writer(os);
|
||||
doc.Accept(writer);
|
||||
|
||||
EXPECT_EQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3,4]}", os.str());
|
||||
}
|
||||
|
||||
// Issue 226: Value of string type should not point to NULL
|
||||
TEST(Document, AssertAcceptInvalidNameType) {
|
||||
Document doc;
|
||||
doc.SetObject();
|
||||
doc.AddMember("a", 0, doc.GetAllocator());
|
||||
doc.FindMember("a")->name.SetNull(); // Change name to non-string type.
|
||||
|
||||
OutputStringStream os;
|
||||
Writer<OutputStringStream> writer(os);
|
||||
ASSERT_THROW(doc.Accept(writer), AssertException);
|
||||
}
|
||||
|
||||
// Issue 44: SetStringRaw doesn't work with wchar_t
|
||||
TEST(Document, UTF16_Document) {
|
||||
GenericDocument< UTF16<> > json;
|
||||
json.Parse<kParseValidateEncodingFlag>(L"[{\"created_at\":\"Wed Oct 30 17:13:20 +0000 2012\"}]");
|
||||
|
||||
ASSERT_TRUE(json.IsArray());
|
||||
GenericValue< UTF16<> >& v = json[0];
|
||||
ASSERT_TRUE(v.IsObject());
|
||||
|
||||
GenericValue< UTF16<> >& s = v[L"created_at"];
|
||||
ASSERT_TRUE(s.IsString());
|
||||
|
||||
EXPECT_EQ(0, wcscmp(L"Wed Oct 30 17:13:20 +0000 2012", s.GetString()));
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
TEST(Document, Traits) {
|
||||
static_assert(std::is_constructible<Document>::value, "");
|
||||
static_assert(std::is_default_constructible<Document>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_copy_constructible<Document>::value, "");
|
||||
#endif
|
||||
static_assert(std::is_move_constructible<Document>::value, "");
|
||||
|
||||
static_assert(!std::is_nothrow_constructible<Document>::value, "");
|
||||
static_assert(!std::is_nothrow_default_constructible<Document>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_nothrow_copy_constructible<Document>::value, "");
|
||||
static_assert(std::is_nothrow_move_constructible<Document>::value, "");
|
||||
#endif
|
||||
|
||||
static_assert(std::is_assignable<Document,Document>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_copy_assignable<Document>::value, "");
|
||||
#endif
|
||||
static_assert(std::is_move_assignable<Document>::value, "");
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static_assert(std::is_nothrow_assignable<Document, Document>::value, "");
|
||||
#endif
|
||||
static_assert(!std::is_nothrow_copy_assignable<Document>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(std::is_nothrow_move_assignable<Document>::value, "");
|
||||
#endif
|
||||
|
||||
static_assert( std::is_destructible<Document>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(std::is_nothrow_destructible<Document>::value, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
struct DocumentMove: public ::testing::Test {
|
||||
};
|
||||
|
||||
typedef ::testing::Types< CrtAllocator, MemoryPoolAllocator<> > MoveAllocatorTypes;
|
||||
TYPED_TEST_CASE(DocumentMove, MoveAllocatorTypes);
|
||||
|
||||
TYPED_TEST(DocumentMove, MoveConstructor) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef GenericDocument<UTF8<>, Allocator> Document;
|
||||
Allocator allocator;
|
||||
|
||||
Document a(&allocator);
|
||||
a.Parse("[\"one\", \"two\", \"three\"]");
|
||||
EXPECT_FALSE(a.HasParseError());
|
||||
EXPECT_TRUE(a.IsArray());
|
||||
EXPECT_EQ(3u, a.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), &allocator);
|
||||
|
||||
// Document b(a); // does not compile (!is_copy_constructible)
|
||||
Document b(std::move(a));
|
||||
EXPECT_TRUE(a.IsNull());
|
||||
EXPECT_TRUE(b.IsArray());
|
||||
EXPECT_EQ(3u, b.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), (void*)0);
|
||||
EXPECT_EQ(&b.GetAllocator(), &allocator);
|
||||
|
||||
b.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
|
||||
EXPECT_FALSE(b.HasParseError());
|
||||
EXPECT_TRUE(b.IsObject());
|
||||
EXPECT_EQ(2u, b.MemberCount());
|
||||
|
||||
// Document c = a; // does not compile (!is_copy_constructible)
|
||||
Document c = std::move(b);
|
||||
EXPECT_TRUE(b.IsNull());
|
||||
EXPECT_TRUE(c.IsObject());
|
||||
EXPECT_EQ(2u, c.MemberCount());
|
||||
EXPECT_EQ(&b.GetAllocator(), (void*)0);
|
||||
EXPECT_EQ(&c.GetAllocator(), &allocator);
|
||||
}
|
||||
|
||||
TYPED_TEST(DocumentMove, MoveConstructorParseError) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef GenericDocument<UTF8<>, Allocator> Document;
|
||||
|
||||
ParseResult noError;
|
||||
Document a;
|
||||
a.Parse("{ 4 = 4]");
|
||||
ParseResult error(a.GetParseError(), a.GetErrorOffset());
|
||||
EXPECT_TRUE(a.HasParseError());
|
||||
EXPECT_NE(error.Code(), noError.Code());
|
||||
EXPECT_NE(error.Offset(), noError.Offset());
|
||||
|
||||
Document b(std::move(a));
|
||||
EXPECT_FALSE(a.HasParseError());
|
||||
EXPECT_TRUE(b.HasParseError());
|
||||
EXPECT_EQ(a.GetParseError(), noError.Code());
|
||||
EXPECT_EQ(b.GetParseError(), error.Code());
|
||||
EXPECT_EQ(a.GetErrorOffset(), noError.Offset());
|
||||
EXPECT_EQ(b.GetErrorOffset(), error.Offset());
|
||||
|
||||
Document c(std::move(b));
|
||||
EXPECT_FALSE(b.HasParseError());
|
||||
EXPECT_TRUE(c.HasParseError());
|
||||
EXPECT_EQ(b.GetParseError(), noError.Code());
|
||||
EXPECT_EQ(c.GetParseError(), error.Code());
|
||||
EXPECT_EQ(b.GetErrorOffset(), noError.Offset());
|
||||
EXPECT_EQ(c.GetErrorOffset(), error.Offset());
|
||||
}
|
||||
|
||||
// This test does not properly use parsing, just for testing.
|
||||
// It must call ClearStack() explicitly to prevent memory leak.
|
||||
// But here we cannot as ClearStack() is private.
|
||||
#if 0
|
||||
TYPED_TEST(DocumentMove, MoveConstructorStack) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef UTF8<> Encoding;
|
||||
typedef GenericDocument<Encoding, Allocator> Document;
|
||||
|
||||
Document a;
|
||||
size_t defaultCapacity = a.GetStackCapacity();
|
||||
|
||||
// Trick Document into getting GetStackCapacity() to return non-zero
|
||||
typedef GenericReader<Encoding, Encoding, Allocator> Reader;
|
||||
Reader reader(&a.GetAllocator());
|
||||
GenericStringStream<Encoding> is("[\"one\", \"two\", \"three\"]");
|
||||
reader.template Parse<kParseDefaultFlags>(is, a);
|
||||
size_t capacity = a.GetStackCapacity();
|
||||
EXPECT_GT(capacity, 0u);
|
||||
|
||||
Document b(std::move(a));
|
||||
EXPECT_EQ(a.GetStackCapacity(), defaultCapacity);
|
||||
EXPECT_EQ(b.GetStackCapacity(), capacity);
|
||||
|
||||
Document c = std::move(b);
|
||||
EXPECT_EQ(b.GetStackCapacity(), defaultCapacity);
|
||||
EXPECT_EQ(c.GetStackCapacity(), capacity);
|
||||
}
|
||||
#endif
|
||||
|
||||
TYPED_TEST(DocumentMove, MoveAssignment) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef GenericDocument<UTF8<>, Allocator> Document;
|
||||
Allocator allocator;
|
||||
|
||||
Document a(&allocator);
|
||||
a.Parse("[\"one\", \"two\", \"three\"]");
|
||||
EXPECT_FALSE(a.HasParseError());
|
||||
EXPECT_TRUE(a.IsArray());
|
||||
EXPECT_EQ(3u, a.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), &allocator);
|
||||
|
||||
// Document b; b = a; // does not compile (!is_copy_assignable)
|
||||
Document b;
|
||||
b = std::move(a);
|
||||
EXPECT_TRUE(a.IsNull());
|
||||
EXPECT_TRUE(b.IsArray());
|
||||
EXPECT_EQ(3u, b.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), (void*)0);
|
||||
EXPECT_EQ(&b.GetAllocator(), &allocator);
|
||||
|
||||
b.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
|
||||
EXPECT_FALSE(b.HasParseError());
|
||||
EXPECT_TRUE(b.IsObject());
|
||||
EXPECT_EQ(2u, b.MemberCount());
|
||||
|
||||
// Document c; c = a; // does not compile (see static_assert)
|
||||
Document c;
|
||||
c = std::move(b);
|
||||
EXPECT_TRUE(b.IsNull());
|
||||
EXPECT_TRUE(c.IsObject());
|
||||
EXPECT_EQ(2u, c.MemberCount());
|
||||
EXPECT_EQ(&b.GetAllocator(), (void*)0);
|
||||
EXPECT_EQ(&c.GetAllocator(), &allocator);
|
||||
}
|
||||
|
||||
TYPED_TEST(DocumentMove, MoveAssignmentParseError) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef GenericDocument<UTF8<>, Allocator> Document;
|
||||
|
||||
ParseResult noError;
|
||||
Document a;
|
||||
a.Parse("{ 4 = 4]");
|
||||
ParseResult error(a.GetParseError(), a.GetErrorOffset());
|
||||
EXPECT_TRUE(a.HasParseError());
|
||||
EXPECT_NE(error.Code(), noError.Code());
|
||||
EXPECT_NE(error.Offset(), noError.Offset());
|
||||
|
||||
Document b;
|
||||
b = std::move(a);
|
||||
EXPECT_FALSE(a.HasParseError());
|
||||
EXPECT_TRUE(b.HasParseError());
|
||||
EXPECT_EQ(a.GetParseError(), noError.Code());
|
||||
EXPECT_EQ(b.GetParseError(), error.Code());
|
||||
EXPECT_EQ(a.GetErrorOffset(), noError.Offset());
|
||||
EXPECT_EQ(b.GetErrorOffset(), error.Offset());
|
||||
|
||||
Document c;
|
||||
c = std::move(b);
|
||||
EXPECT_FALSE(b.HasParseError());
|
||||
EXPECT_TRUE(c.HasParseError());
|
||||
EXPECT_EQ(b.GetParseError(), noError.Code());
|
||||
EXPECT_EQ(c.GetParseError(), error.Code());
|
||||
EXPECT_EQ(b.GetErrorOffset(), noError.Offset());
|
||||
EXPECT_EQ(c.GetErrorOffset(), error.Offset());
|
||||
}
|
||||
|
||||
// This test does not properly use parsing, just for testing.
|
||||
// It must call ClearStack() explicitly to prevent memory leak.
|
||||
// But here we cannot as ClearStack() is private.
|
||||
#if 0
|
||||
TYPED_TEST(DocumentMove, MoveAssignmentStack) {
|
||||
typedef TypeParam Allocator;
|
||||
typedef UTF8<> Encoding;
|
||||
typedef GenericDocument<Encoding, Allocator> Document;
|
||||
|
||||
Document a;
|
||||
size_t defaultCapacity = a.GetStackCapacity();
|
||||
|
||||
// Trick Document into getting GetStackCapacity() to return non-zero
|
||||
typedef GenericReader<Encoding, Encoding, Allocator> Reader;
|
||||
Reader reader(&a.GetAllocator());
|
||||
GenericStringStream<Encoding> is("[\"one\", \"two\", \"three\"]");
|
||||
reader.template Parse<kParseDefaultFlags>(is, a);
|
||||
size_t capacity = a.GetStackCapacity();
|
||||
EXPECT_GT(capacity, 0u);
|
||||
|
||||
Document b;
|
||||
b = std::move(a);
|
||||
EXPECT_EQ(a.GetStackCapacity(), defaultCapacity);
|
||||
EXPECT_EQ(b.GetStackCapacity(), capacity);
|
||||
|
||||
Document c;
|
||||
c = std::move(b);
|
||||
EXPECT_EQ(b.GetStackCapacity(), defaultCapacity);
|
||||
EXPECT_EQ(c.GetStackCapacity(), capacity);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
// Issue 22: Memory corruption via operator=
|
||||
// Fixed by making unimplemented assignment operator private.
|
||||
//TEST(Document, Assignment) {
|
||||
// Document d1;
|
||||
// Document d2;
|
||||
// d1 = d2;
|
||||
//}
|
||||
296
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/encodedstreamtest.cpp
vendored
Normal file
296
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/encodedstreamtest.cpp
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/encodedstream.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/memorystream.h"
|
||||
#include "rapidjson/memorybuffer.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
class EncodedStreamTest : public ::testing::Test {
|
||||
public:
|
||||
EncodedStreamTest() : json_(), length_() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
json_ = ReadFile("utf8.json", true, &length_);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
free(json_);
|
||||
json_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
EncodedStreamTest(const EncodedStreamTest&);
|
||||
EncodedStreamTest& operator=(const EncodedStreamTest&);
|
||||
|
||||
protected:
|
||||
static FILE* Open(const char* filename) {
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "encodings/%s", filename);
|
||||
FILE *fp = fopen(buffer, "rb");
|
||||
if (!fp) {
|
||||
sprintf(buffer, "../../bin/encodings/%s", filename);
|
||||
fp = fopen(buffer, "rb");
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static char *ReadFile(const char* filename, bool appendPath, size_t* outLength) {
|
||||
FILE *fp = appendPath ? Open(filename) : fopen(filename, "rb");
|
||||
|
||||
if (!fp) {
|
||||
*outLength = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
*outLength = (size_t)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* buffer = (char*)malloc(*outLength + 1);
|
||||
size_t readLength = fread(buffer, 1, *outLength, fp);
|
||||
buffer[readLength] = '\0';
|
||||
fclose(fp);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <typename FileEncoding, typename MemoryEncoding>
|
||||
void TestEncodedInputStream(const char* filename) {
|
||||
// Test FileReadStream
|
||||
{
|
||||
char buffer[16];
|
||||
FILE *fp = Open(filename);
|
||||
ASSERT_TRUE(fp != 0);
|
||||
FileReadStream fs(fp, buffer, sizeof(buffer));
|
||||
EncodedInputStream<FileEncoding, FileReadStream> eis(fs);
|
||||
StringStream s(json_);
|
||||
|
||||
while (eis.Peek() != '\0') {
|
||||
unsigned expected, actual;
|
||||
EXPECT_TRUE(UTF8<>::Decode(s, &expected));
|
||||
EXPECT_TRUE(MemoryEncoding::Decode(eis, &actual));
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// Test MemoryStream
|
||||
{
|
||||
size_t size;
|
||||
char* data = ReadFile(filename, true, &size);
|
||||
MemoryStream ms(data, size);
|
||||
EncodedInputStream<FileEncoding, MemoryStream> eis(ms);
|
||||
StringStream s(json_);
|
||||
|
||||
while (eis.Peek() != '\0') {
|
||||
unsigned expected, actual;
|
||||
EXPECT_TRUE(UTF8<>::Decode(s, &expected));
|
||||
EXPECT_TRUE(MemoryEncoding::Decode(eis, &actual));
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void TestAutoUTFInputStream(const char *filename) {
|
||||
// Test FileReadStream
|
||||
{
|
||||
char buffer[16];
|
||||
FILE *fp = Open(filename);
|
||||
ASSERT_TRUE(fp != 0);
|
||||
FileReadStream fs(fp, buffer, sizeof(buffer));
|
||||
AutoUTFInputStream<unsigned, FileReadStream> eis(fs);
|
||||
StringStream s(json_);
|
||||
while (eis.Peek() != '\0') {
|
||||
unsigned expected, actual;
|
||||
EXPECT_TRUE(UTF8<>::Decode(s, &expected));
|
||||
EXPECT_TRUE(AutoUTF<unsigned>::Decode(eis, &actual));
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// Test MemoryStream
|
||||
{
|
||||
size_t size;
|
||||
char* data = ReadFile(filename, true, &size);
|
||||
MemoryStream ms(data, size);
|
||||
AutoUTFInputStream<unsigned, MemoryStream> eis(ms);
|
||||
StringStream s(json_);
|
||||
|
||||
while (eis.Peek() != '\0') {
|
||||
unsigned expected, actual;
|
||||
EXPECT_TRUE(UTF8<>::Decode(s, &expected));
|
||||
EXPECT_TRUE(AutoUTF<unsigned>::Decode(eis, &actual));
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FileEncoding, typename MemoryEncoding>
|
||||
void TestEncodedOutputStream(const char* expectedFilename, bool putBOM) {
|
||||
// Test FileWriteStream
|
||||
{
|
||||
char filename[L_tmpnam];
|
||||
FILE* fp = TempFile(filename);
|
||||
char buffer[16];
|
||||
FileWriteStream os(fp, buffer, sizeof(buffer));
|
||||
EncodedOutputStream<FileEncoding, FileWriteStream> eos(os, putBOM);
|
||||
StringStream s(json_);
|
||||
while (s.Peek() != '\0') {
|
||||
bool success = Transcoder<UTF8<>, MemoryEncoding>::Transcode(s, eos);
|
||||
EXPECT_TRUE(success);
|
||||
}
|
||||
eos.Flush();
|
||||
fclose(fp);
|
||||
EXPECT_TRUE(CompareFile(filename, expectedFilename));
|
||||
remove(filename);
|
||||
}
|
||||
|
||||
// Test MemoryBuffer
|
||||
{
|
||||
MemoryBuffer mb;
|
||||
EncodedOutputStream<FileEncoding, MemoryBuffer> eos(mb, putBOM);
|
||||
StringStream s(json_);
|
||||
while (s.Peek() != '\0') {
|
||||
bool success = Transcoder<UTF8<>, MemoryEncoding>::Transcode(s, eos);
|
||||
EXPECT_TRUE(success);
|
||||
}
|
||||
eos.Flush();
|
||||
EXPECT_TRUE(CompareBufferFile(mb.GetBuffer(), mb.GetSize(), expectedFilename));
|
||||
}
|
||||
}
|
||||
|
||||
void TestAutoUTFOutputStream(UTFType type, bool putBOM, const char *expectedFilename) {
|
||||
// Test FileWriteStream
|
||||
{
|
||||
char filename[L_tmpnam];
|
||||
FILE* fp = TempFile(filename);
|
||||
|
||||
char buffer[16];
|
||||
FileWriteStream os(fp, buffer, sizeof(buffer));
|
||||
AutoUTFOutputStream<unsigned, FileWriteStream> eos(os, type, putBOM);
|
||||
StringStream s(json_);
|
||||
while (s.Peek() != '\0') {
|
||||
bool success = Transcoder<UTF8<>, AutoUTF<unsigned> >::Transcode(s, eos);
|
||||
EXPECT_TRUE(success);
|
||||
}
|
||||
eos.Flush();
|
||||
fclose(fp);
|
||||
EXPECT_TRUE(CompareFile(filename, expectedFilename));
|
||||
remove(filename);
|
||||
}
|
||||
|
||||
// Test MemoryBuffer
|
||||
{
|
||||
MemoryBuffer mb;
|
||||
AutoUTFOutputStream<unsigned, MemoryBuffer> eos(mb, type, putBOM);
|
||||
StringStream s(json_);
|
||||
while (s.Peek() != '\0') {
|
||||
bool success = Transcoder<UTF8<>, AutoUTF<unsigned> >::Transcode(s, eos);
|
||||
EXPECT_TRUE(success);
|
||||
}
|
||||
eos.Flush();
|
||||
EXPECT_TRUE(CompareBufferFile(mb.GetBuffer(), mb.GetSize(), expectedFilename));
|
||||
}
|
||||
}
|
||||
|
||||
bool CompareFile(const char* filename, const char* expectedFilename) {
|
||||
size_t actualLength, expectedLength;
|
||||
char* actualBuffer = ReadFile(filename, false, &actualLength);
|
||||
char* expectedBuffer = ReadFile(expectedFilename, true, &expectedLength);
|
||||
bool ret = (expectedLength == actualLength) && memcmp(expectedBuffer, actualBuffer, actualLength) == 0;
|
||||
free(actualBuffer);
|
||||
free(expectedBuffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CompareBufferFile(const char* actualBuffer, size_t actualLength, const char* expectedFilename) {
|
||||
size_t expectedLength;
|
||||
char* expectedBuffer = ReadFile(expectedFilename, true, &expectedLength);
|
||||
bool ret = (expectedLength == actualLength) && memcmp(expectedBuffer, actualBuffer, actualLength) == 0;
|
||||
free(expectedBuffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *json_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
TEST_F(EncodedStreamTest, EncodedInputStream) {
|
||||
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8.json");
|
||||
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8bom.json");
|
||||
TestEncodedInputStream<UTF16LE<>, UTF16<> >("utf16le.json");
|
||||
TestEncodedInputStream<UTF16LE<>, UTF16<> >("utf16lebom.json");
|
||||
TestEncodedInputStream<UTF16BE<>, UTF16<> >("utf16be.json");
|
||||
TestEncodedInputStream<UTF16BE<>, UTF16<> >("utf16bebom.json");
|
||||
TestEncodedInputStream<UTF32LE<>, UTF32<> >("utf32le.json");
|
||||
TestEncodedInputStream<UTF32LE<>, UTF32<> >("utf32lebom.json");
|
||||
TestEncodedInputStream<UTF32BE<>, UTF32<> >("utf32be.json");
|
||||
TestEncodedInputStream<UTF32BE<>, UTF32<> >("utf32bebom.json");
|
||||
}
|
||||
|
||||
TEST_F(EncodedStreamTest, AutoUTFInputStream) {
|
||||
TestAutoUTFInputStream("utf8.json");
|
||||
TestAutoUTFInputStream("utf8bom.json");
|
||||
TestAutoUTFInputStream("utf16le.json");
|
||||
TestAutoUTFInputStream("utf16lebom.json");
|
||||
TestAutoUTFInputStream("utf16be.json");
|
||||
TestAutoUTFInputStream("utf16bebom.json");
|
||||
TestAutoUTFInputStream("utf32le.json");
|
||||
TestAutoUTFInputStream("utf32lebom.json");
|
||||
TestAutoUTFInputStream("utf32be.json");
|
||||
TestAutoUTFInputStream("utf32bebom.json");
|
||||
}
|
||||
|
||||
TEST_F(EncodedStreamTest, EncodedOutputStream) {
|
||||
TestEncodedOutputStream<UTF8<>, UTF8<> >("utf8.json", false);
|
||||
TestEncodedOutputStream<UTF8<>, UTF8<> >("utf8bom.json", true);
|
||||
TestEncodedOutputStream<UTF16LE<>, UTF16<> >("utf16le.json", false);
|
||||
TestEncodedOutputStream<UTF16LE<>, UTF16<> >("utf16lebom.json",true);
|
||||
TestEncodedOutputStream<UTF16BE<>, UTF16<> >("utf16be.json", false);
|
||||
TestEncodedOutputStream<UTF16BE<>, UTF16<> >("utf16bebom.json",true);
|
||||
TestEncodedOutputStream<UTF32LE<>, UTF32<> >("utf32le.json", false);
|
||||
TestEncodedOutputStream<UTF32LE<>, UTF32<> >("utf32lebom.json",true);
|
||||
TestEncodedOutputStream<UTF32BE<>, UTF32<> >("utf32be.json", false);
|
||||
TestEncodedOutputStream<UTF32BE<>, UTF32<> >("utf32bebom.json",true);
|
||||
}
|
||||
|
||||
TEST_F(EncodedStreamTest, AutoUTFOutputStream) {
|
||||
TestAutoUTFOutputStream(kUTF8, false, "utf8.json");
|
||||
TestAutoUTFOutputStream(kUTF8, true, "utf8bom.json");
|
||||
TestAutoUTFOutputStream(kUTF16LE, false, "utf16le.json");
|
||||
TestAutoUTFOutputStream(kUTF16LE, true, "utf16lebom.json");
|
||||
TestAutoUTFOutputStream(kUTF16BE, false, "utf16be.json");
|
||||
TestAutoUTFOutputStream(kUTF16BE, true, "utf16bebom.json");
|
||||
TestAutoUTFOutputStream(kUTF32LE, false, "utf32le.json");
|
||||
TestAutoUTFOutputStream(kUTF32LE, true, "utf32lebom.json");
|
||||
TestAutoUTFOutputStream(kUTF32BE, false, "utf32be.json");
|
||||
TestAutoUTFOutputStream(kUTF32BE, true, "utf32bebom.json");
|
||||
}
|
||||
432
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/encodingstest.cpp
vendored
Normal file
432
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/encodingstest.cpp
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/encodedstream.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
// Verification of encoders/decoders with Hoehrmann's UTF8 decoder
|
||||
|
||||
// http://www.unicode.org/Public/UNIDATA/Blocks.txt
|
||||
static const unsigned kCodepointRanges[] = {
|
||||
0x0000, 0x007F, // Basic Latin
|
||||
0x0080, 0x00FF, // Latin-1 Supplement
|
||||
0x0100, 0x017F, // Latin Extended-A
|
||||
0x0180, 0x024F, // Latin Extended-B
|
||||
0x0250, 0x02AF, // IPA Extensions
|
||||
0x02B0, 0x02FF, // Spacing Modifier Letters
|
||||
0x0300, 0x036F, // Combining Diacritical Marks
|
||||
0x0370, 0x03FF, // Greek and Coptic
|
||||
0x0400, 0x04FF, // Cyrillic
|
||||
0x0500, 0x052F, // Cyrillic Supplement
|
||||
0x0530, 0x058F, // Armenian
|
||||
0x0590, 0x05FF, // Hebrew
|
||||
0x0600, 0x06FF, // Arabic
|
||||
0x0700, 0x074F, // Syriac
|
||||
0x0750, 0x077F, // Arabic Supplement
|
||||
0x0780, 0x07BF, // Thaana
|
||||
0x07C0, 0x07FF, // NKo
|
||||
0x0800, 0x083F, // Samaritan
|
||||
0x0840, 0x085F, // Mandaic
|
||||
0x0900, 0x097F, // Devanagari
|
||||
0x0980, 0x09FF, // Bengali
|
||||
0x0A00, 0x0A7F, // Gurmukhi
|
||||
0x0A80, 0x0AFF, // Gujarati
|
||||
0x0B00, 0x0B7F, // Oriya
|
||||
0x0B80, 0x0BFF, // Tamil
|
||||
0x0C00, 0x0C7F, // Telugu
|
||||
0x0C80, 0x0CFF, // Kannada
|
||||
0x0D00, 0x0D7F, // Malayalam
|
||||
0x0D80, 0x0DFF, // Sinhala
|
||||
0x0E00, 0x0E7F, // Thai
|
||||
0x0E80, 0x0EFF, // Lao
|
||||
0x0F00, 0x0FFF, // Tibetan
|
||||
0x1000, 0x109F, // Myanmar
|
||||
0x10A0, 0x10FF, // Georgian
|
||||
0x1100, 0x11FF, // Hangul Jamo
|
||||
0x1200, 0x137F, // Ethiopic
|
||||
0x1380, 0x139F, // Ethiopic Supplement
|
||||
0x13A0, 0x13FF, // Cherokee
|
||||
0x1400, 0x167F, // Unified Canadian Aboriginal Syllabics
|
||||
0x1680, 0x169F, // Ogham
|
||||
0x16A0, 0x16FF, // Runic
|
||||
0x1700, 0x171F, // Tagalog
|
||||
0x1720, 0x173F, // Hanunoo
|
||||
0x1740, 0x175F, // Buhid
|
||||
0x1760, 0x177F, // Tagbanwa
|
||||
0x1780, 0x17FF, // Khmer
|
||||
0x1800, 0x18AF, // Mongolian
|
||||
0x18B0, 0x18FF, // Unified Canadian Aboriginal Syllabics Extended
|
||||
0x1900, 0x194F, // Limbu
|
||||
0x1950, 0x197F, // Tai Le
|
||||
0x1980, 0x19DF, // New Tai Lue
|
||||
0x19E0, 0x19FF, // Khmer Symbols
|
||||
0x1A00, 0x1A1F, // Buginese
|
||||
0x1A20, 0x1AAF, // Tai Tham
|
||||
0x1B00, 0x1B7F, // Balinese
|
||||
0x1B80, 0x1BBF, // Sundanese
|
||||
0x1BC0, 0x1BFF, // Batak
|
||||
0x1C00, 0x1C4F, // Lepcha
|
||||
0x1C50, 0x1C7F, // Ol Chiki
|
||||
0x1CD0, 0x1CFF, // Vedic Extensions
|
||||
0x1D00, 0x1D7F, // Phonetic Extensions
|
||||
0x1D80, 0x1DBF, // Phonetic Extensions Supplement
|
||||
0x1DC0, 0x1DFF, // Combining Diacritical Marks Supplement
|
||||
0x1E00, 0x1EFF, // Latin Extended Additional
|
||||
0x1F00, 0x1FFF, // Greek Extended
|
||||
0x2000, 0x206F, // General Punctuation
|
||||
0x2070, 0x209F, // Superscripts and Subscripts
|
||||
0x20A0, 0x20CF, // Currency Symbols
|
||||
0x20D0, 0x20FF, // Combining Diacritical Marks for Symbols
|
||||
0x2100, 0x214F, // Letterlike Symbols
|
||||
0x2150, 0x218F, // Number Forms
|
||||
0x2190, 0x21FF, // Arrows
|
||||
0x2200, 0x22FF, // Mathematical Operators
|
||||
0x2300, 0x23FF, // Miscellaneous Technical
|
||||
0x2400, 0x243F, // Control Pictures
|
||||
0x2440, 0x245F, // Optical Character Recognition
|
||||
0x2460, 0x24FF, // Enclosed Alphanumerics
|
||||
0x2500, 0x257F, // Box Drawing
|
||||
0x2580, 0x259F, // Block Elements
|
||||
0x25A0, 0x25FF, // Geometric Shapes
|
||||
0x2600, 0x26FF, // Miscellaneous Symbols
|
||||
0x2700, 0x27BF, // Dingbats
|
||||
0x27C0, 0x27EF, // Miscellaneous Mathematical Symbols-A
|
||||
0x27F0, 0x27FF, // Supplemental Arrows-A
|
||||
0x2800, 0x28FF, // Braille Patterns
|
||||
0x2900, 0x297F, // Supplemental Arrows-B
|
||||
0x2980, 0x29FF, // Miscellaneous Mathematical Symbols-B
|
||||
0x2A00, 0x2AFF, // Supplemental Mathematical Operators
|
||||
0x2B00, 0x2BFF, // Miscellaneous Symbols and Arrows
|
||||
0x2C00, 0x2C5F, // Glagolitic
|
||||
0x2C60, 0x2C7F, // Latin Extended-C
|
||||
0x2C80, 0x2CFF, // Coptic
|
||||
0x2D00, 0x2D2F, // Georgian Supplement
|
||||
0x2D30, 0x2D7F, // Tifinagh
|
||||
0x2D80, 0x2DDF, // Ethiopic Extended
|
||||
0x2DE0, 0x2DFF, // Cyrillic Extended-A
|
||||
0x2E00, 0x2E7F, // Supplemental Punctuation
|
||||
0x2E80, 0x2EFF, // CJK Radicals Supplement
|
||||
0x2F00, 0x2FDF, // Kangxi Radicals
|
||||
0x2FF0, 0x2FFF, // Ideographic Description Characters
|
||||
0x3000, 0x303F, // CJK Symbols and Punctuation
|
||||
0x3040, 0x309F, // Hiragana
|
||||
0x30A0, 0x30FF, // Katakana
|
||||
0x3100, 0x312F, // Bopomofo
|
||||
0x3130, 0x318F, // Hangul Compatibility Jamo
|
||||
0x3190, 0x319F, // Kanbun
|
||||
0x31A0, 0x31BF, // Bopomofo Extended
|
||||
0x31C0, 0x31EF, // CJK Strokes
|
||||
0x31F0, 0x31FF, // Katakana Phonetic Extensions
|
||||
0x3200, 0x32FF, // Enclosed CJK Letters and Months
|
||||
0x3300, 0x33FF, // CJK Compatibility
|
||||
0x3400, 0x4DBF, // CJK Unified Ideographs Extension A
|
||||
0x4DC0, 0x4DFF, // Yijing Hexagram Symbols
|
||||
0x4E00, 0x9FFF, // CJK Unified Ideographs
|
||||
0xA000, 0xA48F, // Yi Syllables
|
||||
0xA490, 0xA4CF, // Yi Radicals
|
||||
0xA4D0, 0xA4FF, // Lisu
|
||||
0xA500, 0xA63F, // Vai
|
||||
0xA640, 0xA69F, // Cyrillic Extended-B
|
||||
0xA6A0, 0xA6FF, // Bamum
|
||||
0xA700, 0xA71F, // Modifier Tone Letters
|
||||
0xA720, 0xA7FF, // Latin Extended-D
|
||||
0xA800, 0xA82F, // Syloti Nagri
|
||||
0xA830, 0xA83F, // Common Indic Number Forms
|
||||
0xA840, 0xA87F, // Phags-pa
|
||||
0xA880, 0xA8DF, // Saurashtra
|
||||
0xA8E0, 0xA8FF, // Devanagari Extended
|
||||
0xA900, 0xA92F, // Kayah Li
|
||||
0xA930, 0xA95F, // Rejang
|
||||
0xA960, 0xA97F, // Hangul Jamo Extended-A
|
||||
0xA980, 0xA9DF, // Javanese
|
||||
0xAA00, 0xAA5F, // Cham
|
||||
0xAA60, 0xAA7F, // Myanmar Extended-A
|
||||
0xAA80, 0xAADF, // Tai Viet
|
||||
0xAB00, 0xAB2F, // Ethiopic Extended-A
|
||||
0xABC0, 0xABFF, // Meetei Mayek
|
||||
0xAC00, 0xD7AF, // Hangul Syllables
|
||||
0xD7B0, 0xD7FF, // Hangul Jamo Extended-B
|
||||
//0xD800, 0xDB7F, // High Surrogates
|
||||
//0xDB80, 0xDBFF, // High Private Use Surrogates
|
||||
//0xDC00, 0xDFFF, // Low Surrogates
|
||||
0xE000, 0xF8FF, // Private Use Area
|
||||
0xF900, 0xFAFF, // CJK Compatibility Ideographs
|
||||
0xFB00, 0xFB4F, // Alphabetic Presentation Forms
|
||||
0xFB50, 0xFDFF, // Arabic Presentation Forms-A
|
||||
0xFE00, 0xFE0F, // Variation Selectors
|
||||
0xFE10, 0xFE1F, // Vertical Forms
|
||||
0xFE20, 0xFE2F, // Combining Half Marks
|
||||
0xFE30, 0xFE4F, // CJK Compatibility Forms
|
||||
0xFE50, 0xFE6F, // Small Form Variants
|
||||
0xFE70, 0xFEFF, // Arabic Presentation Forms-B
|
||||
0xFF00, 0xFFEF, // Halfwidth and Fullwidth Forms
|
||||
0xFFF0, 0xFFFF, // Specials
|
||||
0x10000, 0x1007F, // Linear B Syllabary
|
||||
0x10080, 0x100FF, // Linear B Ideograms
|
||||
0x10100, 0x1013F, // Aegean Numbers
|
||||
0x10140, 0x1018F, // Ancient Greek Numbers
|
||||
0x10190, 0x101CF, // Ancient Symbols
|
||||
0x101D0, 0x101FF, // Phaistos Disc
|
||||
0x10280, 0x1029F, // Lycian
|
||||
0x102A0, 0x102DF, // Carian
|
||||
0x10300, 0x1032F, // Old Italic
|
||||
0x10330, 0x1034F, // Gothic
|
||||
0x10380, 0x1039F, // Ugaritic
|
||||
0x103A0, 0x103DF, // Old Persian
|
||||
0x10400, 0x1044F, // Deseret
|
||||
0x10450, 0x1047F, // Shavian
|
||||
0x10480, 0x104AF, // Osmanya
|
||||
0x10800, 0x1083F, // Cypriot Syllabary
|
||||
0x10840, 0x1085F, // Imperial Aramaic
|
||||
0x10900, 0x1091F, // Phoenician
|
||||
0x10920, 0x1093F, // Lydian
|
||||
0x10A00, 0x10A5F, // Kharoshthi
|
||||
0x10A60, 0x10A7F, // Old South Arabian
|
||||
0x10B00, 0x10B3F, // Avestan
|
||||
0x10B40, 0x10B5F, // Inscriptional Parthian
|
||||
0x10B60, 0x10B7F, // Inscriptional Pahlavi
|
||||
0x10C00, 0x10C4F, // Old Turkic
|
||||
0x10E60, 0x10E7F, // Rumi Numeral Symbols
|
||||
0x11000, 0x1107F, // Brahmi
|
||||
0x11080, 0x110CF, // Kaithi
|
||||
0x12000, 0x123FF, // Cuneiform
|
||||
0x12400, 0x1247F, // Cuneiform Numbers and Punctuation
|
||||
0x13000, 0x1342F, // Egyptian Hieroglyphs
|
||||
0x16800, 0x16A3F, // Bamum Supplement
|
||||
0x1B000, 0x1B0FF, // Kana Supplement
|
||||
0x1D000, 0x1D0FF, // Byzantine Musical Symbols
|
||||
0x1D100, 0x1D1FF, // Musical Symbols
|
||||
0x1D200, 0x1D24F, // Ancient Greek Musical Notation
|
||||
0x1D300, 0x1D35F, // Tai Xuan Jing Symbols
|
||||
0x1D360, 0x1D37F, // Counting Rod Numerals
|
||||
0x1D400, 0x1D7FF, // Mathematical Alphanumeric Symbols
|
||||
0x1F000, 0x1F02F, // Mahjong Tiles
|
||||
0x1F030, 0x1F09F, // Domino Tiles
|
||||
0x1F0A0, 0x1F0FF, // Playing Cards
|
||||
0x1F100, 0x1F1FF, // Enclosed Alphanumeric Supplement
|
||||
0x1F200, 0x1F2FF, // Enclosed Ideographic Supplement
|
||||
0x1F300, 0x1F5FF, // Miscellaneous Symbols And Pictographs
|
||||
0x1F600, 0x1F64F, // Emoticons
|
||||
0x1F680, 0x1F6FF, // Transport And Map Symbols
|
||||
0x1F700, 0x1F77F, // Alchemical Symbols
|
||||
0x20000, 0x2A6DF, // CJK Unified Ideographs Extension B
|
||||
0x2A700, 0x2B73F, // CJK Unified Ideographs Extension C
|
||||
0x2B740, 0x2B81F, // CJK Unified Ideographs Extension D
|
||||
0x2F800, 0x2FA1F, // CJK Compatibility Ideographs Supplement
|
||||
0xE0000, 0xE007F, // Tags
|
||||
0xE0100, 0xE01EF, // Variation Selectors Supplement
|
||||
0xF0000, 0xFFFFF, // Supplementary Private Use Area-A
|
||||
0x100000, 0x10FFFF, // Supplementary Private Use Area-B
|
||||
0xFFFFFFFF
|
||||
};
|
||||
|
||||
// Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
#define UTF8_ACCEPT 0u
|
||||
#define UTF8_REJECT 12u
|
||||
|
||||
static const unsigned char utf8d[] = {
|
||||
// The first part of the table maps bytes to character classes that
|
||||
// to reduce the size of the transition table and create bitmasks.
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||
|
||||
// The second part is a transition table that maps a combination
|
||||
// of a state of the automaton and a character class to a state.
|
||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
||||
};
|
||||
|
||||
static unsigned inline decode(unsigned* state, unsigned* codep, unsigned byte) {
|
||||
unsigned type = utf8d[byte];
|
||||
|
||||
*codep = (*state != UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
//static bool IsUTF8(unsigned char* s) {
|
||||
// unsigned codepoint, state = 0;
|
||||
//
|
||||
// while (*s)
|
||||
// decode(&state, &codepoint, *s++);
|
||||
//
|
||||
// return state == UTF8_ACCEPT;
|
||||
//}
|
||||
|
||||
TEST(EncodingsTest, UTF8) {
|
||||
StringBuffer os, os2;
|
||||
for (const unsigned* range = kCodepointRanges; *range != 0xFFFFFFFF; range += 2) {
|
||||
for (unsigned codepoint = range[0]; codepoint <= range[1]; ++codepoint) {
|
||||
os.Clear();
|
||||
UTF8<>::Encode(os, codepoint);
|
||||
const char* encodedStr = os.GetString();
|
||||
|
||||
// Decode with Hoehrmann
|
||||
{
|
||||
unsigned decodedCodepoint = 0;
|
||||
unsigned state = 0;
|
||||
|
||||
unsigned decodedCount = 0;
|
||||
for (const char* s = encodedStr; *s; ++s)
|
||||
if (!decode(&state, &decodedCodepoint, (unsigned char)*s)) {
|
||||
EXPECT_EQ(codepoint, decodedCodepoint);
|
||||
decodedCount++;
|
||||
}
|
||||
|
||||
if (*encodedStr) // This decoder cannot handle U+0000
|
||||
EXPECT_EQ(1u, decodedCount); // Should only contain one code point
|
||||
|
||||
EXPECT_EQ(UTF8_ACCEPT, state);
|
||||
if (UTF8_ACCEPT != state)
|
||||
std::cout << std::hex << codepoint << " " << decodedCodepoint << std::endl;
|
||||
}
|
||||
|
||||
// Decode
|
||||
{
|
||||
StringStream is(encodedStr);
|
||||
unsigned decodedCodepoint;
|
||||
bool result = UTF8<>::Decode(is, &decodedCodepoint);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(codepoint, decodedCodepoint);
|
||||
if (!result || codepoint != decodedCodepoint)
|
||||
std::cout << std::hex << codepoint << " " << decodedCodepoint << std::endl;
|
||||
}
|
||||
|
||||
// Validate
|
||||
{
|
||||
StringStream is(encodedStr);
|
||||
os2.Clear();
|
||||
bool result = UTF8<>::Validate(is, os2);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(0, StrCmp(encodedStr, os2.GetString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingsTest, UTF16) {
|
||||
GenericStringBuffer<UTF16<> > os, os2;
|
||||
GenericStringBuffer<UTF8<> > utf8os;
|
||||
for (const unsigned* range = kCodepointRanges; *range != 0xFFFFFFFF; range += 2) {
|
||||
for (unsigned codepoint = range[0]; codepoint <= range[1]; ++codepoint) {
|
||||
os.Clear();
|
||||
UTF16<>::Encode(os, codepoint);
|
||||
const UTF16<>::Ch* encodedStr = os.GetString();
|
||||
|
||||
// Encode with Hoehrmann's code
|
||||
if (codepoint != 0) // cannot handle U+0000
|
||||
{
|
||||
// encode with UTF8<> first
|
||||
utf8os.Clear();
|
||||
UTF8<>::Encode(utf8os, codepoint);
|
||||
|
||||
// transcode from UTF8 to UTF16 with Hoehrmann's code
|
||||
unsigned decodedCodepoint = 0;
|
||||
unsigned state = 0;
|
||||
UTF16<>::Ch buffer[3], *p = &buffer[0];
|
||||
for (const char* s = utf8os.GetString(); *s; ++s) {
|
||||
if (!decode(&state, &decodedCodepoint, (unsigned char)*s))
|
||||
break;
|
||||
}
|
||||
|
||||
if (codepoint <= 0xFFFF)
|
||||
*p++ = static_cast<UTF16<>::Ch>(decodedCodepoint);
|
||||
else {
|
||||
// Encode code points above U+FFFF as surrogate pair.
|
||||
*p++ = static_cast<UTF16<>::Ch>(0xD7C0 + (decodedCodepoint >> 10));
|
||||
*p++ = static_cast<UTF16<>::Ch>(0xDC00 + (decodedCodepoint & 0x3FF));
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
EXPECT_EQ(0, StrCmp(buffer, encodedStr));
|
||||
}
|
||||
|
||||
// Decode
|
||||
{
|
||||
GenericStringStream<UTF16<> > is(encodedStr);
|
||||
unsigned decodedCodepoint;
|
||||
bool result = UTF16<>::Decode(is, &decodedCodepoint);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(codepoint, decodedCodepoint);
|
||||
if (!result || codepoint != decodedCodepoint)
|
||||
std::cout << std::hex << codepoint << " " << decodedCodepoint << std::endl;
|
||||
}
|
||||
|
||||
// Validate
|
||||
{
|
||||
GenericStringStream<UTF16<> > is(encodedStr);
|
||||
os2.Clear();
|
||||
bool result = UTF16<>::Validate(is, os2);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(0, StrCmp(encodedStr, os2.GetString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingsTest, UTF32) {
|
||||
GenericStringBuffer<UTF32<> > os, os2;
|
||||
for (const unsigned* range = kCodepointRanges; *range != 0xFFFFFFFF; range += 2) {
|
||||
for (unsigned codepoint = range[0]; codepoint <= range[1]; ++codepoint) {
|
||||
os.Clear();
|
||||
UTF32<>::Encode(os, codepoint);
|
||||
const UTF32<>::Ch* encodedStr = os.GetString();
|
||||
|
||||
// Decode
|
||||
{
|
||||
GenericStringStream<UTF32<> > is(encodedStr);
|
||||
unsigned decodedCodepoint;
|
||||
bool result = UTF32<>::Decode(is, &decodedCodepoint);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(codepoint, decodedCodepoint);
|
||||
if (!result || codepoint != decodedCodepoint)
|
||||
std::cout << std::hex << codepoint << " " << decodedCodepoint << std::endl;
|
||||
}
|
||||
|
||||
// Validate
|
||||
{
|
||||
GenericStringStream<UTF32<> > is(encodedStr);
|
||||
os2.Clear();
|
||||
bool result = UTF32<>::Validate(is, os2);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(0, StrCmp(encodedStr, os2.GetString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/filestreamtest.cpp
vendored
Normal file
122
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/filestreamtest.cpp
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/filestream.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/encodedstream.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
class FileStreamTest : public ::testing::Test {
|
||||
public:
|
||||
FileStreamTest() : filename_(), json_(), length_() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
FILE *fp = fopen(filename_ = "data/sample.json", "rb");
|
||||
if (!fp)
|
||||
fp = fopen(filename_ = "../../bin/data/sample.json", "rb");
|
||||
ASSERT_TRUE(fp != 0);
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length_ = (size_t)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
json_ = (char*)malloc(length_ + 1);
|
||||
size_t readLength = fread(json_, 1, length_, fp);
|
||||
json_[readLength] = '\0';
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
free(json_);
|
||||
json_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
FileStreamTest(const FileStreamTest&);
|
||||
FileStreamTest& operator=(const FileStreamTest&);
|
||||
|
||||
protected:
|
||||
const char* filename_;
|
||||
char *json_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
// Deprecated
|
||||
//TEST_F(FileStreamTest, FileStream_Read) {
|
||||
// FILE *fp = fopen(filename_, "rb");
|
||||
// ASSERT_TRUE(fp != 0);
|
||||
// FileStream s(fp);
|
||||
//
|
||||
// for (size_t i = 0; i < length_; i++) {
|
||||
// EXPECT_EQ(json_[i], s.Peek());
|
||||
// EXPECT_EQ(json_[i], s.Peek()); // 2nd time should be the same
|
||||
// EXPECT_EQ(json_[i], s.Take());
|
||||
// }
|
||||
//
|
||||
// EXPECT_EQ(length_, s.Tell());
|
||||
// EXPECT_EQ('\0', s.Peek());
|
||||
//
|
||||
// fclose(fp);
|
||||
//}
|
||||
|
||||
TEST_F(FileStreamTest, FileReadStream) {
|
||||
FILE *fp = fopen(filename_, "rb");
|
||||
ASSERT_TRUE(fp != 0);
|
||||
char buffer[65536];
|
||||
FileReadStream s(fp, buffer, sizeof(buffer));
|
||||
|
||||
for (size_t i = 0; i < length_; i++) {
|
||||
EXPECT_EQ(json_[i], s.Peek());
|
||||
EXPECT_EQ(json_[i], s.Peek()); // 2nd time should be the same
|
||||
EXPECT_EQ(json_[i], s.Take());
|
||||
}
|
||||
|
||||
EXPECT_EQ(length_, s.Tell());
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
TEST_F(FileStreamTest, FileWriteStream) {
|
||||
char filename[L_tmpnam];
|
||||
FILE* fp = TempFile(filename);
|
||||
|
||||
char buffer[65536];
|
||||
FileWriteStream os(fp, buffer, sizeof(buffer));
|
||||
for (size_t i = 0; i < length_; i++)
|
||||
os.Put(json_[i]);
|
||||
os.Flush();
|
||||
fclose(fp);
|
||||
|
||||
// Read it back to verify
|
||||
fp = fopen(filename, "rb");
|
||||
FileReadStream is(fp, buffer, sizeof(buffer));
|
||||
|
||||
for (size_t i = 0; i < length_; i++)
|
||||
EXPECT_EQ(json_[i], is.Take());
|
||||
|
||||
EXPECT_EQ(length_, is.Tell());
|
||||
fclose(fp);
|
||||
|
||||
//std::cout << filename << std::endl;
|
||||
remove(filename);
|
||||
}
|
||||
100
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/jsoncheckertest.cpp
vendored
Normal file
100
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/jsoncheckertest.cpp
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
static char* ReadFile(const char* filename, size_t& length) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length = (size_t)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* json = (char*)malloc(length + 1);
|
||||
size_t readLength = fread(json, 1, length, fp);
|
||||
json[readLength] = '\0';
|
||||
fclose(fp);
|
||||
return json;
|
||||
}
|
||||
|
||||
TEST(JsonChecker, Reader) {
|
||||
char filename[256];
|
||||
|
||||
// jsonchecker/failXX.json
|
||||
for (int i = 1; i <= 33; i++) {
|
||||
if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159).
|
||||
continue;
|
||||
if (i == 18) // fail18.json is valid in rapidjson, which has no limitation on depth of nesting.
|
||||
continue;
|
||||
|
||||
sprintf(filename, "jsonchecker/fail%d.json", i);
|
||||
size_t length;
|
||||
char* json = ReadFile(filename, length);
|
||||
if (!json) {
|
||||
sprintf(filename, "../../bin/jsonchecker/fail%d.json", i);
|
||||
json = ReadFile(filename, length);
|
||||
if (!json) {
|
||||
printf("jsonchecker file %s not found", filename);
|
||||
ADD_FAILURE();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
document.Parse((const char*)json);
|
||||
EXPECT_TRUE(document.HasParseError());
|
||||
|
||||
document.Parse<kParseIterativeFlag>((const char*)json);
|
||||
EXPECT_TRUE(document.HasParseError());
|
||||
|
||||
free(json);
|
||||
}
|
||||
|
||||
// passX.json
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
sprintf(filename, "jsonchecker/pass%d.json", i);
|
||||
size_t length;
|
||||
char* json = ReadFile(filename, length);
|
||||
if (!json) {
|
||||
sprintf(filename, "../../bin/jsonchecker/pass%d.json", i);
|
||||
json = ReadFile(filename, length);
|
||||
if (!json) {
|
||||
printf("jsonchecker file %s not found", filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
document.Parse((const char*)json);
|
||||
EXPECT_FALSE(document.HasParseError());
|
||||
|
||||
document.Parse<kParseIterativeFlag>((const char*)json);
|
||||
EXPECT_FALSE(document.HasParseError());
|
||||
|
||||
free(json);
|
||||
}
|
||||
}
|
||||
76
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/namespacetest.cpp
vendored
Normal file
76
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/namespacetest.cpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
// test another instantiation of RapidJSON in a different namespace
|
||||
|
||||
#define RAPIDJSON_NAMESPACE my::rapid::json
|
||||
#define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapid { namespace json {
|
||||
#define RAPIDJSON_NAMESPACE_END } } }
|
||||
|
||||
// include lots of RapidJSON files
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/filereadstream.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/encodedstream.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
static const char json[] = "{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3,4]}";
|
||||
|
||||
TEST(NamespaceTest,Using) {
|
||||
using namespace RAPIDJSON_NAMESPACE;
|
||||
typedef GenericDocument<UTF8<>, CrtAllocator> DocumentType;
|
||||
DocumentType doc;
|
||||
|
||||
doc.Parse(json);
|
||||
EXPECT_TRUE(!doc.HasParseError());
|
||||
}
|
||||
|
||||
TEST(NamespaceTest,Direct) {
|
||||
typedef RAPIDJSON_NAMESPACE::Document Document;
|
||||
typedef RAPIDJSON_NAMESPACE::Reader Reader;
|
||||
typedef RAPIDJSON_NAMESPACE::StringStream StringStream;
|
||||
typedef RAPIDJSON_NAMESPACE::StringBuffer StringBuffer;
|
||||
typedef RAPIDJSON_NAMESPACE::Writer<StringBuffer> WriterType;
|
||||
|
||||
StringStream s(json);
|
||||
StringBuffer buffer;
|
||||
WriterType writer(buffer);
|
||||
buffer.ShrinkToFit();
|
||||
Reader reader;
|
||||
reader.Parse(s, writer);
|
||||
|
||||
EXPECT_STREQ(json, buffer.GetString());
|
||||
EXPECT_EQ(sizeof(json)-1, buffer.GetSize());
|
||||
EXPECT_TRUE(writer.IsComplete());
|
||||
|
||||
Document doc;
|
||||
doc.Parse(buffer.GetString());
|
||||
EXPECT_TRUE(!doc.HasParseError());
|
||||
|
||||
buffer.Clear();
|
||||
writer.Reset(buffer);
|
||||
doc.Accept(writer);
|
||||
EXPECT_STREQ(json, buffer.GetString());
|
||||
EXPECT_TRUE(writer.IsComplete());
|
||||
}
|
||||
1173
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/readertest.cpp
vendored
Normal file
1173
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/readertest.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
152
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/stringbuffertest.cpp
vendored
Normal file
152
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/stringbuffertest.cpp
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
TEST(StringBuffer, InitialSize) {
|
||||
StringBuffer buffer;
|
||||
EXPECT_EQ(0u, buffer.GetSize());
|
||||
EXPECT_STREQ("", buffer.GetString());
|
||||
}
|
||||
|
||||
TEST(StringBuffer, Put) {
|
||||
StringBuffer buffer;
|
||||
buffer.Put('A');
|
||||
|
||||
EXPECT_EQ(1u, buffer.GetSize());
|
||||
EXPECT_STREQ("A", buffer.GetString());
|
||||
}
|
||||
|
||||
TEST(StringBuffer, Clear) {
|
||||
StringBuffer buffer;
|
||||
buffer.Put('A');
|
||||
buffer.Put('B');
|
||||
buffer.Put('C');
|
||||
buffer.Clear();
|
||||
|
||||
EXPECT_EQ(0u, buffer.GetSize());
|
||||
EXPECT_STREQ("", buffer.GetString());
|
||||
}
|
||||
|
||||
TEST(StringBuffer, Push) {
|
||||
StringBuffer buffer;
|
||||
buffer.Push(5);
|
||||
|
||||
EXPECT_EQ(5u, buffer.GetSize());
|
||||
}
|
||||
|
||||
TEST(StringBuffer, Pop) {
|
||||
StringBuffer buffer;
|
||||
buffer.Put('A');
|
||||
buffer.Put('B');
|
||||
buffer.Put('C');
|
||||
buffer.Put('D');
|
||||
buffer.Put('E');
|
||||
buffer.Pop(3);
|
||||
|
||||
EXPECT_EQ(2u, buffer.GetSize());
|
||||
EXPECT_STREQ("AB", buffer.GetString());
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
TEST(StringBuffer, Traits) {
|
||||
static_assert( std::is_constructible<StringBuffer>::value, "");
|
||||
static_assert( std::is_default_constructible<StringBuffer>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_copy_constructible<StringBuffer>::value, "");
|
||||
#endif
|
||||
static_assert( std::is_move_constructible<StringBuffer>::value, "");
|
||||
|
||||
static_assert(!std::is_nothrow_constructible<StringBuffer>::value, "");
|
||||
static_assert(!std::is_nothrow_default_constructible<StringBuffer>::value, "");
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1800
|
||||
static_assert(!std::is_nothrow_copy_constructible<StringBuffer>::value, "");
|
||||
static_assert(!std::is_nothrow_move_constructible<StringBuffer>::value, "");
|
||||
#endif
|
||||
|
||||
static_assert( std::is_assignable<StringBuffer,StringBuffer>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_copy_assignable<StringBuffer>::value, "");
|
||||
#endif
|
||||
static_assert( std::is_move_assignable<StringBuffer>::value, "");
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1800
|
||||
static_assert(!std::is_nothrow_assignable<StringBuffer, StringBuffer>::value, "");
|
||||
#endif
|
||||
|
||||
static_assert(!std::is_nothrow_copy_assignable<StringBuffer>::value, "");
|
||||
static_assert(!std::is_nothrow_move_assignable<StringBuffer>::value, "");
|
||||
|
||||
static_assert( std::is_destructible<StringBuffer>::value, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(std::is_nothrow_destructible<StringBuffer>::value, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(StringBuffer, MoveConstructor) {
|
||||
StringBuffer x;
|
||||
x.Put('A');
|
||||
x.Put('B');
|
||||
x.Put('C');
|
||||
x.Put('D');
|
||||
|
||||
EXPECT_EQ(4u, x.GetSize());
|
||||
EXPECT_STREQ("ABCD", x.GetString());
|
||||
|
||||
// StringBuffer y(x); // does not compile (!is_copy_constructible)
|
||||
StringBuffer y(std::move(x));
|
||||
EXPECT_EQ(0u, x.GetSize());
|
||||
EXPECT_EQ(4u, y.GetSize());
|
||||
EXPECT_STREQ("ABCD", y.GetString());
|
||||
|
||||
// StringBuffer z = y; // does not compile (!is_copy_assignable)
|
||||
StringBuffer z = std::move(y);
|
||||
EXPECT_EQ(0u, y.GetSize());
|
||||
EXPECT_EQ(4u, z.GetSize());
|
||||
EXPECT_STREQ("ABCD", z.GetString());
|
||||
}
|
||||
|
||||
TEST(StringBuffer, MoveAssignment) {
|
||||
StringBuffer x;
|
||||
x.Put('A');
|
||||
x.Put('B');
|
||||
x.Put('C');
|
||||
x.Put('D');
|
||||
|
||||
EXPECT_EQ(4u, x.GetSize());
|
||||
EXPECT_STREQ("ABCD", x.GetString());
|
||||
|
||||
StringBuffer y;
|
||||
// y = x; // does not compile (!is_copy_assignable)
|
||||
y = std::move(x);
|
||||
EXPECT_EQ(0u, x.GetSize());
|
||||
EXPECT_EQ(4u, y.GetSize());
|
||||
EXPECT_STREQ("ABCD", y.GetString());
|
||||
}
|
||||
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
129
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/strtodtest.cpp
vendored
Normal file
129
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/strtodtest.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
#include "rapidjson/internal/strtod.h"
|
||||
|
||||
#define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
|
||||
|
||||
using namespace rapidjson::internal;
|
||||
|
||||
TEST(Strtod, CheckApproximationCase) {
|
||||
static const int kSignificandSize = 52;
|
||||
static const int kExponentBias = 0x3FF;
|
||||
static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
|
||||
static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
|
||||
static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
|
||||
|
||||
// http://www.exploringbinary.com/using-integers-to-check-a-floating-point-approximation/
|
||||
// Let b = 0x1.465a72e467d88p-149
|
||||
// = 5741268244528520 x 2^-201
|
||||
union {
|
||||
double d;
|
||||
uint64_t u;
|
||||
}u;
|
||||
u.u = 0x465a72e467d88 | ((static_cast<uint64_t>(-149 + kExponentBias)) << kSignificandSize);
|
||||
const double b = u.d;
|
||||
const uint64_t bInt = (u.u & kSignificandMask) | kHiddenBit;
|
||||
const int bExp = ((u.u & kExponentMask) >> kSignificandSize) - kExponentBias - kSignificandSize;
|
||||
EXPECT_DOUBLE_EQ(1.7864e-45, b);
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x001465a7, 0x2e467d88), bInt);
|
||||
EXPECT_EQ(-201, bExp);
|
||||
|
||||
// Let d = 17864 x 10-49
|
||||
const char dInt[] = "17864";
|
||||
const int dExp = -49;
|
||||
|
||||
// Let h = 2^(bExp-1)
|
||||
const int hExp = bExp - 1;
|
||||
EXPECT_EQ(-202, hExp);
|
||||
|
||||
int dS_Exp2 = 0;
|
||||
int dS_Exp5 = 0;
|
||||
int bS_Exp2 = 0;
|
||||
int bS_Exp5 = 0;
|
||||
int hS_Exp2 = 0;
|
||||
int hS_Exp5 = 0;
|
||||
|
||||
// Adjust for decimal exponent
|
||||
if (dExp >= 0) {
|
||||
dS_Exp2 += dExp;
|
||||
dS_Exp5 += dExp;
|
||||
}
|
||||
else {
|
||||
bS_Exp2 -= dExp;
|
||||
bS_Exp5 -= dExp;
|
||||
hS_Exp2 -= dExp;
|
||||
hS_Exp5 -= dExp;
|
||||
}
|
||||
|
||||
// Adjust for binary exponent
|
||||
if (bExp >= 0)
|
||||
bS_Exp2 += bExp;
|
||||
else {
|
||||
dS_Exp2 -= bExp;
|
||||
hS_Exp2 -= bExp;
|
||||
}
|
||||
|
||||
// Adjust for half ulp exponent
|
||||
if (hExp >= 0)
|
||||
hS_Exp2 += hExp;
|
||||
else {
|
||||
dS_Exp2 -= hExp;
|
||||
bS_Exp2 -= hExp;
|
||||
}
|
||||
|
||||
// Remove common power of two factor from all three scaled values
|
||||
int common_Exp2 = std::min(dS_Exp2, std::min(bS_Exp2, hS_Exp2));
|
||||
dS_Exp2 -= common_Exp2;
|
||||
bS_Exp2 -= common_Exp2;
|
||||
hS_Exp2 -= common_Exp2;
|
||||
|
||||
EXPECT_EQ(153, dS_Exp2);
|
||||
EXPECT_EQ(0, dS_Exp5);
|
||||
EXPECT_EQ(1, bS_Exp2);
|
||||
EXPECT_EQ(49, bS_Exp5);
|
||||
EXPECT_EQ(0, hS_Exp2);
|
||||
EXPECT_EQ(49, hS_Exp5);
|
||||
|
||||
BigInteger dS = BIGINTEGER_LITERAL(dInt);
|
||||
dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2;
|
||||
|
||||
BigInteger bS(bInt);
|
||||
bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2;
|
||||
|
||||
BigInteger hS(1);
|
||||
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
|
||||
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994138521801764465966248930731085529088") == dS);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994122305215569213032722473144531250000") == bS);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("17763568394002504646778106689453125") == hS);
|
||||
|
||||
EXPECT_EQ(1, dS.Compare(bS));
|
||||
|
||||
BigInteger delta(0);
|
||||
EXPECT_FALSE(dS.Difference(bS, &delta));
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("16216586195252933526457586554279088") == delta);
|
||||
EXPECT_TRUE(bS.Difference(dS, &delta));
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("16216586195252933526457586554279088") == delta);
|
||||
|
||||
EXPECT_EQ(-1, delta.Compare(hS));
|
||||
}
|
||||
40
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/unittest.cpp
vendored
Normal file
40
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/unittest.cpp
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
#if _MSC_VER
|
||||
_CrtMemState memoryState = { 0 };
|
||||
_CrtMemCheckpoint(&memoryState);
|
||||
//_CrtSetBreakAlloc(X);
|
||||
//void *testWhetherMemoryLeakDetectionWorks = malloc(1);
|
||||
#endif
|
||||
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
#if _MSC_VER
|
||||
// Current gtest constantly leak 2 blocks at exit
|
||||
_CrtMemDumpAllObjectsSince(&memoryState);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
113
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/unittest.h
vendored
Normal file
113
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/unittest.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef UNITTEST_H_
|
||||
#define UNITTEST_H_
|
||||
|
||||
|
||||
// gtest indirectly included inttypes.h, without __STDC_CONSTANT_MACROS.
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
#pragma warning(disable : 4996) // 'function': was declared deprecated
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
#if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#endif
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template <typename Ch>
|
||||
inline unsigned StrLen(const Ch* s) {
|
||||
const Ch* p = s;
|
||||
while (*p) p++;
|
||||
return unsigned(p - s);
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
inline int StrCmp(const Ch* s1, const Ch* s2) {
|
||||
while(*s1 && (*s1 == *s2)) { s1++; s2++; }
|
||||
return (unsigned)*s1 < (unsigned)*s2 ? -1 : (unsigned)*s1 > (unsigned)*s2;
|
||||
}
|
||||
|
||||
template <typename Ch>
|
||||
inline Ch* StrDup(const Ch* str) {
|
||||
size_t bufferSize = sizeof(Ch) * (StrLen(str) + 1);
|
||||
Ch* buffer = (Ch*)malloc(bufferSize);
|
||||
memcpy(buffer, str, bufferSize);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline FILE* TempFile(char *filename) {
|
||||
#if _MSC_VER
|
||||
filename = tmpnam(filename);
|
||||
|
||||
// For Visual Studio, tmpnam() adds a backslash in front. Remove it.
|
||||
if (filename[0] == '\\')
|
||||
for (int i = 0; filename[i] != '\0'; i++)
|
||||
filename[i] = filename[i + 1];
|
||||
|
||||
return fopen(filename, "wb");
|
||||
#else
|
||||
strcpy(filename, "/tmp/fileXXXXXX");
|
||||
int fd = mkstemp(filename);
|
||||
return fdopen(fd, "w");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use exception for catching assert
|
||||
#if _MSC_VER
|
||||
#pragma warning(disable : 4127)
|
||||
#endif
|
||||
|
||||
class AssertException : public std::logic_error {
|
||||
public:
|
||||
AssertException(const char* w) : std::logic_error(w) {}
|
||||
};
|
||||
|
||||
#define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x))
|
||||
|
||||
class Random {
|
||||
public:
|
||||
Random(unsigned seed = 0) : mSeed(seed) {}
|
||||
|
||||
unsigned operator()() {
|
||||
mSeed = 214013 * mSeed + 2531011;
|
||||
return mSeed;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned mSeed;
|
||||
};
|
||||
|
||||
#endif // UNITTEST_H_
|
||||
1239
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/valuetest.cpp
vendored
Normal file
1239
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/valuetest.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
308
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/writertest.cpp
vendored
Normal file
308
third_party/socket.io-client-cpp/lib/rapidjson/test/unittest/writertest.cpp
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/reader.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
TEST(Writer, Compact) {
|
||||
StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ");
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
buffer.ShrinkToFit();
|
||||
Reader reader;
|
||||
reader.Parse<0>(s, writer);
|
||||
EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3]}", buffer.GetString());
|
||||
EXPECT_EQ(77u, buffer.GetSize());
|
||||
EXPECT_TRUE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// json -> parse -> writer -> json
|
||||
#define TEST_ROUNDTRIP(json) \
|
||||
{ \
|
||||
StringStream s(json); \
|
||||
StringBuffer buffer; \
|
||||
Writer<StringBuffer> writer(buffer); \
|
||||
Reader reader; \
|
||||
reader.Parse<0>(s, writer); \
|
||||
EXPECT_STREQ(json, buffer.GetString()); \
|
||||
EXPECT_TRUE(writer.IsComplete()); \
|
||||
}
|
||||
|
||||
TEST(Writer, Root) {
|
||||
TEST_ROUNDTRIP("null");
|
||||
TEST_ROUNDTRIP("true");
|
||||
TEST_ROUNDTRIP("false");
|
||||
TEST_ROUNDTRIP("0");
|
||||
TEST_ROUNDTRIP("\"foo\"");
|
||||
TEST_ROUNDTRIP("[]");
|
||||
TEST_ROUNDTRIP("{}");
|
||||
}
|
||||
|
||||
TEST(Writer, Int) {
|
||||
TEST_ROUNDTRIP("[-1]");
|
||||
TEST_ROUNDTRIP("[-123]");
|
||||
TEST_ROUNDTRIP("[-2147483648]");
|
||||
}
|
||||
|
||||
TEST(Writer, UInt) {
|
||||
TEST_ROUNDTRIP("[0]");
|
||||
TEST_ROUNDTRIP("[1]");
|
||||
TEST_ROUNDTRIP("[123]");
|
||||
TEST_ROUNDTRIP("[2147483647]");
|
||||
TEST_ROUNDTRIP("[4294967295]");
|
||||
}
|
||||
|
||||
TEST(Writer, Int64) {
|
||||
TEST_ROUNDTRIP("[-1234567890123456789]");
|
||||
TEST_ROUNDTRIP("[-9223372036854775808]");
|
||||
}
|
||||
|
||||
TEST(Writer, Uint64) {
|
||||
TEST_ROUNDTRIP("[1234567890123456789]");
|
||||
TEST_ROUNDTRIP("[9223372036854775807]");
|
||||
}
|
||||
|
||||
TEST(Writer, String) {
|
||||
TEST_ROUNDTRIP("[\"Hello\"]");
|
||||
TEST_ROUNDTRIP("[\"Hello\\u0000World\"]");
|
||||
TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]");
|
||||
}
|
||||
|
||||
TEST(Writer, Double) {
|
||||
TEST_ROUNDTRIP("[1.2345,1.2345678,0.123456789012,1234567.8]");
|
||||
|
||||
}
|
||||
|
||||
TEST(Writer, Transcode) {
|
||||
const char json[] = "{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3],\"dollar\":\"\x24\",\"cents\":\"\xC2\xA2\",\"euro\":\"\xE2\x82\xAC\",\"gclef\":\"\xF0\x9D\x84\x9E\"}";
|
||||
|
||||
// UTF8 -> UTF16 -> UTF8
|
||||
{
|
||||
StringStream s(json);
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer, UTF16<>, UTF8<> > writer(buffer);
|
||||
GenericReader<UTF8<>, UTF16<> > reader;
|
||||
reader.Parse(s, writer);
|
||||
EXPECT_STREQ(json, buffer.GetString());
|
||||
}
|
||||
|
||||
// UTF8 -> UTF8 -> ASCII -> UTF8 -> UTF8
|
||||
{
|
||||
StringStream s(json);
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer, UTF8<>, ASCII<> > writer(buffer);
|
||||
Reader reader;
|
||||
reader.Parse(s, writer);
|
||||
|
||||
StringBuffer buffer2;
|
||||
Writer<StringBuffer> writer2(buffer2);
|
||||
GenericReader<ASCII<>, UTF8<> > reader2;
|
||||
StringStream s2(buffer.GetString());
|
||||
reader2.Parse(s2, writer2);
|
||||
|
||||
EXPECT_STREQ(json, buffer2.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
#include <sstream>
|
||||
|
||||
class OStreamWrapper {
|
||||
public:
|
||||
typedef char Ch;
|
||||
|
||||
OStreamWrapper(std::ostream& os) : os_(os) {}
|
||||
|
||||
Ch Peek() const { assert(false); return '\0'; }
|
||||
Ch Take() { assert(false); return '\0'; }
|
||||
size_t Tell() const { return 0; }
|
||||
|
||||
Ch* PutBegin() { assert(false); return 0; }
|
||||
void Put(Ch c) { os_.put(c); }
|
||||
void Flush() { os_.flush(); }
|
||||
size_t PutEnd(Ch*) { assert(false); return 0; }
|
||||
|
||||
private:
|
||||
OStreamWrapper(const OStreamWrapper&);
|
||||
OStreamWrapper& operator=(const OStreamWrapper&);
|
||||
|
||||
std::ostream& os_;
|
||||
};
|
||||
|
||||
TEST(Writer, OStreamWrapper) {
|
||||
StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ");
|
||||
|
||||
std::stringstream ss;
|
||||
OStreamWrapper os(ss);
|
||||
|
||||
Writer<OStreamWrapper> writer(os);
|
||||
|
||||
Reader reader;
|
||||
reader.Parse<0>(s, writer);
|
||||
|
||||
std::string actual = ss.str();
|
||||
EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3]}", actual.c_str());
|
||||
}
|
||||
|
||||
TEST(Writer, AssertRootMayBeAnyValue) {
|
||||
#define T(x)\
|
||||
{\
|
||||
StringBuffer buffer;\
|
||||
Writer<StringBuffer> writer(buffer);\
|
||||
EXPECT_TRUE(x);\
|
||||
}
|
||||
T(writer.Bool(false));
|
||||
T(writer.Bool(true));
|
||||
T(writer.Null());
|
||||
T(writer.Int(0));
|
||||
T(writer.Uint(0));
|
||||
T(writer.Int64(0));
|
||||
T(writer.Uint64(0));
|
||||
T(writer.Double(0));
|
||||
T(writer.String("foo"));
|
||||
#undef T
|
||||
}
|
||||
|
||||
TEST(Writer, AssertIncorrectObjectLevel) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.EndObject();
|
||||
ASSERT_THROW(writer.EndObject(), AssertException);
|
||||
}
|
||||
|
||||
TEST(Writer, AssertIncorrectArrayLevel) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartArray();
|
||||
writer.EndArray();
|
||||
ASSERT_THROW(writer.EndArray(), AssertException);
|
||||
}
|
||||
|
||||
TEST(Writer, AssertIncorrectEndObject) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
ASSERT_THROW(writer.EndArray(), AssertException);
|
||||
}
|
||||
|
||||
TEST(Writer, AssertIncorrectEndArray) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
ASSERT_THROW(writer.EndArray(), AssertException);
|
||||
}
|
||||
|
||||
TEST(Writer, AssertObjectKeyNotString) {
|
||||
#define T(x)\
|
||||
{\
|
||||
StringBuffer buffer;\
|
||||
Writer<StringBuffer> writer(buffer);\
|
||||
writer.StartObject();\
|
||||
ASSERT_THROW(x, AssertException); \
|
||||
}
|
||||
T(writer.Bool(false));
|
||||
T(writer.Bool(true));
|
||||
T(writer.Null());
|
||||
T(writer.Int(0));
|
||||
T(writer.Uint(0));
|
||||
T(writer.Int64(0));
|
||||
T(writer.Uint64(0));
|
||||
T(writer.Double(0));
|
||||
T(writer.StartObject());
|
||||
T(writer.StartArray());
|
||||
#undef T
|
||||
}
|
||||
|
||||
TEST(Writer, AssertMultipleRoot) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
|
||||
writer.StartObject();
|
||||
writer.EndObject();
|
||||
ASSERT_THROW(writer.StartObject(), AssertException);
|
||||
|
||||
writer.Reset(buffer);
|
||||
writer.Null();
|
||||
ASSERT_THROW(writer.Int(0), AssertException);
|
||||
|
||||
writer.Reset(buffer);
|
||||
writer.String("foo");
|
||||
ASSERT_THROW(writer.StartArray(), AssertException);
|
||||
|
||||
writer.Reset(buffer);
|
||||
writer.StartArray();
|
||||
writer.EndArray();
|
||||
//ASSERT_THROW(writer.Double(3.14), AssertException);
|
||||
}
|
||||
|
||||
TEST(Writer, RootObjectIsComplete) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.StartObject();
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.String("foo");
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.Int(1);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.EndObject();
|
||||
EXPECT_TRUE(writer.IsComplete());
|
||||
}
|
||||
|
||||
TEST(Writer, RootArrayIsComplete) {
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.StartArray();
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.String("foo");
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.Int(1);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
writer.EndArray();
|
||||
EXPECT_TRUE(writer.IsComplete());
|
||||
}
|
||||
|
||||
TEST(Writer, RootValueIsComplete) {
|
||||
#define T(x)\
|
||||
{\
|
||||
StringBuffer buffer;\
|
||||
Writer<StringBuffer> writer(buffer);\
|
||||
EXPECT_FALSE(writer.IsComplete()); \
|
||||
x; \
|
||||
EXPECT_TRUE(writer.IsComplete()); \
|
||||
}
|
||||
T(writer.Null());
|
||||
T(writer.Bool(true));
|
||||
T(writer.Bool(false));
|
||||
T(writer.Int(0));
|
||||
T(writer.Uint(0));
|
||||
T(writer.Int64(0));
|
||||
T(writer.Uint64(0));
|
||||
T(writer.Double(0));
|
||||
T(writer.String(""));
|
||||
#undef T
|
||||
}
|
||||
Reference in New Issue
Block a user