Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / es6 / unscopables.js
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --harmony-unscopables
6 // Flags: --harmony-collections
7
8 var global = this;
9 var globalProto = Object.getPrototypeOf(global);
10
11 // Number of objects being tested. There is an assert ensuring this is correct.
12 var objectCount = 21;
13
14
15 function runTest(f) {
16   function restore(object, oldProto) {
17     delete object[Symbol.unscopables];
18     delete object.x;
19     delete object.x_;
20     delete object.y;
21     delete object.z;
22     Object.setPrototypeOf(object, oldProto);
23   }
24
25   function getObject(i) {
26     var objects = [
27       {},
28       [],
29       function() {},
30       function() {
31         return arguments;
32       }(),
33       function() {
34         'use strict';
35         return arguments;
36       }(),
37       Object(1),
38       Object(true),
39       Object('bla'),
40       new Date,
41       new RegExp,
42       new Set,
43       new Map,
44       new WeakMap,
45       new WeakSet,
46       new ArrayBuffer(10),
47       new Int32Array(5),
48       Object,
49       Function,
50       Date,
51       RegExp,
52       global
53     ];
54
55     assertEquals(objectCount, objects.length);
56     return objects[i];
57   }
58
59   // Tests depends on this not being there to start with.
60   delete Array.prototype[Symbol.unscopables];
61
62   if (f.length === 1) {
63     for (var i = 0; i < objectCount; i++) {
64       var object = getObject(i);
65       var oldObjectProto = Object.getPrototypeOf(object);
66       f(object);
67       restore(object, oldObjectProto);
68     }
69   } else {
70     for (var i = 0; i < objectCount; i++) {
71       for (var j = 0; j < objectCount; j++) {
72         var object = getObject(i);
73         var proto = getObject(j);
74         if (object === proto) {
75           continue;
76         }
77         var oldObjectProto = Object.getPrototypeOf(object);
78         var oldProtoProto = Object.getPrototypeOf(proto);
79         f(object, proto);
80         restore(object, oldObjectProto);
81         restore(proto, oldProtoProto);
82       }
83     }
84   }
85 }
86
87 // Test array first, since other tests are changing
88 // Array.prototype[Symbol.unscopables].
89 function TestArrayPrototypeUnscopables() {
90   var descr = Object.getOwnPropertyDescriptor(Array.prototype,
91                                               Symbol.unscopables);
92   assertFalse(descr.enumerable);
93   assertFalse(descr.writable);
94   assertTrue(descr.configurable);
95   assertEquals(null, Object.getPrototypeOf(descr.value));
96
97   var copyWithin = 'local copyWithin';
98   var entries = 'local entries';
99   var fill = 'local fill';
100   var find = 'local find';
101   var findIndex = 'local findIndex';
102   var keys = 'local keys';
103   var values = 'local values';
104
105   var array = [];
106   array.toString = 42;
107
108   with (array) {
109     assertEquals('local copyWithin', copyWithin);
110     assertEquals('local entries', entries);
111     assertEquals('local fill', fill);
112     assertEquals('local find', find);
113     assertEquals('local findIndex', findIndex);
114     assertEquals('local keys', keys);
115     assertEquals('local values', values);
116     assertEquals(42, toString);
117   }
118 }
119 TestArrayPrototypeUnscopables();
120
121
122
123 function TestBasics(object) {
124   var x = 1;
125   var y = 2;
126   var z = 3;
127   object.x = 4;
128   object.y = 5;
129
130   with (object) {
131     assertEquals(4, x);
132     assertEquals(5, y);
133     assertEquals(3, z);
134   }
135
136   object[Symbol.unscopables] = {x: true};
137   with (object) {
138     assertEquals(1, x);
139     assertEquals(5, y);
140     assertEquals(3, z);
141   }
142
143   object[Symbol.unscopables] = {x: 0, y: true};
144   with (object) {
145     assertEquals(1, x);
146     assertEquals(2, y);
147     assertEquals(3, z);
148   }
149 }
150 runTest(TestBasics);
151
152
153 function TestUnscopableChain(object) {
154   var x = 1;
155   object.x = 2;
156
157   with (object) {
158     assertEquals(2, x);
159   }
160
161   object[Symbol.unscopables] = {
162     __proto__: {x: true}
163   };
164   with (object) {
165     assertEquals(1, x);
166   }
167 }
168 runTest(TestUnscopableChain);
169
170
171 function TestBasicsSet(object) {
172   var x = 1;
173   object.x = 2;
174
175   with (object) {
176     assertEquals(2, x);
177   }
178
179   object[Symbol.unscopables] = {x: true};
180   with (object) {
181     assertEquals(1, x);
182     x = 3;
183     assertEquals(3, x);
184   }
185
186   assertEquals(3, x);
187   assertEquals(2, object.x);
188 }
189 runTest(TestBasicsSet);
190
191
192 function TestOnProto(object, proto) {
193   var x = 1;
194   var y = 2;
195   var z = 3;
196   proto.x = 4;
197
198   Object.setPrototypeOf(object, proto);
199   object.y = 5;
200
201   with (object) {
202     assertEquals(4, x);
203     assertEquals(5, y);
204     assertEquals(3, z);
205   }
206
207   proto[Symbol.unscopables] = {x: true};
208   with (object) {
209     assertEquals(1, x);
210     assertEquals(5, y);
211     assertEquals(3, z);
212   }
213
214   object[Symbol.unscopables] = {y: true};
215   with (object) {
216     assertEquals(4, x);
217     assertEquals(2, y);
218     assertEquals(3, z);
219   }
220
221   proto[Symbol.unscopables] = {y: true};
222   object[Symbol.unscopables] = {x: true};
223   with (object) {
224     assertEquals(1, x);
225     assertEquals(5, y);
226     assertEquals(3, z);
227   }
228 }
229 runTest(TestOnProto);
230
231
232 function TestSetBlockedOnProto(object, proto) {
233   var x = 1;
234   object.x = 2;
235
236   with (object) {
237     assertEquals(2, x);
238   }
239
240   Object.setPrototypeOf(object, proto);
241   proto[Symbol.unscopables] = {x: true};
242   with (object) {
243     assertEquals(1, x);
244     x = 3;
245     assertEquals(3, x);
246   }
247
248   assertEquals(3, x);
249   assertEquals(2, object.x);
250 }
251 runTest(TestSetBlockedOnProto);
252
253
254 function TestNonObject(object) {
255   var x = 1;
256   var y = 2;
257   object.x = 3;
258   object.y = 4;
259
260   object[Symbol.unscopables] = 'xy';
261   with (object) {
262     assertEquals(3, x);
263     assertEquals(4, y);
264   }
265
266   object[Symbol.unscopables] = null;
267   with (object) {
268     assertEquals(3, x);
269     assertEquals(4, y);
270   }
271 }
272 runTest(TestNonObject);
273
274
275 function TestChangeDuringWith(object) {
276   var x = 1;
277   var y = 2;
278   object.x = 3;
279   object.y = 4;
280
281   with (object) {
282     assertEquals(3, x);
283     assertEquals(4, y);
284     object[Symbol.unscopables] = {x: true};
285     assertEquals(1, x);
286     assertEquals(4, y);
287   }
288 }
289 runTest(TestChangeDuringWith);
290
291
292 function TestChangeDuringWithWithPossibleOptimization(object) {
293   var x = 1;
294   object.x = 2;
295   with (object) {
296     for (var i = 0; i < 1000; i++) {
297       if (i === 500) object[Symbol.unscopables] = {x: true};
298       assertEquals(i < 500 ? 2: 1, x);
299     }
300   }
301 }
302 TestChangeDuringWithWithPossibleOptimization({});
303
304
305 function TestChangeDuringWithWithPossibleOptimization2(object) {
306   var x = 1;
307   object.x = 2;
308   object[Symbol.unscopables] = {x: true};
309   with (object) {
310     for (var i = 0; i < 1000; i++) {
311       if (i === 500) delete object[Symbol.unscopables];
312       assertEquals(i < 500 ? 1 : 2, x);
313     }
314   }
315 }
316 TestChangeDuringWithWithPossibleOptimization2({});
317
318
319 function TestChangeDuringWithWithPossibleOptimization3(object) {
320   var x = 1;
321   object.x = 2;
322   object[Symbol.unscopables] = {};
323   with (object) {
324     for (var i = 0; i < 1000; i++) {
325       if (i === 500) object[Symbol.unscopables].x = true;
326       assertEquals(i < 500 ? 2 : 1, x);
327     }
328   }
329 }
330 TestChangeDuringWithWithPossibleOptimization3({});
331
332
333 function TestChangeDuringWithWithPossibleOptimization4(object) {
334   var x = 1;
335   object.x = 2;
336   object[Symbol.unscopables] = {x: true};
337   with (object) {
338     for (var i = 0; i < 1000; i++) {
339       if (i === 500) delete object[Symbol.unscopables].x;
340       assertEquals(i < 500 ? 1 : 2, x);
341     }
342   }
343 }
344 TestChangeDuringWithWithPossibleOptimization4({});
345
346
347 function TestAccessorReceiver(object, proto) {
348   var x = 'local';
349
350   Object.defineProperty(proto, 'x', {
351     get: function() {
352       assertEquals(object, this);
353       return this.x_;
354     },
355     configurable: true
356   });
357   proto.x_ = 'proto';
358
359   Object.setPrototypeOf(object, proto);
360   proto.x_ = 'object';
361
362   with (object) {
363     assertEquals('object', x);
364   }
365 }
366 runTest(TestAccessorReceiver);
367
368
369 function TestUnscopablesGetter(object) {
370   // This test gets really messy when object is the global since the assert
371   // functions are properties on the global object and the call count gets
372   // completely different.
373   if (object === global) return;
374
375   var x = 'local';
376   object.x = 'object';
377
378   var callCount = 0;
379   Object.defineProperty(object, Symbol.unscopables, {
380     get: function() {
381       callCount++;
382       return {};
383     },
384     configurable: true
385   });
386   with (object) {
387     assertEquals('object', x);
388   }
389   // Once for HasBinding
390   assertEquals(1, callCount);
391
392   callCount = 0;
393   Object.defineProperty(object, Symbol.unscopables, {
394     get: function() {
395       callCount++;
396       return {x: true};
397     },
398     configurable: true
399   });
400   with (object) {
401     assertEquals('local', x);
402   }
403   // Once for HasBinding
404   assertEquals(1, callCount);
405
406   callCount = 0;
407   Object.defineProperty(object, Symbol.unscopables, {
408     get: function() {
409       callCount++;
410       return callCount == 1 ? {} : {x: true};
411     },
412     configurable: true
413   });
414   with (object) {
415     x = 1;
416   }
417   // Once for HasBinding
418   assertEquals(1, callCount);
419   assertEquals(1, object.x);
420   assertEquals('local', x);
421   with (object) {
422     x = 2;
423   }
424   // One more HasBinding.
425   assertEquals(2, callCount);
426   assertEquals(1, object.x);
427   assertEquals(2, x);
428 }
429 runTest(TestUnscopablesGetter);
430
431
432 var global = this;
433 function TestUnscopablesGetter2() {
434   var x = 'local';
435
436   var globalProto = Object.getPrototypeOf(global);
437   var protos = [{}, [], function() {}, global];
438   var objects = [{}, [], function() {}];
439
440   protos.forEach(function(proto) {
441     objects.forEach(function(object) {
442       Object.defineProperty(proto, 'x', {
443         get: function() {
444           assertEquals(object, this);
445           return 'proto';
446         },
447         configurable: true
448       });
449
450       object.__proto__ = proto;
451       Object.defineProperty(object, 'x', {
452         get: function() {
453           assertEquals(object, this);
454           return 'object';
455         },
456         configurable: true
457       });
458
459       with (object) {
460         assertEquals('object', x);
461       }
462
463       object[Symbol.unscopables] = {x: true};
464       with (object) {
465         assertEquals('local', x);
466       }
467
468       delete proto[Symbol.unscopables];
469       delete object[Symbol.unscopables];
470     });
471   });
472
473   delete global.x;
474   Object.setPrototypeOf(global, globalProto);
475 }
476 TestUnscopablesGetter2();
477
478
479 function TestSetterOnBlacklisted(object, proto) {
480   var x = 'local';
481   Object.defineProperty(proto, 'x', {
482     set: function(x) {
483       assertUnreachable();
484     },
485     get: function() {
486       return 'proto';
487     },
488     configurable: true
489   });
490   Object.setPrototypeOf(object, proto);
491   Object.defineProperty(object, 'x', {
492     get: function() {
493       return this.x_;
494     },
495     set: function(x) {
496       this.x_ = x;
497     },
498     configurable: true
499   });
500   object.x_ = 1;
501
502   with (object) {
503     x = 2;
504     assertEquals(2, x);
505   }
506
507   assertEquals(2, object.x);
508
509   object[Symbol.unscopables] = {x: true};
510
511   with (object) {
512     x = 3;
513     assertEquals(3, x);
514   }
515
516   assertEquals(2, object.x);
517 }
518 runTest(TestSetterOnBlacklisted);
519
520
521 function TestObjectsAsUnscopables(object, unscopables) {
522   var x = 1;
523   object.x = 2;
524
525   with (object) {
526     assertEquals(2, x);
527     object[Symbol.unscopables] = unscopables;
528     assertEquals(2, x);
529   }
530 }
531 runTest(TestObjectsAsUnscopables);
532
533
534 function TestAccessorOnUnscopables(object) {
535   var x = 1;
536   object.x = 2;
537
538   var unscopables = {
539     get x() {
540       assertUnreachable();
541     }
542   };
543
544   with (object) {
545     assertEquals(2, x);
546     object[Symbol.unscopables] = unscopables;
547     assertEquals(1, x);
548   }
549 }
550 runTest(TestAccessorOnUnscopables);
551
552
553 function TestLengthUnscopables(object, proto) {
554   var length = 2;
555   with (object) {
556     assertEquals(1, length);
557     object[Symbol.unscopables] = {length: true};
558     assertEquals(2, length);
559     delete object[Symbol.unscopables];
560     assertEquals(1, length);
561   }
562 }
563 TestLengthUnscopables([1], Array.prototype);
564 TestLengthUnscopables(function(x) {}, Function.prototype);
565 TestLengthUnscopables(new String('x'), String.prototype);
566
567
568 function TestFunctionNameUnscopables(object) {
569   var name = 'local';
570   with (object) {
571     assertEquals('f', name);
572     object[Symbol.unscopables] = {name: true};
573     assertEquals('local', name);
574     delete object[Symbol.unscopables];
575     assertEquals('f', name);
576   }
577 }
578 TestFunctionNameUnscopables(function f() {});
579
580
581 function TestFunctionPrototypeUnscopables() {
582   var prototype = 'local';
583   var f = function() {};
584   var g = function() {};
585   Object.setPrototypeOf(f, g);
586   var fp = f.prototype;
587   var gp = g.prototype;
588   with (f) {
589     assertEquals(fp, prototype);
590     f[Symbol.unscopables] = {prototype: true};
591     assertEquals('local', prototype);
592     delete f[Symbol.unscopables];
593     assertEquals(fp, prototype);
594   }
595 }
596 TestFunctionPrototypeUnscopables(function() {});
597
598
599 function TestFunctionArgumentsUnscopables() {
600   var func = function() {
601     var arguments = 'local';
602     var args = func.arguments;
603     with (func) {
604       assertEquals(args, arguments);
605       func[Symbol.unscopables] = {arguments: true};
606       assertEquals('local', arguments);
607       delete func[Symbol.unscopables];
608       assertEquals(args, arguments);
609     }
610   }
611   func(1);
612 }
613 TestFunctionArgumentsUnscopables();
614
615
616 function TestArgumentsLengthUnscopables() {
617   var func = function() {
618     var length = 'local';
619     with (arguments) {
620       assertEquals(1, length);
621       arguments[Symbol.unscopables] = {length: true};
622       assertEquals('local', length);
623     }
624   }
625   func(1);
626 }
627 TestArgumentsLengthUnscopables();
628
629
630 function TestFunctionCallerUnscopables() {
631   var func = function() {
632     var caller = 'local';
633     with (func) {
634       assertEquals(TestFunctionCallerUnscopables, caller);
635       func[Symbol.unscopables] = {caller: true};
636       assertEquals('local', caller);
637       delete func[Symbol.unscopables];
638       assertEquals(TestFunctionCallerUnscopables, caller);
639     }
640   }
641   func(1);
642 }
643 TestFunctionCallerUnscopables();
644
645
646 function TestGetUnscopablesGetterThrows() {
647   var object = {
648     get x() {
649       assertUnreachable();
650     }
651   };
652   function CustomError() {}
653   Object.defineProperty(object, Symbol.unscopables, {
654     get: function() {
655       throw new CustomError();
656     }
657   });
658   assertThrows(function() {
659     with (object) {
660       x;
661     }
662   }, CustomError);
663 }
664 TestGetUnscopablesGetterThrows();