Flutter Engine
The Flutter Engine
Functions
JSONTest.cpp File Reference
#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "src/base/SkArenaAlloc.h"
#include "src/utils/SkJSON.h"
#include "tests/Test.h"
#include <cstring>
#include <string_view>

Go to the source code of this file.

Functions

 DEF_TEST (JSON_Parse, reporter)
 
template<typename T , typename VT >
static void check_primitive (skiatest::Reporter *reporter, const Value &v, T pv, bool is_type)
 
template<typename T >
static void check_vector (skiatest::Reporter *reporter, const Value &v, size_t expected_size, bool is_vector)
 
static void check_string (skiatest::Reporter *reporter, const Value &v, const char *s)
 
 DEF_TEST (JSON_DOM_visit, reporter)
 
template<typename T >
void check_value (skiatest::Reporter *reporter, const Value &v, const char *expected_string)
 
 DEF_TEST (JSON_DOM_build, reporter)
 
 DEF_TEST (JSON_ParseNumber, reporter)
 
 DEF_TEST (JSON_Lookup, r)
 
 DEF_TEST (JSON_Writable, r)
 

Function Documentation

◆ check_primitive()

template<typename T , typename VT >
static void check_primitive ( skiatest::Reporter reporter,
const Value v,
T  pv,
bool  is_type 
)
static

Definition at line 155 of file JSONTest.cpp.

156 {
157
158 REPORTER_ASSERT(reporter, v.is<VT>() == is_type);
159 const VT* cast_t = v;
160 REPORTER_ASSERT(reporter, (cast_t != nullptr) == is_type);
161
162 if (is_type) {
163 REPORTER_ASSERT(reporter, &v.as<VT>() == cast_t);
164 REPORTER_ASSERT(reporter, *v.as<VT>() == pv);
165 }
166}
reporter
Definition: FontMgrTest.cpp:39
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
const T & as() const
Definition: SkJSON.h:85
bool is() const
Definition: SkJSON.h:77

◆ check_string()

static void check_string ( skiatest::Reporter reporter,
const Value v,
const char *  s 
)
static

Definition at line 184 of file JSONTest.cpp.

184 {
185 check_vector<StringValue>(reporter, v, s ? strlen(s) : 0, !!s);
186 if (s) {
188 REPORTER_ASSERT(reporter, !strcmp(v.as<StringValue>().begin(), s));
189 }
190}
const char * begin() const
Definition: SkJSON.h:315
std::string_view str() const
Definition: SkJSON.h:327
struct MyStruct s

◆ check_value()

template<typename T >
void check_value ( skiatest::Reporter reporter,
const Value v,
const char *  expected_string 
)

Definition at line 342 of file JSONTest.cpp.

342 {
344
345 const T* cast_t = v;
346 REPORTER_ASSERT(reporter, cast_t == &v.as<T>());
347
348 const auto vstr = v.toString();
349 REPORTER_ASSERT(reporter, 0 == strcmp(expected_string, vstr.c_str()));
350}
SkString toString() const
Definition: SkJSON.cpp:938
#define T
Definition: precompiler.cc:65

◆ check_vector()

template<typename T >
static void check_vector ( skiatest::Reporter reporter,
const Value v,
size_t  expected_size,
bool  is_vector 
)
static

Definition at line 169 of file JSONTest.cpp.

170 {
171 REPORTER_ASSERT(reporter, v.is<T>() == is_vector);
172 const T* cast_t = v;
173 REPORTER_ASSERT(reporter, (cast_t != nullptr) == is_vector);
174
175 if (is_vector) {
176 const auto& vec = v.as<T>();
177 REPORTER_ASSERT(reporter, &vec == cast_t);
178 REPORTER_ASSERT(reporter, vec.size() == expected_size);
179 REPORTER_ASSERT(reporter, vec.begin() != nullptr);
180 REPORTER_ASSERT(reporter, vec.end() == vec.begin() + expected_size);
181 }
182}

◆ DEF_TEST() [1/6]

DEF_TEST ( JSON_DOM_build  ,
reporter   
)

Definition at line 352 of file JSONTest.cpp.

