/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "Test.h" #include "SkJSON.h" #include "SkStream.h" using namespace skjson; DEF_TEST(SkJSON_Parse, reporter) { static constexpr struct { const char* in; const char* out; } g_tests[] = { { "" , nullptr }, { "[" , nullptr }, { "]" , nullptr }, { "{" , nullptr }, { "}" , nullptr }, { "{]" , nullptr }, { "[}" , nullptr }, { "1" , nullptr }, { "true" , nullptr }, { "false", nullptr }, { "null" , nullptr }, { "[nulll]" , nullptr }, { "[false2]", nullptr }, { "[true:]" , nullptr }, { "[1 2]" , nullptr }, { "[1,,2]" , nullptr }, { "[1,2,]" , nullptr }, { "[,1,2]" , nullptr }, { "[ \"foo" , nullptr }, { "[ \"fo\0o\" ]" , nullptr }, { "{ null }" , nullptr }, { "{ \"k\" : }" , nullptr }, { "{ : null }" , nullptr }, { "{ \"k\" : : null }" , nullptr }, { "{ \"k\" : null , }" , nullptr }, { "{ \"k\" : null \"k\" : 1 }", nullptr }, { " \n\r\t [ \n\r\t ] \n\r\t " , "[]" }, { "[ null ]" , "[null]" }, { "[ true ]" , "[true]" }, { "[ false ]" , "[false]" }, { "[ 0 ]" , "[0]" }, { "[ 1 ]" , "[1]" }, { "[ 1.248 ]" , "[1.248]" }, { "[ \"\" ]" , "[\"\"]" }, { "[ \" f o o \" ]" , "[\" f o o \"]" }, { "[ \"123456\" ]" , "[\"123456\"]" }, { "[ \"1234567\" ]" , "[\"1234567\"]" }, { "[ \"12345678\" ]" , "[\"12345678\"]" }, { "[ \"123456789\" ]" , "[\"123456789\"]" }, { "[ null , true, false,0,12.8 ]", "[null,true,false,0,12.8]" }, { " \n\r\t { \n\r\t } \n\r\t " , "{}" }, { "{ \"k\" : null }" , "{\"k\":null}" }, { "{ \"k1\" : null, \"k2 \":0 }", "{\"k1\":null,\"k2 \":0}" }, { "{ \"k1\" : null, \"k1\":0 }" , "{\"k1\":null,\"k1\":0}" }, { "{ \"k1\" : null, \n\ \"k2\" : 0, \n\ \"k3\" : [ \n\ true, \r\n\ { \"kk1\" : \"foo\" , \n\ \"kk2\" : \"bar\" , \n\ \"kk3\" : 1.28 , \n\ \"kk4\" : [ 42 ] \n\ } , \n\ \"boo\" , \n\ null \n\ ] \n\ }", "{\"k1\":null,\"k2\":0,\"k3\":[true," "{\"kk1\":\"foo\",\"kk2\":\"bar\",\"kk3\":1.28,\"kk4\":[42]},\"boo\",null]}" }, }; for (const auto& tst : g_tests) { DOM dom(tst.in); const auto success = !dom.root().is(); REPORTER_ASSERT(reporter, success == (tst.out != nullptr)); if (!success) continue; SkDynamicMemoryWStream str; dom.write(&str); str.write8('\0'); auto data = str.detachAsData(); REPORTER_ASSERT(reporter, !strcmp(tst.out, static_cast(data->data()))); } } template static void check_primitive(skiatest::Reporter* reporter, const Value& v, T pv, bool is_type) { REPORTER_ASSERT(reporter, v.is() == is_type); REPORTER_ASSERT(reporter, *v.as() == pv); } template static void check_vector(skiatest::Reporter* reporter, const Value& v, size_t expected_size, bool is_vector) { REPORTER_ASSERT(reporter, v.is() == is_vector); const auto& vec = v.as(); REPORTER_ASSERT(reporter, vec.size() == expected_size); REPORTER_ASSERT(reporter, (vec.begin() != nullptr) == is_vector); REPORTER_ASSERT(reporter, vec.end() == vec.begin() + expected_size); } static void check_string(skiatest::Reporter* reporter, const Value& v, const char* s) { check_vector(reporter, v, s ? strlen(s) : 0, !!s); if (s) { REPORTER_ASSERT(reporter, !strcmp(v.as().begin(), s)); } } DEF_TEST(SkJSON_DOM, reporter) { static constexpr char json[] = "{ \n\ \"k1\": null, \n\ \"k2\": false, \n\ \"k3\": true, \n\ \"k4\": 42, \n\ \"k5\": .75, \n\ \"k6\": \"foo\", \n\ \"k7\": [ 1, true, \"bar\" ], \n\ \"k8\": { \"kk1\": 2, \"kk2\": false, \"kk1\": \"baz\" } \n\ }"; DOM dom(json); const auto& jroot = dom.root().as(); REPORTER_ASSERT(reporter, jroot.is()); { const auto& v = jroot["k1"]; REPORTER_ASSERT(reporter, v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, 0, false); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k2"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, true); check_primitive(reporter, v, 0, false); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k3"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, true, true); check_primitive(reporter, v, 0, false); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k4"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, 42, true); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k5"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, .75f, true); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k6"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, 0, false); check_string(reporter, v, "foo"); check_vector(reporter, v, 0, false); check_vector(reporter, v, 0, false); } { const auto& v = jroot["k7"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, 0, false); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 3, true); check_primitive(reporter, v.as()[0], 1, true); check_primitive(reporter, v.as()[1], true, true); check_vector(reporter, v.as()[2], 3, true); REPORTER_ASSERT(reporter, v.as()[3].is()); } { const auto& v = jroot["k8"]; REPORTER_ASSERT(reporter, !v.is()); check_primitive(reporter, v, false, false); check_primitive(reporter, v, 0, false); check_string(reporter, v, nullptr); check_vector(reporter, v, 0, false); check_vector(reporter, v, 3, true); const auto& m0 = v.as().begin()[0]; check_string(reporter, m0.fKey, "kk1"); check_primitive(reporter, m0.fValue, 2, true); const auto& m1 = v.as().begin()[1]; check_string(reporter, m1.fKey, "kk2"); check_primitive(reporter, m1.fValue, false, true); const auto& m2 = v.as().begin()[2]; check_string(reporter, m2.fKey, "kk1"); check_string(reporter, m2.fValue, "baz"); REPORTER_ASSERT(reporter, v.as()[""].is()); REPORTER_ASSERT(reporter, v.as()["nosuchkey"].is()); check_string(reporter, v.as()["kk1"], "baz"); check_primitive(reporter, v.as()["kk2"], false, true); } { const auto& v = jroot["foo"].as()["bar"].as()["baz"]; REPORTER_ASSERT(reporter, v.is()); } }