mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-27 01:33:59 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			223 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2015 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.
 | |
| 
 | |
| // Flags: --allow-natives-syntax
 | |
| 
 | |
| (function testBasicFunctionality() {
 | |
|    var target = {
 | |
|      target_one: 1,
 | |
|      property: "value"
 | |
|    };
 | |
| 
 | |
|    var handler = {handler:1};
 | |
| 
 | |
|    var proxy = new Proxy(target, handler);
 | |
|    assertEquals("value", proxy.property);
 | |
|    assertEquals(undefined, proxy.nothing);
 | |
|    assertEquals(undefined, proxy.handler);
 | |
| 
 | |
|    handler.get = function() { return "value 2" };
 | |
|    assertEquals("value 2", proxy.property);
 | |
|    assertEquals("value 2", proxy.nothing);
 | |
|    assertEquals("value 2", proxy.handler);
 | |
| 
 | |
|    var handler2 = new Proxy({get: function() { return "value 3" }},{});
 | |
|    var proxy2 = new Proxy(target, handler2);
 | |
|    assertEquals("value 3", proxy2.property);
 | |
|    assertEquals("value 3", proxy2.nothing);
 | |
|    assertEquals("value 3", proxy2.handler);
 | |
| })();
 | |
| 
 | |
| (function testThrowOnGettingTrap() {
 | |
|   var handler = new Proxy({}, {get: function(){ throw Error() }});
 | |
|   var proxy = new Proxy({}, handler);
 | |
|   assertThrows("proxy.property", Error);
 | |
| })();
 | |
| 
 | |
| (function testThrowOnTrapNotCallable() {
 | |
|   var handler = new Proxy({}, {get: 'not_callable' });
 | |
|   var proxy = new Proxy({}, handler);
 | |
|   assertThrows("proxy.property", Error);
 | |
| })();
 | |
| 
 | |
| (function testFallback() {
 | |
|   var target = {property:"value"};
 | |
|   var proxy = new Proxy(target, {});
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertEquals(undefined, proxy.property2);
 | |
| })();
 | |
| 
 | |
| (function testFallbackUndefinedTrap() {
 | |
|   var handler = new Proxy({}, {get: function(){ return undefined }});
 | |
|   var target = {property:"value"};
 | |
|   var proxy = new Proxy(target, handler);
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertEquals(undefined, proxy.property2);
 | |
| })();
 | |
| 
 | |
| (function testFailingInvariant() {
 | |
|   var target = {};
 | |
|   var handler = { get: function(r, p){ if (p != "key4") return "value" }}
 | |
|   var proxy = new Proxy(target, handler);
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertEquals("value", proxy.key);
 | |
|   assertEquals("value", proxy.key2);
 | |
|   assertEquals("value", proxy.key3);
 | |
| 
 | |
|   // Define a non-configurable, non-writeable property on the target for
 | |
|   // which the handler will return a different value.
 | |
|   Object.defineProperty(target, "key", {
 | |
|     configurable: false,
 | |
|     writable: false,
 | |
|     value: "different value"
 | |
|   });
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertThrows(function(){ proxy.key }, TypeError);
 | |
|   assertEquals("value", proxy.key2);
 | |
|   assertEquals("value", proxy.key3);
 | |
| 
 | |
|   // Define a non-configurable getter on the target for which the handler
 | |
|   // will return a value, according to the spec we do not throw.
 | |
|   Object.defineProperty(target, "key2", {
 | |
|     configurable: false,
 | |
|     get: function() { return "different value" }
 | |
|   });
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertThrows(function(){ proxy.key }, TypeError);
 | |
|   assertEquals("value", proxy.key2);
 | |
|   assertEquals("value", proxy.key3);
 | |
| 
 | |
|   // Define a non-configurable setter without a corresponding getter on the
 | |
|   // target for which the handler will return a value.
 | |
|   Object.defineProperty(target, "key3", {
 | |
|     configurable: false,
 | |
|     set: function() { }
 | |
|   });
 | |
|   assertEquals("value", proxy.property);
 | |
|   assertThrows(function(){ proxy.key }, TypeError);
 | |
|   assertEquals("value", proxy.key2);
 | |
|   assertThrows(function(){ proxy.key3 }, TypeError);
 | |
| 
 | |
|   // Define a non-configurable setter without a corresponding getter on the
 | |
|   // target for which the handler will return undefined.
 | |
|   Object.defineProperty(target, "key4", {
 | |
|     configurable: false,
 | |
|     set: function() { }
 | |
|   });
 | |
|   assertSame(undefined, proxy.key4);
 | |
| })();
 | |
