Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(789)

Side by Side Diff: test/mjsunit/harmony/proxies-json.js

Issue 1515133002: [proxies] Support proxies in JSON.parse and JSON.stringify. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/js/json.js ('k') | test/mjsunit/json.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // Flags: --harmony-proxies 28 // Flags: --harmony-proxies --harmony-reflect
29
30
31
32 ///////////////////////////////////////////////////////////////////////////////
33 // JSON.stringify
34
29 35
30 function testStringify(expected, object) { 36 function testStringify(expected, object) {
31 // Test fast case that bails out to slow case. 37 // Test fast case that bails out to slow case.
32 assertEquals(expected, JSON.stringify(object)); 38 assertEquals(expected, JSON.stringify(object));
33 // Test slow case. 39 // Test slow case.
34 assertEquals(expected, JSON.stringify(object, undefined, 0)); 40 assertEquals(expected, JSON.stringify(object, undefined, 0));
35 } 41 }
36 42
37 // Test serializing a proxy, function proxy and objects that contain them. 43
44 // Test serializing a proxy, a function proxy, and objects that contain them.
45
38 var handler1 = { 46 var handler1 = {
39 get: function(target, name) { 47 get: function(target, name) {
40 return name.toUpperCase(); 48 return name.toUpperCase();
41 }, 49 },
42 enumerate: function(target) { 50 ownKeys: function() {
43 return ['a', 'b', 'c']; 51 return ['a', 'b', 'c'];
44 }, 52 },
45 getOwnPropertyDescriptor: function(target, name) { 53 getOwnPropertyDescriptor: function() {
46 return { enumerable: true }; 54 return { enumerable: true, configurable: true };
47 } 55 }
48 } 56 }
49 57
50 var proxy1 = new Proxy({}, handler1); 58 var proxy1 = new Proxy({}, handler1);
51 testStringify('{"a":"A","b":"B","c":"C"}', proxy1); 59 testStringify('{"a":"A","b":"B","c":"C"}', proxy1);
52 60
53 var proxy_fun = Proxy.createFunction(handler1, function() { return 1; }); 61 var proxy_fun = new Proxy(() => {}, handler1);
62 assertTrue(typeof(proxy_fun) === 'function');
54 testStringify(undefined, proxy_fun); 63 testStringify(undefined, proxy_fun);
55 testStringify('[1,null]', [1, proxy_fun]); 64 testStringify('[1,null]', [1, proxy_fun]);
56 65
66 handler1.apply = function() { return 666; };
67 testStringify(undefined, proxy_fun);
68 testStringify('[1,null]', [1, proxy_fun]);
69
57 var parent1a = { b: proxy1 }; 70 var parent1a = { b: proxy1 };
58 testStringify('{"b":{"a":"A","b":"B","c":"C"}}', parent1a); 71 testStringify('{"b":{"a":"A","b":"B","c":"C"}}', parent1a);
59 72
60 var parent1b = { a: 123, b: proxy1, c: true }; 73 var parent1b = { a: 123, b: proxy1, c: true };
61 testStringify('{"a":123,"b":{"a":"A","b":"B","c":"C"},"c":true}', parent1b); 74 testStringify('{"a":123,"b":{"a":"A","b":"B","c":"C"},"c":true}', parent1b);
62 75
63 var parent1c = [123, proxy1, true]; 76 var parent1c = [123, proxy1, true];
64 testStringify('[123,{"a":"A","b":"B","c":"C"},true]', parent1c); 77 testStringify('[123,{"a":"A","b":"B","c":"C"},true]', parent1c);
65 78
79
66 // Proxy with side effect. 80 // Proxy with side effect.
81
67 var handler2 = { 82 var handler2 = {
68 get: function(target, name) { 83 get: function(target, name) {
69 delete parent2.c; 84 delete parent2.c;
70 return name.toUpperCase(); 85 return name.toUpperCase();
71 }, 86 },
72 enumerate: function(target) { 87 ownKeys: function() {
73 return ['a', 'b', 'c']; 88 return ['a', 'b', 'c'];
74 }, 89 },
75 getOwnPropertyDescriptor: function(target, name) { 90 getOwnPropertyDescriptor: function() {
76 return { enumerable: true }; 91 return { enumerable: true, configurable: true };
77 } 92 }
78 } 93 }
79 94
80 var proxy2 = new Proxy({}, handler2); 95 var proxy2 = new Proxy({}, handler2);
81 var parent2 = { a: "delete", b: proxy2, c: "remove" }; 96 var parent2 = { a: "delete", b: proxy2, c: "remove" };
82 var expected2 = '{"a":"delete","b":{"a":"A","b":"B","c":"C"}}'; 97 var expected2 = '{"a":"delete","b":{"a":"A","b":"B","c":"C"}}';
83 assertEquals(expected2, JSON.stringify(parent2)); 98 assertEquals(expected2, JSON.stringify(parent2));
84 parent2.c = "remove"; // Revert side effect. 99 parent2.c = "remove"; // Revert side effect.
85 assertEquals(expected2, JSON.stringify(parent2, undefined, 0)); 100 assertEquals(expected2, JSON.stringify(parent2, undefined, 0));
86 101
87 // Proxy with a get function that uses the first argument. 102
103 // Proxy with a get function that uses the receiver argument.
104
88 var handler3 = { 105 var handler3 = {
89 get: function(target, name) { 106 get: function(target, name, receiver) {
90 if (name == 'valueOf') return function() { return "proxy" }; 107 if (name == 'valueOf' || name === Symbol.toPrimitive) {
91 return name + "(" + target + ")"; 108 return function() { return "proxy" };
109 };
110 if (typeof name !== 'symbol') return name + "(" + receiver + ")";
92 }, 111 },
93 enumerate: function(target) { 112 ownKeys: function() {
94 return ['a', 'b', 'c']; 113 return ['a', 'b', 'c'];
95 }, 114 },
96 getOwnPropertyDescriptor: function(target, name) { 115 getOwnPropertyDescriptor: function() {
97 return { enumerable: true }; 116 return { enumerable: true, configurable: true };
98 } 117 }
99 } 118 }
100 119
101 var proxy3 = new Proxy({}, handler3); 120 var proxy3 = new Proxy({}, handler3);
102 var parent3 = { x: 123, y: proxy3 } 121 var parent3 = { x: 123, y: proxy3 }
103 testStringify('{"x":123,"y":{"a":"a(proxy)","b":"b(proxy)","c":"c(proxy)"}}', 122 testStringify('{"x":123,"y":{"a":"a(proxy)","b":"b(proxy)","c":"c(proxy)"}}',
104 parent3); 123 parent3);
105 124
125
106 // Empty proxy. 126 // Empty proxy.
127
107 var handler4 = { 128 var handler4 = {
108 get: function(target, name) { 129 get: function(target, name) {
109 return 0; 130 return 0;
110 }, 131 },
111 enumerate: function(target) { 132 enumerate: function(target) {
112 return []; 133 return [][Symbol.iterator]();
134 },
135 has: function() {
136 return true;
113 }, 137 },
114 getOwnPropertyDescriptor: function(target, name) { 138 getOwnPropertyDescriptor: function(target, name) {
115 return { enumerable: false }; 139 return { enumerable: false };
116 } 140 }
117 } 141 }
118 142
119 var proxy4 = new Proxy({}, handler4); 143 var proxy4 = new Proxy({}, handler4);
120 testStringify('{}', proxy4); 144 testStringify('{}', proxy4);
121 testStringify('{"a":{}}', { a: proxy4 }); 145 testStringify('{"a":{}}', { a: proxy4 });
122 146
147
123 // Proxy that provides a toJSON function that uses this. 148 // Proxy that provides a toJSON function that uses this.
149
124 var handler5 = { 150 var handler5 = {
125 get: function(target, name) { 151 get: function(target, name) {
126 if (name == 'z') return 97000; 152 if (name == 'z') return 97000;
127 return function(key) { return key.charCodeAt(0) + this.z; }; 153 return function(key) { return key.charCodeAt(0) + this.z; };
128 }, 154 },
129 enumerate: function(target) { 155 enumerate: function(target) {
130 return ['toJSON', 'z']; 156 return ['toJSON', 'z'][Symbol.iterator]();
157 },
158 has: function() {
159 return true;
131 }, 160 },
132 getOwnPropertyDescriptor: function(target, name) { 161 getOwnPropertyDescriptor: function(target, name) {
133 return { enumerable: true }; 162 return { enumerable: true };
134 } 163 }
135 } 164 }
136 165
137 var proxy5 = new Proxy({}, handler5); 166 var proxy5 = new Proxy({}, handler5);
138 testStringify('{"a":97097}', { a: proxy5 }); 167 testStringify('{"a":97097}', { a: proxy5 });
139 168
169
140 // Proxy that provides a toJSON function that returns undefined. 170 // Proxy that provides a toJSON function that returns undefined.
171
141 var handler6 = { 172 var handler6 = {
142 get: function(target, name) { 173 get: function(target, name) {
143 return function(key) { return undefined; }; 174 return function(key) { return undefined; };
144 }, 175 },
145 enumerate: function(target) { 176 enumerate: function(target) {
146 return ['toJSON']; 177 return ['toJSON'][Symbol.iterator]();
178 },
179 has: function() {
180 return true;
147 }, 181 },
148 getOwnPropertyDescriptor: function(target, name) { 182 getOwnPropertyDescriptor: function(target, name) {
149 return { enumerable: true }; 183 return { enumerable: true };
150 } 184 }
151 } 185 }
152 186
153 var proxy6 = new Proxy({}, handler6); 187 var proxy6 = new Proxy({}, handler6);
154 testStringify('[1,null,true]', [1, proxy6, true]); 188 testStringify('[1,null,true]', [1, proxy6, true]);
155 testStringify('{"a":1,"c":true}', {a: 1, b: proxy6, c: true}); 189 testStringify('{"a":1,"c":true}', {a: 1, b: proxy6, c: true});
156 190
191
157 // Object containing a proxy that changes the parent's properties. 192 // Object containing a proxy that changes the parent's properties.
193
158 var handler7 = { 194 var handler7 = {
159 get: function(target, name) { 195 get: function(target, name) {
160 delete parent7.a; 196 delete parent7.a;
161 delete parent7.c; 197 delete parent7.c;
162 parent7.e = "5"; 198 parent7.e = "5";
163 return name.toUpperCase(); 199 return name.toUpperCase();
164 }, 200 },
165 enumerate: function(target) { 201 ownKeys: function() {
166 return ['a', 'b', 'c']; 202 return ['a', 'b', 'c'];
167 }, 203 },
168 getOwnPropertyDescriptor: function(target, name) { 204 getOwnPropertyDescriptor: function() {
169 return { enumerable: true }; 205 return { enumerable: true, configurable: true };
170 } 206 }
171 } 207 }
172 208
173 var proxy7 = new Proxy({}, handler7); 209 var proxy7 = new Proxy({}, handler7);
174 var parent7 = { a: "1", b: proxy7, c: "3", d: "4" }; 210 var parent7 = { a: "1", b: proxy7, c: "3", d: "4" };
175 assertEquals('{"a":"1","b":{"a":"A","b":"B","c":"C"},"d":"4"}', 211 assertEquals('{"a":"1","b":{"a":"A","b":"B","c":"C"},"d":"4"}',
176 JSON.stringify(parent7)); 212 JSON.stringify(parent7));
177 assertEquals('{"b":{"a":"A","b":"B","c":"C"},"d":"4","e":"5"}', 213 assertEquals('{"b":{"a":"A","b":"B","c":"C"},"d":"4","e":"5"}',
178 JSON.stringify(parent7)); 214 JSON.stringify(parent7));
215
216
217 // (Proxy handler to log trap calls)
218
219 var log = [];
220 var logger = {};
221 var handler = new Proxy({}, logger);
222
223 logger.get = function(t, trap, r) {
224 return function() {
225 log.push([trap, ...arguments]);
226 return Reflect[trap](...arguments);
227 }
228 };
229
230
231 // Object is a callable proxy
232
233 log.length = 0;
234 var target = () => 42;
235 var proxy = new Proxy(target, handler);
236 assertTrue(typeof proxy === 'function');
237
238 assertEquals(undefined, JSON.stringify(proxy));
239 assertEquals(1, log.length)
240 for (var i in log) assertSame(target, log[i][1]);
241
242 assertEquals(["get", target, "toJSON", proxy], log[0]);
243
244
245 // Object is a non-callable non-arraylike proxy
246
247 log.length = 0;
248 var target = {foo: 42}
249 var proxy = new Proxy(target, handler);
250 assertFalse(Array.isArray(proxy));
251
252 assertEquals('{"foo":42}', JSON.stringify(proxy));
253 assertEquals(4, log.length)
254 for (var i in log) assertSame(target, log[i][1]);
255
256 assertEquals(
257 ["get", target, "toJSON", proxy], log[0]);
258 assertEquals(
259 ["ownKeys", target], log[1]); // EnumerableOwnNames
260 assertEquals(
261 ["getOwnPropertyDescriptor", target, "foo"], log[2]); // EnumerableOwnNames
262 assertEquals(
263 ["get", target, "foo", proxy], log[3]);
264
265
266 // Object is an arraylike proxy
267
268 log.length = 0;
269 var target = [42];
270 var proxy = new Proxy(target, handler);
271 assertTrue(Array.isArray(proxy));
272
273 assertEquals('[42]', JSON.stringify(proxy));
274 assertEquals(3, log.length)
275 for (var i in log) assertSame(target, log[i][1]);
276
277 assertEquals(["get", target, "toJSON", proxy], log[0]);
278 assertEquals(["get", target, "length", proxy], log[1]);
279 assertEquals(["get", target, "0", proxy], log[2]);
280
281
282 // Replacer is a callable proxy
283
284 log.length = 0;
285 var object = {0: "foo", 1: 666};
286 var target = (key, val) => key == "1" ? val + 42 : val;
287 var proxy = new Proxy(target, handler);
288 assertTrue(typeof proxy === 'function');
289
290 assertEquals('{"0":"foo","1":708}', JSON.stringify(object, proxy));
291 assertEquals(3, log.length)
292 for (var i in log) assertSame(target, log[i][1]);
293
294 assertEquals(4, log[0].length)
295 assertEquals("apply", log[0][0]);
296 assertEquals("", log[0][3][0]);
297 assertEquals({0: "foo", 1: 666}, log[0][3][1]);
298 assertEquals(4, log[1].length)
299 assertEquals("apply", log[1][0]);
300 assertEquals(["0", "foo"], log[1][3]);
301 assertEquals(4, log[2].length)
302 assertEquals("apply", log[2][0]);
303 assertEquals(["1", 666], log[2][3]);
304
305
306 // Replacer is an arraylike proxy
307
308 log.length = 0;
309 var object = {0: "foo", 1: 666};
310 var target = [0];
311 var proxy = new Proxy(target, handler);
312 assertTrue(Array.isArray(proxy));
313
314 assertEquals('{"0":"foo"}', JSON.stringify(object, proxy));
315 assertEquals(2, log.length)
316 for (var i in log) assertSame(target, log[i][1]);
317
318 assertEquals(["get", target, "length", proxy], log[0]);
319 assertEquals(["get", target, "0", proxy], log[1]);
320
321
322 // Replacer is an arraylike proxy and object is an array
323
324 log.length = 0;
325 var object = ["foo", 42];
326 var target = [0];
327 var proxy = new Proxy(target, handler);
328 assertTrue(Array.isArray(proxy));
329
330 assertEquals('["foo",42]', JSON.stringify(object, proxy));
331 assertEquals(2, log.length);
332 for (var i in log) assertSame(target, log[i][1]);
333
334 assertEquals(["get", target, "length", proxy], log[0]);
335 assertEquals(["get", target, "0", proxy], log[1]);
336
337
338 // Replacer is an arraylike proxy with a non-trivial length
339
340 var getTrap = function(t, key) {
341 if (key === "length") return {[Symbol.toPrimitive]() {return 42}};
342 if (key === "41") return "foo";
343 if (key === "42") return "bar";
344 };
345 var target = [];
346 var proxy = new Proxy(target, {get: getTrap});
347 assertTrue(Array.isArray(proxy));
348 var object = {foo: true, bar: 666};
349 assertEquals('{"foo":true}', JSON.stringify(object, proxy));
350
351
352 // Replacer is an arraylike proxy with a bogus length
353
354 var getTrap = function(t, key) {
355 if (key === "length") return Symbol();
356 if (key === "41") return "foo";
357 if (key === "42") return "bar";
358 };
359 var target = [];
360 var proxy = new Proxy(target, {get: getTrap});
361 assertTrue(Array.isArray(proxy));
362 var object = {foo: true, bar: 666};
363 assertThrows(() => JSON.stringify(object, proxy), TypeError);
364
365
366 // Replacer returns a non-callable non-arraylike proxy
367
368 log.length = 0;
369 var object = ["foo", 42];
370 var target = {baz: 5};
371 var proxy = new Proxy(target, handler);
372 var replacer = (key, val) => key === "1" ? proxy : val;
373
374 assertEquals('["foo",{"baz":5}]', JSON.stringify(object, replacer));
375 assertEquals(3, log.length);
376 for (var i in log) assertSame(target, log[i][1]);
377
378 assertEquals(["ownKeys", target], log[0]);
379 assertEquals(["getOwnPropertyDescriptor", target, "baz"], log[1]);
380
381
382 // Replacer returns an arraylike proxy
383
384 log.length = 0;
385 var object = ["foo", 42];
386 var target = ["bar"];
387 var proxy = new Proxy(target, handler);
388 var replacer = (key, val) => key === "1" ? proxy : val;
389
390 assertEquals('["foo",["bar"]]', JSON.stringify(object, replacer));
391 assertEquals(2, log.length);
392 for (var i in log) assertSame(target, log[i][1]);
393
394 assertEquals(["get", target, "length", proxy], log[0]);
395 assertEquals(["get", target, "0", proxy], log[1]);
396
397
398 // Replacer returns an arraylike proxy with a non-trivial length
399
400 var getTrap = function(t, key) {
401 if (key === "length") return {[Symbol.toPrimitive]() {return 3}};
402 if (key === "2") return "baz";
403 if (key === "3") return "bar";
404 };
405 var target = [];
406 var proxy = new Proxy(target, {get: getTrap});
407 var replacer = (key, val) => key === "goo" ? proxy : val;
408 var object = {foo: true, goo: false};
409 assertEquals('{"foo":true,"goo":[null,null,"baz"]}',
410 JSON.stringify(object, replacer));
411
412
413 // Replacer returns an arraylike proxy with a bogus length
414
415 var getTrap = function(t, key) {
416 if (key === "length") return Symbol();
417 if (key === "2") return "baz";
418 if (key === "3") return "bar";
419 };
420 var target = [];
421 var proxy = new Proxy(target, {get: getTrap});
422 var replacer = (key, val) => key === "goo" ? proxy : val;
423 var object = {foo: true, goo: false};
424 assertThrows(() => JSON.stringify(object, replacer));
425
426
427 // Replacer returns a callable proxy
428
429 log.length = 0;
430 var target = () => 666;
431 var proxy = new Proxy(target, handler);
432 var replacer = (key, val) => key === "1" ? proxy : val;
433
434 assertEquals('["foo",null]', JSON.stringify(["foo", 42], replacer));
435 assertEquals(0, log.length);
436
437 assertEquals('{"0":"foo"}', JSON.stringify({0: "foo", 1: 42}, replacer));
438 assertEquals(0, log.length);
439
440
441
442 ///////////////////////////////////////////////////////////////////////////////
443 // JSON.parse
444
445
446 // Reviver is a callable proxy
447
448 log.length = 0;
449 var target = () => 42;
450 var proxy = new Proxy(target, handler);
451 assertTrue(typeof proxy === "function");
452
453 assertEquals(42, JSON.parse("[true, false]", proxy));
454 assertEquals(3, log.length);
455 for (var i in log) assertSame(target, log[i][1]);
456
457 assertEquals(4, log[0].length);
458 assertEquals("apply", log[0][0]);
459 assertEquals(["0", true], log[0][3]);
460 assertEquals(4, log[1].length);
461 assertEquals("apply", log[1][0]);
462 assertEquals(["1", false], log[1][3]);
463 assertEquals(4, log[2].length);
464 assertEquals("apply", log[2][0]);
465 assertEquals(["", [42, 42]], log[2][3]);
466
467
468 // Reviver plants a non-arraylike proxy into a yet-to-be-visited property
469
470 log.length = 0;
471 var target = {baz: 42};
472 var proxy = new Proxy(target, handler);
473 var reviver = function(p, v) {
474 if (p === "baz") return 5;
475 if (p === "foo") this.bar = proxy;
476 return v;
477 }
478
479 assertEquals({foo: 0, bar: proxy}, JSON.parse('{"foo":0,"bar":1}', reviver));
480 assertEquals(4, log.length);
481 for (var i in log) assertSame(target, log[i][1]);
482
483 assertEquals(["ownKeys", target], log[0]);
484 assertEquals(["getOwnPropertyDescriptor", target, "baz"], log[1]);
485 assertEquals(["get", target, "baz", proxy], log[2]);
486 assertEquals(["defineProperty", target, "baz",
487 {value: 5, configurable: true, writable: true, enumerable: true}], log[3]);
488
489
490 // Reviver plants an arraylike proxy into a yet-to-be-visited property
491
492 log.length = 0;
493 var target = [42];
494 var proxy = new Proxy(target, handler);
495 assertTrue(Array.isArray(proxy));
496 var reviver = function(p, v) {
497 if (p === "0") return undefined;
498 if (p === "foo") this.bar = proxy;
499 return v;
500 }
501
502 var result = JSON.parse('{"foo":0,"bar":1}', reviver);
503 assertEquals({foo: 0, bar: proxy}, result);
504 assertSame(result.bar, proxy);
505 assertEquals(3, log.length);
506 for (var i in log) assertSame(target, log[i][1]);
507
508 assertEquals(["get", target, "length", proxy], log[0]);
509 assertEquals(["get", target, "0", proxy], log[1]);
510 assertEquals(["deleteProperty", target, "0"], log[2]);
OLDNEW
« no previous file with comments | « src/js/json.js ('k') | test/mjsunit/json.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698