352 {
353 SkArenaAlloc alloc(4096);
354
355 const auto v0 = NullValue();
356 check_value<NullValue>(reporter, v0, "null");
357
358 const auto v1 = BoolValue(true);
359 check_value<BoolValue>(reporter, v1, "true");
360
361 const auto v2 = BoolValue(false);
362 check_value<BoolValue>(reporter, v2, "false");
363
364 const auto v3 = NumberValue(0);
365 check_value<NumberValue>(reporter, v3, "0");
366
367 const auto v4 = NumberValue(42);
368 check_value<NumberValue>(reporter, v4, "42");
369
370 const auto v5 = NumberValue(42.75f);
371 check_value<NumberValue>(reporter, v5, "42.75");
372
373 const auto v6 = StringValue(nullptr, 0, alloc);
374 check_value<StringValue>(reporter, v6, "\"\"");
375
376 const auto v7 = StringValue(" foo ", 5, alloc);
377 check_value<StringValue>(reporter, v7, "\" foo \"");
378
379 const auto v8 = StringValue(" foo bar baz ", 13, alloc);
380 check_value<StringValue>(reporter, v8, "\" foo bar baz \"");
381
382 const auto v9 = ArrayValue(nullptr, 0, alloc);
383 check_value<ArrayValue>(reporter, v9, "[]");
384
385 const Value values0[] = { v0, v3, v9 };
386 const auto v10 = ArrayValue(values0, std::size(values0), alloc);
387 check_value<ArrayValue>(reporter, v10, "[null,0,[]]");
388
389 const auto v11 = ObjectValue(nullptr, 0, alloc);
390 check_value<ObjectValue>(reporter, v11, "{}");
391
392 const Member members0[] = {
393 { StringValue("key_0", 5, alloc), v1 },
394 { StringValue("key_1", 5, alloc), v4 },
395 { StringValue("key_2", 5, alloc), v11 },
396 };
397 const auto v12 = ObjectValue(members0, std::size(members0), alloc);
398 check_value<ObjectValue>(reporter, v12, "{"
399 "\"key_0\":true,"
400 "\"key_1\":42,"
401 "\"key_2\":{}"
402 "}");
403
404 const Value values1[] = { v2, v6, v12 };
405 const auto v13 = ArrayValue(values1, std::size(values1), alloc);
406 check_value<ArrayValue>(reporter, v13, "["
407 "false,"
408 "\"\","
409 "{"
410 "\"key_0\":true,"
411 "\"key_1\":42,"
412 "\"key_2\":{}"
413 "}"
414 "]");
415
416 const Member members1[] = {
417 { StringValue("key_00", 6, alloc), v5 },
418 { StringValue("key_01", 6, alloc), v7 },
419 { StringValue("key_02", 6, alloc), v13 },
420 };
421 const auto v14 = ObjectValue(members1, std::size(members1), alloc);
422 check_value<ObjectValue>(reporter, v14, "{"
423 "\"key_00\":42.75,"
424 "\"key_01\":\" foo \","
425 "\"key_02\":["
426 "false,"
427 "\"\","
428 "{"
429 "\"key_0\":true,"
430 "\"key_1\":42,"
431 "\"key_2\":{}"
432 "}"
433 "]"
434 "}");
435}
static SkV4 v4(SkV3 v, SkScalar w)
Definition: SkM44.cpp:329
Vec2Value v2
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ DEF_TEST() [2/6]

DEF_TEST ( JSON_DOM_visit  ,
reporter   
)

Definition at line 192 of file JSONTest.cpp.

