1 | // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #include "platform/assert.h" |
6 | #include "platform/text_buffer.h" |
7 | #include "vm/dart_api_impl.h" |
8 | #include "vm/json_stream.h" |
9 | #include "vm/unit_test.h" |
10 | |
11 | namespace dart { |
12 | |
13 | #ifndef PRODUCT |
14 | |
15 | TEST_CASE(JSON_TextBuffer) { |
16 | TextBuffer w(5); // Small enough to make buffer grow at least once. |
17 | w.Printf("{ \"%s\" : %d" , "length" , 175); |
18 | EXPECT_STREQ("{ \"length\" : 175" , w.buffer()); |
19 | w.Printf(", \"%s\" : \"%s\" }" , "command" , "stopIt" ); |
20 | EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }" , w.buffer()); |
21 | } |
22 | |
23 | TEST_CASE(JSON_JSONStream_Primitives) { |
24 | { |
25 | JSONStream js; |
26 | { JSONObject jsobj(&js); } |
27 | EXPECT_STREQ("{}" , js.ToCString()); |
28 | } |
29 | { |
30 | JSONStream js; |
31 | { JSONArray jsarr(&js); } |
32 | EXPECT_STREQ("[]" , js.ToCString()); |
33 | } |
34 | { |
35 | JSONStream js; |
36 | { |
37 | JSONArray jsarr(&js); |
38 | jsarr.AddValue(true); |
39 | } |
40 | EXPECT_STREQ("[true]" , js.ToCString()); |
41 | } |
42 | { |
43 | JSONStream js; |
44 | { |
45 | JSONArray jsarr(&js); |
46 | jsarr.AddValue(false); |
47 | } |
48 | EXPECT_STREQ("[false]" , js.ToCString()); |
49 | } |
50 | { |
51 | JSONStream js; |
52 | { |
53 | JSONArray jsarr(&js); |
54 | jsarr.AddValue(static_cast<intptr_t>(4)); |
55 | } |
56 | EXPECT_STREQ("[4]" , js.ToCString()); |
57 | } |
58 | { |
59 | JSONStream js; |
60 | { |
61 | JSONArray jsarr(&js); |
62 | jsarr.AddValue(1.0); |
63 | } |
64 | EXPECT_STREQ("[1.0]" , js.ToCString()); |
65 | } |
66 | { |
67 | JSONStream js; |
68 | { |
69 | JSONArray jsarr(&js); |
70 | jsarr.AddValue("hello" ); |
71 | } |
72 | EXPECT_STREQ("[\"hello\"]" , js.ToCString()); |
73 | } |
74 | { |
75 | JSONStream js; |
76 | { |
77 | JSONArray jsarr(&js); |
78 | jsarr.AddValueF("h%s" , "elo" ); |
79 | } |
80 | EXPECT_STREQ("[\"helo\"]" , js.ToCString()); |
81 | } |
82 | } |
83 | |
84 | TEST_CASE(JSON_JSONStream_Array) { |
85 | JSONStream js; |
86 | { |
87 | JSONArray jsarr(&js); |
88 | jsarr.AddValue(true); |
89 | jsarr.AddValue(false); |
90 | } |
91 | EXPECT_STREQ("[true,false]" , js.ToCString()); |
92 | } |
93 | |
94 | TEST_CASE(JSON_JSONStream_Object) { |
95 | JSONStream js; |
96 | { |
97 | JSONObject jsobj(&js); |
98 | jsobj.AddProperty("key1" , "a" ); |
99 | jsobj.AddProperty("key2" , "b" ); |
100 | } |
101 | EXPECT_STREQ("{\"key1\":\"a\",\"key2\":\"b\"}" , js.ToCString()); |
102 | } |
103 | |
104 | TEST_CASE(JSON_JSONStream_NestedObject) { |
105 | JSONStream js; |
106 | { |
107 | JSONObject jsobj(&js); |
108 | JSONObject jsobj1(&jsobj, "key" ); |
109 | jsobj1.AddProperty("key1" , "d" ); |
110 | } |
111 | EXPECT_STREQ("{\"key\":{\"key1\":\"d\"}}" , js.ToCString()); |
112 | } |
113 | |
114 | TEST_CASE(JSON_JSONStream_ObjectArray) { |
115 | JSONStream js; |
116 | { |
117 | JSONArray jsarr(&js); |
118 | { |
119 | JSONObject jsobj(&jsarr); |
120 | jsobj.AddProperty("key" , "e" ); |
121 | } |
122 | { |
123 | JSONObject jsobj(&jsarr); |
124 | jsobj.AddProperty("yek" , "f" ); |
125 | } |
126 | } |
127 | EXPECT_STREQ("[{\"key\":\"e\"},{\"yek\":\"f\"}]" , js.ToCString()); |
128 | } |
129 | |
130 | TEST_CASE(JSON_JSONStream_ArrayArray) { |
131 | JSONStream js; |
132 | { |
133 | JSONArray jsarr(&js); |
134 | { |
135 | JSONArray jsarr1(&jsarr); |
136 | jsarr1.AddValue(static_cast<intptr_t>(4)); |
137 | } |
138 | { |
139 | JSONArray jsarr1(&jsarr); |
140 | jsarr1.AddValue(false); |
141 | } |
142 | } |
143 | EXPECT_STREQ("[[4],[false]]" , js.ToCString()); |
144 | } |
145 | |
146 | TEST_CASE(JSON_JSONStream_Printf) { |
147 | JSONStream js; |
148 | { |
149 | JSONArray jsarr(&js); |
150 | jsarr.AddValueF("%d %s" , 2, "hello" ); |
151 | } |
152 | EXPECT_STREQ("[\"2 hello\"]" , js.ToCString()); |
153 | } |
154 | |
155 | TEST_CASE(JSON_JSONStream_ObjectPrintf) { |
156 | JSONStream js; |
157 | { |
158 | JSONObject jsobj(&js); |
159 | jsobj.AddPropertyF("key" , "%d %s" , 2, "hello" ); |
160 | } |
161 | EXPECT_STREQ("{\"key\":\"2 hello\"}" , js.ToCString()); |
162 | } |
163 | |
164 | ISOLATE_UNIT_TEST_CASE(JSON_JSONStream_DartObject) { |
165 | JSONStream js; |
166 | { |
167 | JSONArray jsarr(&js); |
168 | jsarr.AddValue(Object::Handle(Object::null())); |
169 | JSONObject jsobj(&jsarr); |
170 | jsobj.AddProperty("object_key" , Object::Handle(Object::null())); |
171 | } |
172 | char buffer[1024]; |
173 | ElideJSONSubstring("classes" , js.ToCString(), buffer); |
174 | EXPECT_STREQ( |
175 | "[{\"type\":\"@Instance\"," |
176 | "\"_vmType\":\"null\"," |
177 | "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\"," |
178 | "\"name\":\"Null\"}," |
179 | "\"kind\":\"Null\"," |
180 | "\"fixedId\":true," |
181 | "\"id\":\"objects\\/null\"," |
182 | "\"valueAsString\":\"null\"}," |
183 | "{\"object_key\":" |
184 | "{\"type\":\"@Instance\"," |
185 | "\"_vmType\":\"null\"," |
186 | "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\"," |
187 | "\"name\":\"Null\"}," |
188 | "\"kind\":\"Null\"," |
189 | "\"fixedId\":true," |
190 | "\"id\":\"objects\\/null\"," |
191 | "\"valueAsString\":\"null\"}}]" , |
192 | buffer); |
193 | } |
194 | |
195 | TEST_CASE(JSON_JSONStream_EscapedString) { |
196 | JSONStream js; |
197 | { |
198 | JSONArray jsarr(&js); |
199 | jsarr.AddValue("Hel\"\"lo\r\n\t" ); |
200 | } |
201 | EXPECT_STREQ("[\"Hel\\\"\\\"lo\\r\\n\\t\"]" , js.ToCString()); |
202 | } |
203 | |
204 | TEST_CASE(JSON_JSONStream_DartString) { |
205 | const char* kScriptChars = |
206 | "var ascii = 'Hello, World!';\n" |
207 | "var unicode = '\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5\\u0163" |
208 | "\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E\\u00E5\\u0163" |
209 | "\\u00EE\\u1EDD\\u00F1';\n" |
210 | "var surrogates = '\\u{1D11E}\\u{1D11E}\\u{1D11E}" |
211 | "\\u{1D11E}\\u{1D11E}';\n" |
212 | "var wrongEncoding = '\\u{1D11E}' + surrogates[0] + '\\u{1D11E}';" |
213 | "var nullInMiddle = 'This has\\u0000 four words.';" ; |
214 | |
215 | Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
216 | EXPECT_VALID(lib); |
217 | |
218 | Dart_Handle result; |
219 | TransitionNativeToVM transition1(thread); |
220 | String& obj = String::Handle(); |
221 | |
222 | auto do_test = [&](const char* field_name, const char* expected) { |
223 | { |
224 | TransitionVMToNative to_native(thread); |
225 | result = Dart_GetField(lib, NewString(field_name)); |
226 | EXPECT_VALID(result); |
227 | } |
228 | |
229 | obj ^= Api::UnwrapHandle(result); |
230 | |
231 | { |
232 | JSONStream js; |
233 | { |
234 | JSONObject jsobj(&js); |
235 | EXPECT(!jsobj.AddPropertyStr(field_name, obj)); |
236 | } |
237 | EXPECT_STREQ(expected, js.ToCString()); |
238 | } |
239 | }; |
240 | |
241 | { |
242 | TransitionVMToNative to_native(thread); |
243 | result = Dart_GetField(lib, NewString("ascii" )); |
244 | EXPECT_VALID(result); |
245 | } |
246 | |
247 | obj ^= Api::UnwrapHandle(result); |
248 | |
249 | { |
250 | JSONStream js; |
251 | { |
252 | JSONObject jsobj(&js); |
253 | EXPECT(jsobj.AddPropertyStr("subrange" , obj, 1, 4)); |
254 | } |
255 | EXPECT_STREQ("{\"subrange\":\"ello\"}" , js.ToCString()); |
256 | } |
257 | |
258 | do_test("ascii" , "{\"ascii\":\"Hello, World!\"}" ); |
259 | do_test("unicode" , "{\"unicode\":\"Îñţérñåţîöñåļîžåţîờñ\"}" ); |
260 | do_test("surrogates" , "{\"surrogates\":\"𝄞𝄞𝄞𝄞𝄞\"}" ); |
261 | do_test("wrongEncoding" , "{\"wrongEncoding\":\"𝄞\\uD834𝄞\"}" ); |
262 | do_test("nullInMiddle" , "{\"nullInMiddle\":\"This has\\u0000 four words.\"}" ); |
263 | } |
264 | |
265 | TEST_CASE(JSON_JSONStream_Params) { |
266 | const char* param_keys[] = {"dog" , "cat" }; |
267 | const char* param_values[] = {"apple" , "banana" }; |
268 | |
269 | JSONStream js; |
270 | EXPECT(js.num_params() == 0); |
271 | js.SetParams(¶m_keys[0], ¶m_values[0], 2); |
272 | EXPECT(js.num_params() == 2); |
273 | EXPECT(!js.HasParam("lizard" )); |
274 | EXPECT(js.HasParam("dog" )); |
275 | EXPECT(js.HasParam("cat" )); |
276 | EXPECT(js.ParamIs("cat" , "banana" )); |
277 | EXPECT(!js.ParamIs("dog" , "banana" )); |
278 | } |
279 | |
280 | #endif // !PRODUCT |
281 | |
282 | } // namespace dart |
283 | |