blob: 8b876ddf4ee2759f2144d80f886e48ada414c144 [file] [log] [blame]
Florin Malita7796f002018-06-08 12:25:38 -04001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
9
10#include "SkJSON.h"
11#include "SkStream.h"
12
13using namespace skjson;
14
15DEF_TEST(SkJSON_Parse, reporter) {
16 static constexpr struct {
17 const char* in;
18 const char* out;
19 } g_tests[] = {
20 { "" , nullptr },
21 { "[" , nullptr },
22 { "]" , nullptr },
23 { "{" , nullptr },
24 { "}" , nullptr },
25 { "{]" , nullptr },
26 { "[}" , nullptr },
27 { "1" , nullptr },
28 { "true" , nullptr },
29 { "false", nullptr },
30 { "null" , nullptr },
31
32 { "[nulll]" , nullptr },
33 { "[false2]", nullptr },
34 { "[true:]" , nullptr },
35
36 { "[1 2]" , nullptr },
37 { "[1,,2]" , nullptr },
38 { "[1,2,]" , nullptr },
39 { "[,1,2]" , nullptr },
40
41 { "[ \"foo" , nullptr },
42 { "[ \"fo\0o\" ]" , nullptr },
43
44 { "{ null }" , nullptr },
45 { "{ \"k\" : }" , nullptr },
46 { "{ : null }" , nullptr },
47 { "{ \"k\" : : null }" , nullptr },
48 { "{ \"k\" : null , }" , nullptr },
49 { "{ \"k\" : null \"k\" : 1 }", nullptr },
50
51
52 { " \n\r\t [ \n\r\t ] \n\r\t " , "[]" },
53 { "[ null ]" , "[null]" },
54 { "[ true ]" , "[true]" },
55 { "[ false ]" , "[false]" },
56 { "[ 0 ]" , "[0]" },
57 { "[ 1 ]" , "[1]" },
58 { "[ 1.248 ]" , "[1.248]" },
59 { "[ \"\" ]" , "[\"\"]" },
60 { "[ \" f o o \" ]" , "[\" f o o \"]" },
61 { "[ \"123456\" ]" , "[\"123456\"]" },
62 { "[ \"1234567\" ]" , "[\"1234567\"]" },
63 { "[ \"12345678\" ]" , "[\"12345678\"]" },
64 { "[ \"123456789\" ]" , "[\"123456789\"]" },
65 { "[ null , true, false,0,12.8 ]", "[null,true,false,0,12.8]" },
66
67 { " \n\r\t { \n\r\t } \n\r\t " , "{}" },
68 { "{ \"k\" : null }" , "{\"k\":null}" },
69 { "{ \"k1\" : null, \"k2 \":0 }", "{\"k1\":null,\"k2 \":0}" },
70 { "{ \"k1\" : null, \"k1\":0 }" , "{\"k1\":null,\"k1\":0}" },
71
72 { "{ \"k1\" : null, \n\
73 \"k2\" : 0, \n\
74 \"k3\" : [ \n\
75 true, \r\n\
76 { \"kk1\" : \"foo\" , \n\
77 \"kk2\" : \"bar\" , \n\
78 \"kk3\" : 1.28 , \n\
79 \"kk4\" : [ 42 ] \n\
80 } , \n\
81 \"boo\" , \n\
82 null \n\
83 ] \n\
84 }",
85 "{\"k1\":null,\"k2\":0,\"k3\":[true,"
86 "{\"kk1\":\"foo\",\"kk2\":\"bar\",\"kk3\":1.28,\"kk4\":[42]},\"boo\",null]}" },
87 };
88
89 for (const auto& tst : g_tests) {
90 DOM dom(tst.in);
91 const auto success = !dom.root().is<NullValue>();
92 REPORTER_ASSERT(reporter, success == (tst.out != nullptr));
93 if (!success) continue;
94
95 SkDynamicMemoryWStream str;
96 dom.write(&str);
97 str.write8('\0');
98
99 auto data = str.detachAsData();
100 REPORTER_ASSERT(reporter, !strcmp(tst.out, static_cast<const char*>(data->data())));
101 }
102
103}
104
105template <typename T, typename VT>
106static void check_primitive(skiatest::Reporter* reporter, const Value& v, T pv,
107 bool is_type) {
108
109 REPORTER_ASSERT(reporter, v.is<VT>() == is_type);
110 REPORTER_ASSERT(reporter, *v.as<VT>() == pv);
111}
112
113template <typename T>
114static void check_vector(skiatest::Reporter* reporter, const Value& v, size_t expected_size,
115 bool is_vector) {
116 REPORTER_ASSERT(reporter, v.is<T>() == is_vector);
117
118 const auto& vec = v.as<T>();
119 REPORTER_ASSERT(reporter, vec.size() == expected_size);
120 REPORTER_ASSERT(reporter, (vec.begin() != nullptr) == is_vector);
121 REPORTER_ASSERT(reporter, vec.end() == vec.begin() + expected_size);
122}
123
124static void check_string(skiatest::Reporter* reporter, const Value& v, const char* s) {
125 check_vector<StringValue>(reporter, v, s ? strlen(s) : 0, !!s);
126 if (s) {
127 REPORTER_ASSERT(reporter, !strcmp(v.as<StringValue>().begin(), s));
128 }
129}
130
131DEF_TEST(SkJSON_DOM, reporter) {
132 static constexpr char json[] = "{ \n\
133 \"k1\": null, \n\
134 \"k2\": false, \n\
135 \"k3\": true, \n\
136 \"k4\": 42, \n\
137 \"k5\": .75, \n\
138 \"k6\": \"foo\", \n\
139 \"k7\": [ 1, true, \"bar\" ], \n\
140 \"k8\": { \"kk1\": 2, \"kk2\": false, \"kk1\": \"baz\" } \n\
141 }";
142
143 DOM dom(json);
144
145 const auto& jroot = dom.root().as<ObjectValue>();
146 REPORTER_ASSERT(reporter, jroot.is<ObjectValue>());
147
148 {
149 const auto& v = jroot["k1"];
150 REPORTER_ASSERT(reporter, v.is<NullValue>());
151
152 check_primitive<bool, BoolValue>(reporter, v, false, false);
153 check_primitive<float, NumberValue>(reporter, v, 0, false);
154
155 check_string(reporter, v, nullptr);
156 check_vector<ArrayValue >(reporter, v, 0, false);
157 check_vector<ObjectValue>(reporter, v, 0, false);
158 }
159
160 {
161 const auto& v = jroot["k2"];
162 REPORTER_ASSERT(reporter, !v.is<NullValue>());
163
164 check_primitive<bool, BoolValue>(reporter, v, false, true);
165 check_primitive<float, NumberValue>(reporter, v, 0, false);
166
167 check_string(reporter, v, nullptr);
168 check_vector<ArrayValue >(reporter, v, 0, false);
169 check_vector<ObjectValue>(reporter, v, 0, false);
170 }
171
172 {
173 const auto& v = jroot["k3"];
174 REPORTER_ASSERT(reporter, !v.is<NullValue>());
175
176 check_primitive<bool, BoolValue>(reporter, v, true, true);
177 check_primitive<float, NumberValue>(reporter, v, 0, false);
178
179 check_string(reporter, v, nullptr);
180 check_vector<ArrayValue >(reporter, v, 0, false);
181 check_vector<ObjectValue>(reporter, v, 0, false);
182 }
183
184 {
185 const auto& v = jroot["k4"];
186 REPORTER_ASSERT(reporter, !v.is<NullValue>());
187
188 check_primitive<bool, BoolValue>(reporter, v, false, false);
189 check_primitive<float, NumberValue>(reporter, v, 42, true);
190
191 check_string(reporter, v, nullptr);
192 check_vector<ArrayValue >(reporter, v, 0, false);
193 check_vector<ObjectValue>(reporter, v, 0, false);
194 }
195
196 {
197 const auto& v = jroot["k5"];
198 REPORTER_ASSERT(reporter, !v.is<NullValue>());
199
200 check_primitive<bool, BoolValue>(reporter, v, false, false);
201 check_primitive<float, NumberValue>(reporter, v, .75f, true);
202
203 check_string(reporter, v, nullptr);
204 check_vector<ArrayValue >(reporter, v, 0, false);
205 check_vector<ObjectValue>(reporter, v, 0, false);
206 }
207
208 {
209 const auto& v = jroot["k6"];
210 REPORTER_ASSERT(reporter, !v.is<NullValue>());
211
212 check_primitive<bool, BoolValue>(reporter, v, false, false);
213 check_primitive<float, NumberValue>(reporter, v, 0, false);
214
215 check_string(reporter, v, "foo");
216 check_vector<ArrayValue >(reporter, v, 0, false);
217 check_vector<ObjectValue>(reporter, v, 0, false);
218 }
219
220 {
221 const auto& v = jroot["k7"];
222 REPORTER_ASSERT(reporter, !v.is<NullValue>());
223
224 check_primitive<bool, BoolValue>(reporter, v, false, false);
225 check_primitive<float, NumberValue>(reporter, v, 0, false);
226
227 check_string(reporter, v, nullptr);
228 check_vector<ObjectValue>(reporter, v, 0, false);
229
230 check_vector<ArrayValue >(reporter, v, 3, true);
231 check_primitive<float, NumberValue>(reporter, v.as<ArrayValue>()[0], 1, true);
232 check_primitive<bool, BoolValue>(reporter, v.as<ArrayValue>()[1], true, true);
233 check_vector<StringValue>(reporter, v.as<ArrayValue>()[2], 3, true);
234 REPORTER_ASSERT(reporter, v.as<ArrayValue>()[3].is<NullValue>());
235 }
236
237 {
238 const auto& v = jroot["k8"];
239 REPORTER_ASSERT(reporter, !v.is<NullValue>());
240
241 check_primitive<bool, BoolValue>(reporter, v, false, false);
242 check_primitive<float, NumberValue>(reporter, v, 0, false);
243
244 check_string(reporter, v, nullptr);
245 check_vector<ArrayValue >(reporter, v, 0, false);
246
247 check_vector<ObjectValue>(reporter, v, 3, true);
248
249 const auto& m0 = v.as<ObjectValue>().begin()[0];
250 check_string(reporter, m0.fKey, "kk1");
251 check_primitive<float, NumberValue>(reporter, m0.fValue, 2, true);
252
253 const auto& m1 = v.as<ObjectValue>().begin()[1];
254 check_string(reporter, m1.fKey, "kk2");
255 check_primitive<bool, BoolValue>(reporter, m1.fValue, false, true);
256
257 const auto& m2 = v.as<ObjectValue>().begin()[2];
258 check_string(reporter, m2.fKey, "kk1");
259 check_string(reporter, m2.fValue, "baz");
260
261 REPORTER_ASSERT(reporter, v.as<ObjectValue>()[""].is<NullValue>());
262 REPORTER_ASSERT(reporter, v.as<ObjectValue>()["nosuchkey"].is<NullValue>());
263 check_string(reporter, v.as<ObjectValue>()["kk1"], "baz");
264 check_primitive<bool, BoolValue>(reporter, v.as<ObjectValue>()["kk2"], false, true);
265 }
266
267 {
268 const auto& v =
269 jroot["foo"].as<ObjectValue>()["bar"].as<ObjectValue>()["baz"];
270 REPORTER_ASSERT(reporter, v.is<NullValue>());
271 }
272}