| 
 | |
| (function testGetInternalIterators() {
 | |
|   var log = [];
 | |
|   var array = [1,2,3,4,5]
 | |
|   var origIt = array[Symbol.iterator]();
 | |
|   var it = new Proxy(origIt, {
 | |
|     get(t, name) {
 | |
|       log.push(`[[Get]](iterator, ${String(name)})`);
 | |
|       return Reflect.get(t, name);
 | |
|     },
 | |
|     set(t, name, val) {
 | |
|       log.push(`[[Set]](iterator, ${String(name)}, ${String(val)})`);
 | |
|       return Reflect.set(t, name, val);
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   assertThrows(function() {
 | |
|     for (var v of it) log.push(v);
 | |
|   }, TypeError);
 | |
|   assertEquals([
 | |
|     "[[Get]](iterator, Symbol(Symbol.iterator))",
 | |
|     "[[Get]](iterator, next)"
 | |
|   ], log);
 | |
| })();
 | |
| 
 | |
| (function testGetterWithSideEffect() {
 | |
|   var obj = {
 | |
|     key: 0
 | |
|   }
 | |
|   assertEquals(obj.key, 0);
 | |
|   var p = new Proxy(obj, {});
 | |
|   var q = new Proxy(p, {
 | |
|     get(target, name) {
 | |
|       if (name != 'key') return Reflect.get(target, name);
 | |
|       target.key++;
 | |
|       return target.key;
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   assertEquals(0, p.key);
 | |
|   // Assert the trap is not called twice.
 | |
|   assertEquals(1, q.key);
 | |
| })();
 | |
| 
 | |
| (function testReceiverWithTrap() {
 | |
|   var obj = {};
 | |
|   var p = new Proxy(obj, {
 | |
|     get(target, name, receiver) {
 | |
|       if (name != 'key') return Reflect.get(target, name);
 | |
| 
 | |
|       assertSame(target, obj);
 | |
|       assertSame(receiver, p);
 | |
|       return 42;
 | |
|     }
 | |
|   });
 | |
|   assertEquals(42, p.key);
 | |
| })();
 | |
| 
 | |
| (function testReceiverWithoutTrap() {
 | |
|   var obj = {
 | |
|     get prop() {
 | |
|       assertSame(this, p);
 | |
|       return 42;
 | |
|     }
 | |
|   };
 | |
|   var p = new Proxy(obj, {});
 | |
|   assertEquals(42, p.prop);
 | |
| })();
 | |
| 
 | |
| (function testGetPropertyDetailsBailout() {
 | |
|   var obj = {
 | |
|   }
 | |
|   var p = new Proxy(obj, {
 | |
|     getOwnPropertyDescriptor() {
 | |
|       throw new Error('Error from proxy getOwnPropertyDescriptor trap');
 | |
|     }
 | |
|   });
 | |
|   var q = new Proxy(p, {
 | |
|     get(target, name) {
 | |
|       return 42;
 | |
|     }
 | |
|   });
 | |
|   assertThrows(function(){ q.prop }, Error,
 | |
|     'Error from proxy getOwnPropertyDescriptor trap');
 | |
| })();
 | |
| 
 | |
| (function testGetPropertyDetailsBailout2() {
 | |
|   var obj = {};
 | |
|   Object.defineProperty(obj, 'prop', {
 | |
|     value: 53,
 | |
|     configurable: false
 | |
|   });
 | |
|   var p = new Proxy(obj, {});
 | |
|   var q = new Proxy(p, {
 | |
|     get(target, name) {
 | |
|       return 42;
 | |
|     }
 | |
|   });
 | |
|   assertThrows(function(){ q.prop }, TypeError,
 | |
|     "'get' on proxy: property 'prop' is a read-only and non-configurable data" +
 | |
|     " property on the proxy target but the proxy did not return its actual" +
 | |
|     " value (expected '53' but got '42')");
 | |
| })();
 | |
| 
 | |
| (function test32BitIndex() {
 | |
|   var index = (1 << 31) + 1;
 | |
|   var obj = {};
 | |
|   obj[index] = 42;
 | |
|   var p = new Proxy(obj, {});
 | |
|   for (var i = 0; i < 3; ++i) {
 | |
|     assertEquals(42, p[index]);
 | |
|   }
 | |
| })();
 |