mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-30 21:50:47 +01:00
back-port JSON and accompanying Foundation portions (JSONString, Dynamic::Var etc)
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
#include "Poco/TextConverter.h"
|
||||
#include "Poco/Nullable.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
@@ -28,7 +30,8 @@
|
||||
using namespace Poco::JSON;
|
||||
using namespace Poco::Dynamic;
|
||||
using Poco::DynamicStruct;
|
||||
|
||||
using Poco::DateTime;
|
||||
using Poco::DateTimeFormatter;
|
||||
|
||||
JSONTest::JSONTest(const std::string& name): CppUnit::TestCase("JSON")
|
||||
{
|
||||
@@ -320,6 +323,11 @@ void JSONTest::testStringProperty()
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
|
||||
object.set("test2", 'a');
|
||||
std::ostringstream ostr;
|
||||
object.stringify(ostr);
|
||||
assert(ostr.str() == "{\"test\":\"value\",\"test2\":\"a\"}");
|
||||
|
||||
DynamicStruct ds = object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isString());
|
||||
@@ -400,7 +408,7 @@ void JSONTest::testEmptyPropertyName()
|
||||
|
||||
void JSONTest::testComplexObject()
|
||||
{
|
||||
std::string json =
|
||||
std::string json =
|
||||
"{"
|
||||
"\"id\": 1,"
|
||||
"\"jsonrpc\": \"2.0\","
|
||||
@@ -454,7 +462,7 @@ void JSONTest::testComplexObject()
|
||||
"}"
|
||||
"]"
|
||||
"}";
|
||||
|
||||
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
@@ -619,27 +627,49 @@ void JSONTest::testObjectProperty()
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
assert (false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert (object->isObject("test"));
|
||||
assert (!object->isArray("test"));
|
||||
|
||||
Var test = object->get("test");
|
||||
assert(test.type() == typeid(Object::Ptr));
|
||||
assert (test.type() == typeid(Object::Ptr));
|
||||
Object::Ptr subObject = test.extract<Object::Ptr>();
|
||||
|
||||
test = subObject->get("property");
|
||||
assert(test.isString());
|
||||
assert (test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
assert (value.compare("value") == 0);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds["test"].isStruct());
|
||||
assert (ds["test"]["property"] == "value");
|
||||
|
||||
// make sure that Object is recognized as such
|
||||
{
|
||||
Object obj;
|
||||
Object inner;
|
||||
inner.set("some_number", 5);
|
||||
inner.set("some_string", "xyz");
|
||||
std::string key = "new_object";
|
||||
obj.set(key, inner);
|
||||
assert(obj.isObject(key));
|
||||
}
|
||||
|
||||
// make sure that Object pointer is recognized as Object
|
||||
{
|
||||
Object obj;
|
||||
Poco::JSON::Object::Ptr inner = new Poco::JSON::Object;
|
||||
inner->set("some_number", 5);
|
||||
inner->set("some_string", "xyz");
|
||||
std::string key = "new_object";
|
||||
obj.set(key, inner);
|
||||
assert(obj.isObject(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -679,6 +709,22 @@ void JSONTest::testObjectArray()
|
||||
assert (ds["test"]["test1"][1] == 2);
|
||||
assert (ds["test"]["test1"][2] == 3);
|
||||
assert (ds["test"]["test2"] == 4);
|
||||
|
||||
#ifdef POCO_ENABLE_CPP11
|
||||
|
||||
object->set("test3", "another top level value");
|
||||
ds = std::move(*object);
|
||||
assert (ds.size() == 2);
|
||||
assert (ds["test"].isStruct());
|
||||
assert (ds["test"]["test1"].isArray());
|
||||
assert (ds["test"]["test1"].size() == 3);
|
||||
assert (ds["test"]["test1"][0] == 1);
|
||||
assert (ds["test"]["test1"][1] == 2);
|
||||
assert (ds["test"]["test1"][2] == 3);
|
||||
assert (ds["test"]["test2"] == 4);
|
||||
assert (ds["test3"] == "another top level value");
|
||||
|
||||
#endif // POCO_ENABLE_CPP11
|
||||
}
|
||||
|
||||
|
||||
@@ -698,6 +744,7 @@ void JSONTest::testArrayOfObjects()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.isArray());
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
Poco::JSON::Array::Ptr arr = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Object::Ptr object = arr->getObject(0);
|
||||
@@ -921,6 +968,12 @@ void JSONTest::testStringElement()
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0] == "value");
|
||||
|
||||
std::stringstream s;
|
||||
json = "[ \"\\u0017\" ]";
|
||||
Var v = Parser().parse(json);
|
||||
Stringifier::condense(v, s);
|
||||
assert(s.str() == "[\"\\u0017\"]");
|
||||
}
|
||||
|
||||
|
||||
@@ -990,11 +1043,18 @@ void JSONTest::testSetArrayElement()
|
||||
Var result = parser.parse(json);
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
|
||||
Poco::Dynamic::Array dynArray = *array;
|
||||
assert(dynArray.size() == 0);
|
||||
|
||||
// array[0] = 7
|
||||
array->set(0, 7);
|
||||
assert(array->size() == 1);
|
||||
assert(array->getElement<int>(0) == 7);
|
||||
|
||||
dynArray = *array;
|
||||
assert(dynArray.size() == 1);
|
||||
assert(dynArray[0] == 7);
|
||||
|
||||
// array[2] = "foo"
|
||||
array->set(2, std::string("foo"));
|
||||
assert(array->size() == 3);
|
||||
@@ -1002,12 +1062,31 @@ void JSONTest::testSetArrayElement()
|
||||
assert(array->isNull(1));
|
||||
assert(array->getElement<std::string>(2) == "foo");
|
||||
|
||||
dynArray = *array;
|
||||
assert(dynArray.size() == 3);
|
||||
assert(dynArray[0] == 7);
|
||||
assert(dynArray[1].isEmpty());
|
||||
assert(dynArray[2] == "foo");
|
||||
|
||||
// array[1] = 13
|
||||
array->set(1, 13);
|
||||
assert(array->size() == 3);
|
||||
assert(array->getElement<int>(0) == 7);
|
||||
assert(array->getElement<int>(1) == 13);
|
||||
assert(array->getElement<std::string>(2) == "foo");
|
||||
|
||||
#ifdef POCO_ENABLE_CPP11
|
||||
|
||||
dynArray = std::move(*array);
|
||||
assert(dynArray.size() == 3);
|
||||
assert(dynArray[0] == 7);
|
||||
assert(dynArray[1] == 13);
|
||||
assert(dynArray[2] == "foo");
|
||||
|
||||
#endif POCO_ENABLE_CPP11
|
||||
|
||||
dynArray.clear();
|
||||
assert(dynArray.size() == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,7 +1207,10 @@ void JSONTest::testComment()
|
||||
catch(Poco::SyntaxException&)
|
||||
{
|
||||
}
|
||||
|
||||
catch (JSONException&)
|
||||
{
|
||||
}
|
||||
|
||||
parser.reset();
|
||||
parser.setAllowComments(true);
|
||||
try
|
||||
@@ -1211,7 +1293,7 @@ void JSONTest::testPrintHandler()
|
||||
"}"
|
||||
);
|
||||
|
||||
json =
|
||||
json =
|
||||
"{"
|
||||
"\"array\":"
|
||||
"["
|
||||
@@ -1255,7 +1337,6 @@ void JSONTest::testPrintHandler()
|
||||
pHandler->setIndent(0);
|
||||
parser.reset();
|
||||
parser.parse(json);
|
||||
std::cout << ostr.str() << std::endl;
|
||||
assert (json == ostr.str());
|
||||
|
||||
json="[{\"1\":\"one\",\"0\":[\"zero\",\"nil\"]}]";
|
||||
@@ -1270,6 +1351,27 @@ void JSONTest::testPrintHandler()
|
||||
|
||||
void JSONTest::testStringify()
|
||||
{
|
||||
std::ostringstream os;
|
||||
Var i = 123;
|
||||
Stringifier::stringify(i, os);
|
||||
assert(os.str() == "123");
|
||||
|
||||
os.str("");
|
||||
Var f = 123.456;
|
||||
Stringifier::stringify(f, os);
|
||||
assert(os.str() == "123.456");
|
||||
|
||||
os.str("");
|
||||
Var s = "abcdef";
|
||||
Stringifier::stringify(s, os);
|
||||
assert(os.str() == "\"abcdef\"");
|
||||
|
||||
os.str("");
|
||||
DateTime dt;
|
||||
Var d = dt;
|
||||
Stringifier::stringify(d, os);
|
||||
assert(os.str() == std::string("\"" + DateTimeFormatter::format(dt, Poco::DateTimeFormat::ISO8601_FORMAT) + "\""));
|
||||
|
||||
std::string str1 = "\r";
|
||||
std::string str2 = "\n";
|
||||
Poco::JSON::Object obj1, obj2;
|
||||
@@ -1478,7 +1580,7 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
assert (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
|
||||
"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
|
||||
"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
|
||||
|
||||
|
||||
ostr.str("");
|
||||
Stringifier::stringify(result, ostr, 1);
|
||||
assert (ostr.str() == "{\n"
|
||||
@@ -1498,7 +1600,7 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
" ],\n"
|
||||
" \"address\" : {\n"
|
||||
" \"number\" : 742,\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"town\" : \"Springfield\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
@@ -1523,7 +1625,7 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
" ],\n"
|
||||
" \"address\" : {\n"
|
||||
" \"number\" : 742,\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"town\" : \"Springfield\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
@@ -1548,7 +1650,7 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
" ],\n"
|
||||
" \"address\" : {\n"
|
||||
" \"number\" : 742,\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"street\" : \"Evergreen Terrace\",\n"
|
||||
" \"town\" : \"Springfield\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
@@ -1559,16 +1661,16 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
assert (ds["Simpsons"]["husband"].isStruct());
|
||||
assert (ds["Simpsons"]["husband"]["name"] == "Homer");
|
||||
assert (ds["Simpsons"]["husband"]["age"] == 38);
|
||||
|
||||
|
||||
assert (ds["Simpsons"]["wife"].isStruct());
|
||||
assert (ds["Simpsons"]["wife"]["name"] == "Marge");
|
||||
assert (ds["Simpsons"]["wife"]["age"] == 36);
|
||||
|
||||
|
||||
assert (ds["Simpsons"]["children"].isArray());
|
||||
assert (ds["Simpsons"]["children"][0] == "Bart");
|
||||
assert (ds["Simpsons"]["children"][1] == "Lisa");
|
||||
assert (ds["Simpsons"]["children"][2] == "Maggie");
|
||||
|
||||
|
||||
assert (ds["Simpsons"]["address"].isStruct());
|
||||
assert (ds["Simpsons"]["address"]["number"] == 742);
|
||||
assert (ds["Simpsons"]["address"]["street"] == "Evergreen Terrace");
|
||||
@@ -1593,7 +1695,7 @@ void JSONTest::testValidJanssonFiles()
|
||||
if ( inputFile.exists() )
|
||||
{
|
||||
Poco::FileInputStream fis(filePath.toString());
|
||||
std::cout << filePath.toString() << std::endl;
|
||||
std::cout << filePath.toString() << " ... ";
|
||||
|
||||
Parser parser;
|
||||
Var result;
|
||||
@@ -1633,13 +1735,13 @@ void JSONTest::testInvalidJanssonFiles()
|
||||
{
|
||||
Poco::Path filePath(*it, "input");
|
||||
|
||||
if ( filePath.isFile() )
|
||||
if (filePath.isFile())
|
||||
{
|
||||
Poco::File inputFile(filePath);
|
||||
if ( inputFile.exists() )
|
||||
if (inputFile.exists())
|
||||
{
|
||||
Poco::FileInputStream fis(filePath.toString());
|
||||
std::cout << filePath.toString() << std::endl;
|
||||
std::cout << filePath.toString() << " ... ";
|
||||
|
||||
Parser parser;
|
||||
parser.setAllowNullByte(false);
|
||||
@@ -1650,15 +1752,13 @@ void JSONTest::testInvalidJanssonFiles()
|
||||
parser.parse(fis);
|
||||
result = parser.asVar();
|
||||
// We shouldn't get here.
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
fail(result.convert<std::string>());
|
||||
}
|
||||
catch(JSONException&)
|
||||
catch(Poco::Exception& /*ex*/)
|
||||
{
|
||||
continue;
|
||||
std::cout << /*" (" << ex.displayText() << ") " <<*/ "Ok!" << std::endl;
|
||||
}
|
||||
catch(Poco::SyntaxException&)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1682,7 +1782,7 @@ void JSONTest::testInvalidUnicodeJanssonFiles()
|
||||
if ( inputFile.exists() )
|
||||
{
|
||||
Poco::FileInputStream fis(filePath.toString());
|
||||
std::cout << filePath.toString() << std::endl;
|
||||
std::cout << filePath.toString() << " ... ";
|
||||
|
||||
Parser parser;
|
||||
parser.setAllowNullByte(false);
|
||||
@@ -1693,15 +1793,13 @@ void JSONTest::testInvalidUnicodeJanssonFiles()
|
||||
parser.parse(fis);
|
||||
result = parser.asVar();
|
||||
// We shouldn't get here.
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
fail(result.convert<std::string>());
|
||||
}
|
||||
catch(JSONException&)
|
||||
catch(Poco::Exception& /*ex*/)
|
||||
{
|
||||
continue;
|
||||
std::cout << /*" (" << ex.displayText() << ") " <<*/ "Ok!" << std::endl;
|
||||
}
|
||||
catch(Poco::SyntaxException&)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1762,13 +1860,13 @@ void JSONTest::testUnicode()
|
||||
|
||||
parser.reset();
|
||||
os.str("");
|
||||
os << '[' << (char)0xC2 << (char)0x92 << ']';
|
||||
os << "[\"" << (char)0xC2 << (char)0x92 << "\"]";
|
||||
result = parser.parse(os.str());
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
parser.reset();
|
||||
os.str("");
|
||||
os << '[' << (char)0xAC << ']';
|
||||
os << "[\"" << (char)0xAC << "\"]";
|
||||
try
|
||||
{
|
||||
parser.parse(os.str());
|
||||
@@ -1778,13 +1876,13 @@ void JSONTest::testUnicode()
|
||||
|
||||
parser.reset();
|
||||
os.str("");
|
||||
os << '[' << (char)0xE2 << (char)0x82 << (char)0xAC << ']';
|
||||
os << "[\"" << (char)0xE2 << (char)0x82 << (char)0xAC << "\"]";
|
||||
result = parser.parse(os.str());
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
parser.reset();
|
||||
os.str("");
|
||||
os << '[' << (char)0xA2 << ']';
|
||||
os << "[\"" << (char)0xA2 << "\"]";
|
||||
try
|
||||
{
|
||||
parser.parse(os.str());
|
||||
@@ -1794,7 +1892,7 @@ void JSONTest::testUnicode()
|
||||
|
||||
parser.reset();
|
||||
os.str("");
|
||||
os << '[' << (char)0xF0 << (char)0xA4 << (char)0xAD << (char)0xAD << ']';
|
||||
os << "[\"" << (char)0xF0 << (char)0xA4 << (char)0xAD << (char)0xAD << "\"]";
|
||||
result = parser.parse(os.str());
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
}
|
||||
@@ -1807,6 +1905,45 @@ void JSONTest::testSmallBuffer()
|
||||
parser.parse(jsonStr);
|
||||
}
|
||||
|
||||
void JSONTest::testEscape0()
|
||||
{
|
||||
Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
|
||||
|
||||
std::string nullString("B\0b", 3);
|
||||
json->set("name", nullString);
|
||||
|
||||
std::stringstream ss;
|
||||
json->stringify(ss);
|
||||
|
||||
assert(ss.str().compare("{\"name\":\"B\\u0000b\"}") == 0);
|
||||
}
|
||||
|
||||
void JSONTest::testEscapeUnicode()
|
||||
{
|
||||
Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
|
||||
std::string chinese("{ \"name\" : \"\\u4e2d\" }");
|
||||
Poco::JSON::Parser parser(new Poco::JSON::ParseHandler());
|
||||
Var result = parser.parse(chinese);
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
|
||||
std::stringstream ss;
|
||||
object->stringify(ss);
|
||||
|
||||
assert(ss.str().compare("{\"name\":\"\\u4E2D\"}") == 0);
|
||||
|
||||
const unsigned char utf8Chars[] = {'{', '"', 'n', 'a', 'm', 'e', '"', ':',
|
||||
'"', 'g', 195, 188, 'n', 't', 'e', 'r', '"', '}', 0};
|
||||
std::string utf8Text((const char*) utf8Chars);
|
||||
parser.reset();
|
||||
result = parser.parse(utf8Text);
|
||||
object = result.extract<Object::Ptr>();
|
||||
ss.str(""); object->stringify(ss);
|
||||
assert (ss.str() == "{\"name\":\"g\\u00FCnter\"}");
|
||||
}
|
||||
|
||||
|
||||
std::string JSONTest::getTestFilesPath(const std::string& type)
|
||||
{
|
||||
@@ -1823,6 +1960,7 @@ std::string JSONTest::getTestFilesPath(const std::string& type)
|
||||
ostr.str("");
|
||||
ostr << "/JSON/testsuite/data/" << type << '/';
|
||||
validDir = Poco::Environment::get("POCO_BASE") + ostr.str();
|
||||
std::cout << validDir << std::endl;
|
||||
pathPattern = validDir;
|
||||
|
||||
if (Poco::File(pathPattern).exists())
|
||||
@@ -1881,6 +2019,8 @@ CppUnit::Test* JSONTest::suite()
|
||||
CppUnit_addTest(pSuite, JSONTest, testTemplate);
|
||||
CppUnit_addTest(pSuite, JSONTest, testUnicode);
|
||||
CppUnit_addTest(pSuite, JSONTest, testSmallBuffer);
|
||||
CppUnit_addTest(pSuite, JSONTest, testEscape0);
|
||||
CppUnit_addTest(pSuite, JSONTest, testEscapeUnicode);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user