192 {
193 static constexpr char json[] = "{ \n\
194 \"k1\": null, \n\
195 \"k2\": false, \n\
196 \"k3\": true, \n\
197 \"k4\": 42, \n\
198 \"k5\": .75, \n\
199 \"k6\": \"foo\", \n\
200 \"k6b\": \"this string is long\", \n\
201 \"k7\": [ 1, true, \"bar\" ], \n\
202 \"k8\": { \"kk1\": 2, \"kk2\": false, \"kk1\": \"baz\" } \n\
203 }";
204
205 DOM dom(json, strlen(json));
206
207 const auto& jroot = dom.root().as<ObjectValue>();
209
210 {
211 const auto& v = jroot["k1"];
213
214 check_primitive<bool, BoolValue>(reporter, v, false, false);
215 check_primitive<float, NumberValue>(reporter, v, 0, false);
216
217 check_string(reporter, v, nullptr);
218 check_vector<ArrayValue >(reporter, v, 0, false);
219 check_vector<ObjectValue>(reporter, v, 0, false);
220 }
221
222 {
223 const auto& v = jroot["k2"];
225
226 check_primitive<bool, BoolValue>(reporter, v, false, true);
227 check_primitive<float, NumberValue>(reporter, v, 0, false);
228
229 check_string(reporter, v, nullptr);
230 check_vector<ArrayValue >(reporter, v, 0, false);
231 check_vector<ObjectValue>(reporter, v, 0, false);
232 }
233
234 {
235 const auto& v = jroot["k3"];
237
238 check_primitive<bool, BoolValue>(reporter, v, true, true);
239 check_primitive<float, NumberValue>(reporter, v, 0, false);
240
241 check_string(reporter, v, nullptr);
242 check_vector<ArrayValue >(reporter, v, 0, false);
243 check_vector<ObjectValue>(reporter, v, 0, false);
244 }
245
246 {
247 const auto& v = jroot["k4"];
249
250 check_primitive<bool, BoolValue>(reporter, v, false, false);
251 check_primitive<float, NumberValue>(reporter, v, 42, true);
252
253 check_string(reporter, v, nullptr);
254 check_vector<ArrayValue >(reporter, v, 0, false);
255 check_vector<ObjectValue>(reporter, v, 0, false);
256 }
257
258 {
259 const auto& v = jroot["k5"];
261
262 check_primitive<bool, BoolValue>(reporter, v, false, false);
263 check_primitive<float, NumberValue>(reporter, v, .75f, true);
264
265 check_string(reporter, v, nullptr);
266 check_vector<ArrayValue >(reporter, v, 0, false);
267 check_vector<ObjectValue>(reporter, v, 0, false);
268 }
269
270 {
271 const auto& v = jroot["k6"];
273
274 check_primitive<bool, BoolValue>(reporter, v, false, false);
275 check_primitive<float, NumberValue>(reporter, v, 0, false);
276
277 check_string(reporter, v, "foo");
278 check_vector<ArrayValue >(reporter, v, 0, false);
279 check_vector<ObjectValue>(reporter, v, 0, false);
280 }
281
282 {
283 const auto& v = jroot["k6b"];
285
286 check_primitive<bool, BoolValue>(reporter, v, false, false);
287 check_primitive<float, NumberValue>(reporter, v, 0, false);
288
289 check_string(reporter, v, "this string is long");
290 check_vector<ArrayValue >(reporter, v, 0, false);
291 check_vector<ObjectValue>(reporter, v, 0, false);
292 }
293
294 {
295 const auto& v = jroot["k7"];
297
298 check_primitive<bool, BoolValue>(reporter, v, false, false);
299 check_primitive<float, NumberValue>(reporter, v, 0, false);
300
301 check_string(reporter, v, nullptr);
302 check_vector<ObjectValue>(reporter, v, 0, false);
303
304 check_vector<ArrayValue >(reporter, v, 3, true);
305 check_primitive<float, NumberValue>(reporter, v.as<ArrayValue>()[0], 1, true);
306 check_primitive<bool, BoolValue>(reporter, v.as<ArrayValue>()[1], true, true);
307 check_vector<StringValue>(reporter, v.as<ArrayValue>()[2], 3, true);
308 }
309
310 {
311 const auto& v = jroot["k8"];
313
314 check_primitive<bool, BoolValue>(reporter, v, false, false);
315 check_primitive<float, NumberValue>(reporter, v, 0, false);
316
317 check_string(reporter, v, nullptr);
318 check_vector<ArrayValue >(reporter, v, 0, false);
319
320 check_vector<ObjectValue>(reporter, v, 3, true);
321
322 const auto& m0 = v.as<ObjectValue>().begin()[0];
323 check_string(reporter, m0.fKey, "kk1");
324 check_primitive<float, NumberValue>(reporter, m0.fValue, 2, true);
325
326 const auto& m1 = v.as<ObjectValue>().begin()[1];
327 check_string(reporter, m1.fKey, "kk2");
328 check_primitive<bool, BoolValue>(reporter, m1.fValue, false, true);
329
330 const auto& m2 = v.as<ObjectValue>().begin()[2];
331 check_string(reporter, m2.fKey, "kk1");
332 check_string(reporter, m2.fValue, "baz");
333
335 REPORTER_ASSERT(reporter, v.as<ObjectValue>()["nosuchkey"].is<NullValue>());
336 check_string(reporter, v.as<ObjectValue>()["kk1"], "baz");
337 check_primitive<bool, BoolValue>(reporter, v.as<ObjectValue>()["kk2"], false, true);
338 }
339}
static void check_string(skiatest::Reporter *reporter, const Value &v, const char *s)
Definition: JSONTest.cpp:184
static const char * begin(const StringSlice &s)
Definition: editor.cpp:252
Definition: dom.py:1

