mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 03:34:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			740 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			740 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2014 the V8 project authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| var global = this;
 | |
| var globalProto = Object.getPrototypeOf(global);
 | |
| 
 | |
| // Number of objects being tested. There is an assert ensuring this is correct.
 | |
| var objectCount = 21;
 | |
| 
 | |
| 
 | |
| function runTest(f) {
 | |
|   function restore(object, oldProto) {
 | |
|     delete object[Symbol.unscopables];
 | |
|     delete object.x;
 | |
|     delete object.x_;
 | |
|     delete object.y;
 | |
|     delete object.z;
 | |
|     Object.setPrototypeOf(object, oldProto);
 | |
|   }
 | |
| 
 | |
|   function getObject(i) {
 | |
|     var objects = [
 | |
|       {},
 | |
|       [],
 | |
|       function() {},
 | |
|       function() {
 | |
|         return arguments;
 | |
|       }(),
 | |
|       function() {
 | |
|         'use strict';
 | |
|         return arguments;
 | |
|       }(),
 | |
|       Object(1),
 | |
|       Object(true),
 | |
|       Object('bla'),
 | |
|       new Date,
 | |
|       new RegExp,
 | |
|       new Set,
 | |
|       new Map,
 | |
|       new WeakMap,
 | |
|       new WeakSet,
 | |
|       new ArrayBuffer(10),
 | |
|       new Int32Array(5),
 | |
|       Object,
 | |
|       Function,
 | |
|       Date,
 | |
|       RegExp,
 | |
|       global
 | |
|     ];
 | |
| 
 | |
|     assertEquals(objectCount, objects.length);
 | |
|     return objects[i];
 | |
|   }
 | |
| 
 | |
|   // Tests depends on this not being there to start with.
 | |
|   delete Array.prototype[Symbol.unscopables];
 | |
| 
 | |
|   if (f.length === 1) {
 | |
|     for (var i = 0; i < objectCount; i++) {
 | |
|       var object = getObject(i);
 | |
|       var oldObjectProto = Object.getPrototypeOf(object);
 | |
|       f(object);
 | |
|       restore(object, oldObjectProto);
 | |
|     }
 | |
|   } else {
 | |
|     for (var i = 0; i < objectCount; i++) {
 | |
|       for (var j = 0; j < objectCount; j++) {
 | |
|         var object = getObject(i);
 | |
|         var proto = getObject(j);
 | |
|         if (object === proto) {
 | |
|           continue;
 | |
|         }
 | |
|         var oldObjectProto = Object.getPrototypeOf(object);
 | |
|         var oldProtoProto = Object.getPrototypeOf(proto);
 | |
|         f(object, proto);
 | |
|         restore(object, oldObjectProto);
 | |
|         restore(proto, oldProtoProto);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Test array first, since other tests are changing
 | |
| // Array.prototype[Symbol.unscopables].
 | |
| function TestArrayPrototypeUnscopables() {
 | |
|   var descr = Object.getOwnPropertyDescriptor(Array.prototype,
 | |
|                                               Symbol.unscopables);
 | |
|   assertFalse(descr.enumerable);
 | |
|   assertFalse(descr.writable);
 | |
|   assertTrue(descr.configurable);
 | |
|   assertEquals(null, Object.getPrototypeOf(descr.value));
 | |
| 
 | |
|   var copyWithin = 'local copyWithin';
 | |
|   var entries = 'local entries';
 | |
|   var fill = 'local fill';
 | |
|   var find = 'local find';
 | |
|   var findIndex = 'local findIndex';
 | |
|   var flat = 'local flat';
 | |
|   var flatMap = 'local flatMap';
 | |
|   var keys = 'local keys';
 | |
|   var includes = 'local includes';
 | |
|   var values = 'local values';
 | |
| 
 | |
|   var array = [];
 | |
|   array.toString = 42;
 | |
| 
 | |
|   with (array) {
 | |
|     assertEquals('local copyWithin', copyWithin);
 | |
|     assertEquals('local entries', entries);
 | |
|     assertEquals('local fill', fill);
 | |
|     assertEquals('local find', find);
 | |
|     assertEquals('local findIndex', findIndex);
 | |
|     assertEquals('local flat', flat);
 | |
|     assertEquals('local flatMap', flatMap);
 | |
|     assertEquals('local includes', includes);
 | |
|     assertEquals('local keys', keys);
 | |
|     assertEquals('local values', values);
 | |
|     assertEquals(42, toString);
 | |
|   }
 | |
| }
 | |
| TestArrayPrototypeUnscopables();
 | |
| 
 | |
| 
 | |
| 
 | |
| function TestBasics(object) {
 | |
|   var x = 1;
 | |
|   var y = 2;
 | |
|   var z = 3;
 | |
|   object.x = 4;
 | |
|   object.y = 5;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(4, x);
 | |
|     assertEquals(5, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| 
 | |
|   var truthyValues = [true, 1, 'x', {}, Symbol()];
 | |
|   for (var truthyValue of truthyValues) {
 | |
|     object[Symbol.unscopables] = {x: truthyValue};
 | |
|     with (object) {
 | |
|       assertEquals(1, x);
 | |
|       assertEquals(5, y);
 | |
|       assertEquals(3, z);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   var falsyValues = [false, 0, -0, NaN, '', null, undefined];
 | |
|   for (var falsyValue of falsyValues) {
 | |
|     object[Symbol.unscopables] = {x: falsyValue, y: true};
 | |
|     with (object) {
 | |
|       assertEquals(4, x);
 | |
|       assertEquals(2, y);
 | |
|       assertEquals(3, z);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (var xFalsy of falsyValues) {
 | |
|     for (var yFalsy of falsyValues) {
 | |
|       object[Symbol.unscopables] = {x: xFalsy, y: yFalsy};
 | |
|       with (object) {
 | |
|         assertEquals(4, x);
 | |
|         assertEquals(5, y);
 | |
|         assertEquals(3, z);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| runTest(TestBasics);
 | |
| 
 | |
| 
 | |
| function TestUnscopableChain(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| 
 | |
|   object[Symbol.unscopables] = {
 | |
|     __proto__: {x: true}
 | |
|   };
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|   }
 | |
| 
 | |
|   object[Symbol.unscopables] = {
 | |
|     __proto__: {x: undefined}
 | |
|   };
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| }
 | |
| runTest(TestUnscopableChain);
 | |
| 
 | |
| 
 | |
| function TestBasicsSet(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| 
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|     x = 3;
 | |
|     assertEquals(3, x);
 | |
|   }
 | |
| 
 | |
|   assertEquals(3, x);
 | |
|   assertEquals(2, object.x);
 | |
| }
 | |
| runTest(TestBasicsSet);
 | |
| 
 | |
| 
 | |
| function TestOnProto(object, proto) {
 | |
|   var x = 1;
 | |
|   var y = 2;
 | |
|   var z = 3;
 | |
|   proto.x = 4;
 | |
| 
 | |
|   Object.setPrototypeOf(object, proto);
 | |
|   object.y = 5;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(4, x);
 | |
|     assertEquals(5, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| 
 | |
|   proto[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|     assertEquals(5, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| 
 | |
|   object[Symbol.unscopables] = {y: true};
 | |
|   with (object) {
 | |
|     assertEquals(4, x);
 | |
|     assertEquals(2, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| 
 | |
|   proto[Symbol.unscopables] = {y: true};
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|     assertEquals(5, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| 
 | |
|   proto[Symbol.unscopables] = {y: true};
 | |
|   object[Symbol.unscopables] = {x: true, y: undefined};
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|     assertEquals(5, y);
 | |
|     assertEquals(3, z);
 | |
|   }
 | |
| }
 | |
| runTest(TestOnProto);
 | |
| 
 | |
| 
 | |
| function TestSetBlockedOnProto(object, proto) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| 
 | |
|   Object.setPrototypeOf(object, proto);
 | |
|   proto[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     assertEquals(1, x);
 | |
|     x = 3;
 | |
|     assertEquals(3, x);
 | |
|   }
 | |
| 
 | |
|   assertEquals(3, x);
 | |
|   assertEquals(2, object.x);
 | |
| }
 | |
| runTest(TestSetBlockedOnProto);
 | |
| 
 | |
| 
 | |
| function TestNonObject(object) {
 | |
|   var x = 1;
 | |
|   var y = 2;
 | |
|   object.x = 3;
 | |
|   object.y = 4;
 | |
| 
 | |
|   object[Symbol.unscopables] = 'xy';
 | |
|   with (object) {
 | |
|     assertEquals(3, x);
 | |
|     assertEquals(4, y);
 | |
|   }
 | |
| 
 | |
|   object[Symbol.unscopables] = null;
 | |
|   with (object) {
 | |
|     assertEquals(3, x);
 | |
|     assertEquals(4, y);
 | |
|   }
 | |
| }
 | |
| runTest(TestNonObject);
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWith(object) {
 | |
|   var x = 1;
 | |
|   var y = 2;
 | |
|   object.x = 3;
 | |
|   object.y = 4;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(3, x);
 | |
|     assertEquals(4, y);
 | |
|     object[Symbol.unscopables] = {x: true};
 | |
|     assertEquals(1, x);
 | |
|     assertEquals(4, y);
 | |
|   }
 | |
| }
 | |
| runTest(TestChangeDuringWith);
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWithWithPossibleOptimization(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
|   with (object) {
 | |
|     for (var i = 0; i < 1000; i++) {
 | |
|       if (i === 500) object[Symbol.unscopables] = {x: true};
 | |
|       assertEquals(i < 500 ? 2: 1, x);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| TestChangeDuringWithWithPossibleOptimization({});
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWithWithPossibleOptimization2(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     for (var i = 0; i < 1000; i++) {
 | |
|       if (i === 500) delete object[Symbol.unscopables];
 | |
|       assertEquals(i < 500 ? 1 : 2, x);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| TestChangeDuringWithWithPossibleOptimization2({});
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWithWithPossibleOptimization3(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
|   object[Symbol.unscopables] = {};
 | |
|   with (object) {
 | |
|     for (var i = 0; i < 1000; i++) {
 | |
|       if (i === 500) object[Symbol.unscopables].x = true;
 | |
|       assertEquals(i < 500 ? 2 : 1, x);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| TestChangeDuringWithWithPossibleOptimization3({});
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWithWithPossibleOptimization4(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     for (var i = 0; i < 1000; i++) {
 | |
|       if (i === 500) delete object[Symbol.unscopables].x;
 | |
|       assertEquals(i < 500 ? 1 : 2, x);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| TestChangeDuringWithWithPossibleOptimization4({});
 | |
| 
 | |
| 
 | |
| function TestChangeDuringWithWithPossibleOptimization4(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
|   with (object) {
 | |
|     for (var i = 0; i < 1000; i++) {
 | |
|       if (i === 500) object[Symbol.unscopables].x = undefined;
 | |
|       assertEquals(i < 500 ? 1 : 2, x);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| TestChangeDuringWithWithPossibleOptimization4({});
 | |
| 
 | |
| 
 | |
| function TestAccessorReceiver(object, proto) {
 | |
|   var x = 'local';
 | |
| 
 | |
|   Object.defineProperty(proto, 'x', {
 | |
|     get: function() {
 | |
|       assertEquals(object, this);
 | |
|       return this.x_;
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   proto.x_ = 'proto';
 | |
| 
 | |
|   Object.setPrototypeOf(object, proto);
 | |
|   proto.x_ = 'object';
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals('object', x);
 | |
|   }
 | |
| }
 | |
| runTest(TestAccessorReceiver);
 | |
| 
 | |
| 
 | |
| function TestUnscopablesGetter(object) {
 | |
|   // This test gets really messy when object is the global since the assert
 | |
|   // functions are properties on the global object and the call count gets
 | |
|   // completely different.
 | |
|   if (object === global) return;
 | |
| 
 | |
|   var x = 'local';
 | |
|   object.x = 'object';
 | |
| 
 | |
|   var callCount = 0;
 | |
|   Object.defineProperty(object, Symbol.unscopables, {
 | |
|     get: function() {
 | |
|       callCount++;
 | |
|       return {};
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   with (object) {
 | |
|     assertEquals('object', x);
 | |
|   }
 | |
|   // Once for HasBinding
 | |
|   assertEquals(1, callCount);
 | |
| 
 | |
|   callCount = 0;
 | |
|   Object.defineProperty(object, Symbol.unscopables, {
 | |
|     get: function() {
 | |
|       callCount++;
 | |
|       return {x: true};
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   with (object) {
 | |
|     assertEquals('local', x);
 | |
|   }
 | |
|   // Once for HasBinding
 | |
|   assertEquals(1, callCount);
 | |
| 
 | |
|   callCount = 0;
 | |
|   Object.defineProperty(object, Symbol.unscopables, {
 | |
|     get: function() {
 | |
|       callCount++;
 | |
|       return callCount == 1 ? {} : {x: true};
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   with (object) {
 | |
|     x = 1;
 | |
|   }
 | |
|   // Once for HasBinding
 | |
|   assertEquals(1, callCount);
 | |
|   assertEquals(1, object.x);
 | |
|   assertEquals('local', x);
 | |
|   with (object) {
 | |
|     x = 2;
 | |
|   }
 | |
|   // One more HasBinding.
 | |
|   assertEquals(2, callCount);
 | |
|   assertEquals(1, object.x);
 | |
|   assertEquals(2, x);
 | |
| }
 | |
| runTest(TestUnscopablesGetter);
 | |
| 
 | |
| 
 | |
| var global = this;
 | |
| function TestUnscopablesGetter2() {
 | |
|   var x = 'local';
 | |
| 
 | |
|   var globalProto = Object.getPrototypeOf(global);
 | |
|   var protos = [{}, [], function() {}, global];
 | |
|   var objects = [{}, [], function() {}];
 | |
| 
 | |
|   protos.forEach(function(proto) {
 | |
|     objects.forEach(function(object) {
 | |
|       Object.defineProperty(proto, 'x', {
 | |
|         get: function() {
 | |
|           assertEquals(object, this);
 | |
|           return 'proto';
 | |
|         },
 | |
|         configurable: true
 | |
|       });
 | |
| 
 | |
|       object.__proto__ = proto;
 | |
|       Object.defineProperty(object, 'x', {
 | |
|         get: function() {
 | |
|           assertEquals(object, this);
 | |
|           return 'object';
 | |
|         },
 | |
|         configurable: true
 | |
|       });
 | |
| 
 | |
|       with (object) {
 | |
|         assertEquals('object', x);
 | |
|       }
 | |
| 
 | |
|       object[Symbol.unscopables] = {x: true};
 | |
|       with (object) {
 | |
|         assertEquals('local', x);
 | |
|       }
 | |
| 
 | |
|       delete proto[Symbol.unscopables];
 | |
|       delete object[Symbol.unscopables];
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   delete global.x;
 | |
|   Object.setPrototypeOf(global, globalProto);
 | |
| }
 | |
| TestUnscopablesGetter2();
 | |
| 
 | |
| 
 | |
| function TestSetterOnBlacklisted(object, proto) {
 | |
|   var x = 'local';
 | |
|   Object.defineProperty(proto, 'x', {
 | |
|     set: function(x) {
 | |
|       assertUnreachable();
 | |
|     },
 | |
|     get: function() {
 | |
|       return 'proto';
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.setPrototypeOf(object, proto);
 | |
|   Object.defineProperty(object, 'x', {
 | |
|     get: function() {
 | |
|       return this.x_;
 | |
|     },
 | |
|     set: function(x) {
 | |
|       this.x_ = x;
 | |
|     },
 | |
|     configurable: true
 | |
|   });
 | |
|   object.x_ = 1;
 | |
| 
 | |
|   with (object) {
 | |
|     x = 2;
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| 
 | |
|   assertEquals(2, object.x);
 | |
| 
 | |
|   object[Symbol.unscopables] = {x: true};
 | |
| 
 | |
|   with (object) {
 | |
|     x = 3;
 | |
|     assertEquals(3, x);
 | |
|   }
 | |
| 
 | |
|   assertEquals(2, object.x);
 | |
| }
 | |
| runTest(TestSetterOnBlacklisted);
 | |
| 
 | |
| 
 | |
| function TestObjectsAsUnscopables(object, unscopables) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|     object[Symbol.unscopables] = unscopables;
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
| }
 | |
| runTest(TestObjectsAsUnscopables);
 | |
| 
 | |
| 
 | |
| function TestAccessorOnUnscopables(object) {
 | |
|   var x = 1;
 | |
|   object.x = 2;
 | |
| 
 | |
|   var calls = 0;
 | |
|   var unscopables = {
 | |
|     get x() {
 | |
|       calls++;
 | |
|       return calls === 1 ? true : undefined;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   with (object) {
 | |
|     assertEquals(2, x);
 | |
|     object[Symbol.unscopables] = unscopables;
 | |
|     assertEquals(1, x);
 | |
|     assertEquals(2, x);
 | |
|   }
 | |
|   assertEquals(2, calls);
 | |
| }
 | |
| runTest(TestAccessorOnUnscopables);
 | |
| 
 | |
| 
 | |
| function TestLengthUnscopables(object, proto) {
 | |
|   var length = 2;
 | |
|   with (object) {
 | |
|     assertEquals(1, length);
 | |
|     object[Symbol.unscopables] = {length: true};
 | |
|     assertEquals(2, length);
 | |
|     delete object[Symbol.unscopables];
 | |
|     assertEquals(1, length);
 | |
|   }
 | |
| }
 | |
| TestLengthUnscopables([1], Array.prototype);
 | |
| TestLengthUnscopables(function(x) {}, Function.prototype);
 | |
| TestLengthUnscopables(new String('x'), String.prototype);
 | |
| 
 | |
| 
 | |
| function TestFunctionNameUnscopables(object) {
 | |
|   var name = 'local';
 | |
|   with (object) {
 | |
|     assertEquals('f', name);
 | |
|     object[Symbol.unscopables] = {name: true};
 | |
|     assertEquals('local', name);
 | |
|     delete object[Symbol.unscopables];
 | |
|     assertEquals('f', name);
 | |
|   }
 | |
| }
 | |
| TestFunctionNameUnscopables(function f() {});
 | |
| 
 | |
| 
 | |
| function TestFunctionPrototypeUnscopables() {
 | |
|   var prototype = 'local';
 | |
|   var f = function() {};
 | |
|   var g = function() {};
 | |
|   Object.setPrototypeOf(f, g);
 | |
|   var fp = f.prototype;
 | |
|   var gp = g.prototype;
 | |
|   with (f) {
 | |
|     assertEquals(fp, prototype);
 | |
|     f[Symbol.unscopables] = {prototype: true};
 | |
|     assertEquals('local', prototype);
 | |
|     delete f[Symbol.unscopables];
 | |
|     assertEquals(fp, prototype);
 | |
|   }
 | |
| }
 | |
| TestFunctionPrototypeUnscopables(function() {});
 | |
| 
 | |
| 
 | |
| function TestFunctionArgumentsUnscopables() {
 | |
|   var func = function() {
 | |
|     var arguments = 'local';
 | |
|     var args = func.arguments;
 | |
|     with (func) {
 | |
|       assertEquals(args, arguments);
 | |
|       func[Symbol.unscopables] = {arguments: true};
 | |
|       assertEquals('local', arguments);
 | |
|       delete func[Symbol.unscopables];
 | |
|       assertEquals(args, arguments);
 | |
|     }
 | |
|   }
 | |
|   func(1);
 | |
| }
 | |
| TestFunctionArgumentsUnscopables();
 | |
| 
 | |
| 
 | |
| function TestArgumentsLengthUnscopables() {
 | |
|   var func = function() {
 | |
|     var length = 'local';
 | |
|     with (arguments) {
 | |
|       assertEquals(1, length);
 | |
|       arguments[Symbol.unscopables] = {length: true};
 | |
|       assertEquals('local', length);
 | |
|     }
 | |
|   }
 | |
|   func(1);
 | |
| }
 | |
| TestArgumentsLengthUnscopables();
 | |
| 
 | |
| 
 | |
| function TestFunctionCallerUnscopables() {
 | |
|   var func = function() {
 | |
|     var caller = 'local';
 | |
|     with (func) {
 | |
|       assertEquals(TestFunctionCallerUnscopables, caller);
 | |
|       func[Symbol.unscopables] = {caller: true};
 | |
|       assertEquals('local', caller);
 | |
|       delete func[Symbol.unscopables];
 | |
|       assertEquals(TestFunctionCallerUnscopables, caller);
 | |
|     }
 | |
|   }
 | |
|   func(1);
 | |
| }
 | |
| TestFunctionCallerUnscopables();
 | |
| 
 | |
| 
 | |
| function TestGetUnscopablesGetterThrows() {
 | |
|   var object = {
 | |
|     get x() {
 | |
|       assertUnreachable();
 | |
|     }
 | |
|   };
 | |
|   function CustomError() {}
 | |
|   Object.defineProperty(object, Symbol.unscopables, {
 | |
|     get: function() {
 | |
|       throw new CustomError();
 | |
|     }
 | |
|   });
 | |
|   assertThrows(function() {
 | |
|     with (object) {
 | |
|       x;
 | |
|     }
 | |
|   }, CustomError);
 | |
| }
 | |
| TestGetUnscopablesGetterThrows();
 | |
| 
 | |
| 
 | |
| function TestGetUnscopablesGetterThrows2() {
 | |
|   var object = {
 | |
|     get x() {
 | |
|       assertUnreachable();
 | |
|     }
 | |
|   };
 | |
|   function CustomError() {}
 | |
| 
 | |
|   object[Symbol.unscopables] = {
 | |
|     get x() {
 | |
|       throw new CustomError();
 | |
|     }
 | |
|   };
 | |
|   assertThrows(function() {
 | |
|     with (object) {
 | |
|       x;
 | |
|     }
 | |
|   }, CustomError);
 | |
| }
 | |
| TestGetUnscopablesGetterThrows();
 |