◆ DEF_TEST() [3/6]

DEF_TEST ( JSON_Lookup  ,
 
)

Definition at line 477 of file JSONTest.cpp.

477 {
478 const char* json = R"({"foo": { "bar": { "baz": 100 }}})";
479 const DOM dom(json, strlen(json));
480 const Value& root = dom.root();
481
483 REPORTER_ASSERT(r, root["foo"].is<ObjectValue>());
484 REPORTER_ASSERT(r, root["foo"]["bar"].is<ObjectValue>());
485 REPORTER_ASSERT(r, root["foo"]["bar"]["baz"].is<NumberValue>());
486
487 REPORTER_ASSERT(r, root["foozz"].is<NullValue>());
488 REPORTER_ASSERT(r, root["foozz"]["barzz"].is<NullValue>());
489 REPORTER_ASSERT(r, root["foozz"]["barzz"]["bazzz"].is<NullValue>());
490}
string root
Definition: scale_cpu.py:20

◆ DEF_TEST() [4/6]

DEF_TEST ( JSON_Parse  ,
reporter   
)

Definition at line 22 of file JSONTest.cpp.

22 {
23 static constexpr struct {
24 const char* in;
25 const char* out;
26 } g_tests[] = {
27 { "" , nullptr },
28 { "[" , nullptr },
29 { "]" , nullptr },
30 { "[[]" , nullptr },
31 { "[]]" , nullptr },
32 { "[]f" , nullptr },
33 { "{" , nullptr },
34 { "}" , nullptr },
35 { "{{}" , nullptr },
36 { "{}}" , nullptr },
37 { "{}f" , nullptr },
38 { "{]" , nullptr },
39 { "[}" , nullptr },
40 { "{\"}" , nullptr },
41 { "[\"]" , nullptr },
42 { "1" , nullptr },
43 { "true" , nullptr },
44 { "false", nullptr },
45 { "null" , nullptr },
46
47 { "[nulll]" , nullptr },
48 { "[false2]", nullptr },
49 { "[true:]" , nullptr },
50
51 { "[1 2]" , nullptr },
52 { "[1,,2]" , nullptr },
53 { "[1,2,]" , nullptr },
54 { "[,1,2]" , nullptr },
55
56 { "[ \"foo" , nullptr },
57 { "[ \"fo\0o\" ]" , nullptr },
58
59 { "{\"\":{}" , nullptr },
60 { "{ null }" , nullptr },
61 { "{ \"k\" : }" , nullptr },
62 { "{ : null }" , nullptr },
63 { "{ \"k\" : : null }" , nullptr },
64 { "{ \"k\" : null , }" , nullptr },
65 { "{ \"k\" : null \"k\" : 1 }", nullptr },
66
67 {R"zzz(["\)zzz" , nullptr},
68 {R"zzz(["\])zzz" , nullptr},
69 {R"zzz(["\"])zzz" , nullptr},
70 {R"zzz(["\z"])zzz" , nullptr},
71 {R"zzz(["\u"])zzz" , nullptr},
72 {R"zzz(["\u0"])zzz" , nullptr},
73 {R"zzz(["\u00"])zzz" , nullptr},
74 {R"zzz(["\u000"])zzz", nullptr},
75
76 { "[]" , "[]" },
77 { " \n\r\t [ \n\r\t ] \n\r\t " , "[]" },
78 { "[[]]" , "[[]]" },
79 { "[ null ]" , "[null]" },
80 { "[ true ]" , "[true]" },
81 { "[ false ]" , "[false]" },
82 { "[ 0 ]" , "[0]" },
83 { "[ 1 ]" , "[1]" },
84 { "[ 1.248 ]" , "[1.248]" },
85 { "[ \"\" ]" , "[\"\"]" },
86 { "[ \"foo{bar}baz\" ]" , "[\"foo{bar}baz\"]" },
87 { "[ \" f o o \" ]" , "[\" f o o \"]" },
88 { "[ \"123456\" ]" , "[\"123456\"]" },
89 { "[ \"1234567\" ]" , "[\"1234567\"]" },
90 { "[ \"12345678\" ]" , "[\"12345678\"]" },
91 { "[ \"123456789\" ]" , "[\"123456789\"]" },
92 { "[ null , true, false,0,12.8 ]", "[null,true,false,0,12.8]" },
93
94 { "{}" , "{}" },
95 { " \n\r\t { \n\r\t } \n\r\t " , "{}" },
96 { "{ \"k\" : null }" , "{\"k\":null}" },
97 { "{ \"foo{\" : \"bar}baz\" }" , "{\"foo{\":\"bar}baz\"}" },
98 { "{ \"k1\" : null, \"k2 \":0 }", "{\"k1\":null,\"k2 \":0}" },
99 { "{ \"k1\" : null, \"k1\":0 }" , "{\"k1\":null,\"k1\":0}" },
100
101 { "{ \"k1\" : null, \n\
102 \"k2\" : 0, \n\
103 \"k3\" : [ \n\
104 true, \r\n\
105 { \"kk1\" : \"foo\" , \n\
106 \"kk2\" : \"bar\" , \n\
107 \"kk3\" : 1.28 , \n\
108 \"kk4\" : [ 42 ] \n\
109 } , \n\
110 \"boo\" , \n\
111 null \n\
112 ] \n\
113 }",
114 "{\"k1\":null,\"k2\":0,\"k3\":[true,"
115 "{\"kk1\":\"foo\",\"kk2\":\"bar\",\"kk3\":1.28,\"kk4\":[42]},\"boo\",null]}" },
116
117 {R"zzz(["\""])zzz" , "[\"\"\"]"},
118 {R"zzz(["\\"])zzz" , "[\"\\\"]"},
119 {R"zzz(["\/"])zzz" , "[\"/\"]" },
120 {R"zzz(["\b"])zzz" , "[\"\b\"]"},
121 {R"zzz(["\f"])zzz" , "[\"\f\"]"},
122 {R"zzz(["\n"])zzz" , "[\"\n\"]"},
123 {R"zzz(["\r"])zzz" , "[\"\r\"]"},
124 {R"zzz(["\t"])zzz" , "[\"\t\"]"},
125 {R"zzz(["\u1234"])zzz", "[\"\u1234\"]"},
126
127 {R"zzz(["foo\"bar"])zzz" , "[\"foo\"bar\"]"},
128 {R"zzz(["foo\\bar"])zzz" , "[\"foo\\bar\"]"},
129 {R"zzz(["foo\/bar"])zzz" , "[\"foo/bar\"]" },
130 {R"zzz(["foo\bbar"])zzz" , "[\"foo\bbar\"]"},
131 {R"zzz(["foo\fbar"])zzz" , "[\"foo\fbar\"]"},
132 {R"zzz(["foo\nbar"])zzz" , "[\"foo\nbar\"]"},
133 {R"zzz(["foo\rbar"])zzz" , "[\"foo\rbar\"]"},
134 {R"zzz(["foo\tbar"])zzz" , "[\"foo\tbar\"]"},
135 {R"zzz(["foo\u1234bar"])zzz", "[\"foo\u1234bar\"]"},
136 };
137
138 for (const auto& tst : g_tests) {
139 DOM dom(tst.in, strlen(tst.in));
140 const auto success = !dom.root().is<NullValue>();
141 REPORTER_ASSERT(reporter, success == (tst.out != nullptr));
142 if (!success) continue;
143
145 dom.write(&str);
146 str.write8('\0');
147
148 auto data = str.detachAsData();
149 REPORTER_ASSERT(reporter, !strcmp(tst.out, static_cast<const char*>(data->data())));
150 }
151
152}
sk_sp< SkData > detachAsData()
Definition: SkStream.cpp:707
bool write8(U8CPU value)
Definition: SkStream.h:235
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ DEF_TEST() [5/6]

DEF_TEST ( JSON_ParseNumber  ,
reporter   
)

Definition at line 437 of file JSONTest.cpp.

437 {
438 static constexpr struct {
439 const char* string;
441 tolerance;
442 } gTests[] = {
443 { "0", 0, 0 },
444 { "1", 1, 0 },
445
446 { "00000000", 0, 0 },
447 { "00000001", 1, 0 },
448
449 { "0.001", 0.001f, 0 },
450 { "1.001", 1.001f, 0 },
451
452 { "0.000001" , 0.000001f, 0 },
453 { "1.000001" , 1.000001f, 0 },
454 { "1000.000001", 1000.000001f, 0 },
455
456 { "0.0000000001" , 0.0000000001f, 0 },
457 { "1.0000000001" , 1.0000000001f, 0 },
458 { "1000.0000000001", 1000.0000000001f, 0 },
459
460 { "20.001111814444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444473",
461 20.001f, 0.001f },
462 };
463
464 for (const auto& test : gTests) {
465 const auto json = SkStringPrintf("{ \"key\": %s }", test.string);
466 const DOM dom(json.c_str(), json.size());
467 const ObjectValue* jroot = dom.root();
468
470
471 const NumberValue* jnumber = (*jroot)["key"];
472 REPORTER_ASSERT(reporter, jnumber);
473 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(**jnumber, test.value, test.tolerance));
474 }
475}
static const TestCase gTests[]
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
float SkScalar
Definition: extension.cpp:12
uint8_t value

◆ DEF_TEST() [6/6]

DEF_TEST ( JSON_Writable  ,
 
)

Definition at line 492 of file JSONTest.cpp.

492 {
493 const char* json = R"({"null": null, "num": 100})";
494 const DOM dom(json, strlen(json));
495 REPORTER_ASSERT(r, dom.root().is<ObjectValue>());
496 const ObjectValue& root = dom.root().as<ObjectValue>();
497
498 SkArenaAlloc alloc(4096);
499
500 REPORTER_ASSERT(r, root["null"].is<NullValue>());
501 Value& w1 = root.writable("null", alloc);
502 REPORTER_ASSERT(r, w1.is<NullValue>());
503 w1 = NumberValue(42);
504 REPORTER_ASSERT(r, root["null"].is<NumberValue>());
505 REPORTER_ASSERT(r, *root["null"].as<NumberValue>() == 42);
506
507 REPORTER_ASSERT(r, root["num"].is<NumberValue>());
508 Value& w2 = root.writable("num", alloc);
510 w2 = StringValue("foo", 3, alloc);
511 REPORTER_ASSERT(r, root["num"].is<StringValue>());
512 REPORTER_ASSERT(r, root["num"].as<StringValue>().str() == "foo");
513
514 // new/insert semantics
515 REPORTER_ASSERT(r, root["new"].is<NullValue>());
516 REPORTER_ASSERT(r, root.size() == 2u);
517 Value& w3 = root.writable("new", alloc);
518 REPORTER_ASSERT(r, w3.is<NullValue>());
519 w3 = BoolValue(true);
520 REPORTER_ASSERT(r, root.size() == 3u);
521 REPORTER_ASSERT(r, root["new"].is<BoolValue>());
522 REPORTER_ASSERT(r, *root["new"].as<BoolValue>());
523
524 root.writable("newobj", alloc) = ObjectValue(nullptr, 0, alloc);
525 REPORTER_ASSERT(r, root.size() == 4u);
526 REPORTER_ASSERT(r, root["newobj"].is<ObjectValue>());
527 const ObjectValue& newobj = root["newobj"].as<ObjectValue>();
528 REPORTER_ASSERT(r, newobj.size() == 0u);
529
530 newobj.writable("newprop", alloc) = NumberValue(-1);
531 REPORTER_ASSERT(r, newobj.size() == 1u);
532 REPORTER_ASSERT(r, root["newobj"]["newprop"].is<NumberValue>());
533 REPORTER_ASSERT(r, *root["newobj"]["newprop"].as<NumberValue>() == -1);
534
535 REPORTER_ASSERT(r, root.toString() ==
536 SkString(R"({"null":42,"num":"foo","new":true,"newobj":{"newprop":-1}})"));
537}
Value & writable(const char *key, SkArenaAlloc &) const
Definition: SkJSON.cpp:244
size_t size() const
Definition: SkJSON.h:262