1// Copyright 2015 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-proxies 6 7// Check basic call to trap. 8 9var g_target, g_name, g_desc; 10var handler = { 11 defineProperty: function(target, name, desc) { 12 g_target = target; 13 g_name = name; 14 g_desc = desc; 15 return true; 16 } 17} 18var target = {} 19var proxy = new Proxy(target, handler); 20var desc = { value: 1, writable: true, configurable: true, enumerable: true }; 21Object.defineProperty(proxy, "foo", desc); 22assertSame(target, g_target); 23assertEquals("foo", g_name); 24assertEquals(desc, g_desc); 25 26// Check specific steps in the spec 27 28// Step 4: revoked handler 29var pair = Proxy.revocable(target, handler); 30Object.defineProperty(proxy, "foo2", desc); 31assertSame(target, g_target); 32assertEquals("foo2", g_name); 33assertEquals(desc, g_desc); 34pair.revoke(); 35assertThrows('Object.defineProperty(pair.proxy, "bar", desc);', TypeError); 36 37// Step 6: Trap isn't callable. 38handler.defineProperty = 1; 39assertThrows("Object.defineProperty(proxy, 'foo', {value: 2})", TypeError); 40 41// Step 7: Trap is undefined. 42handler.defineProperty = undefined; 43Object.defineProperty(proxy, "prop1", desc); 44assertEquals(desc, Object.getOwnPropertyDescriptor(target, "prop1")); 45var target2 = {}; 46var proxy2 = new Proxy(target2, {}); 47Object.defineProperty(proxy2, "prop2", desc); 48assertEquals(desc, Object.getOwnPropertyDescriptor(target2, "prop2")); 49 50// Step 9: Property name is passed to the trap as a string. 51handler.defineProperty = function(t, name, d) { g_name = name; return true; }; 52Object.defineProperty(proxy, 0, desc); 53assertTrue(typeof g_name === "string"); 54assertEquals("0", g_name); 55 56// Step 10: Trap returns false. 57handler.defineProperty = function(t, n, d) { return false; } 58assertThrows("Object.defineProperty(proxy, 'foo', desc)", TypeError); 59 60// Step 15a: Trap returns true for adding a property to a non-extensible target. 61handler.defineProperty = function(t, n, d) { return true; } 62Object.preventExtensions(target); 63assertThrows("Object.defineProperty(proxy, 'foo', desc)", TypeError); 64 65// Step 15b: Trap returns true for adding a non-configurable property. 66target = {}; 67proxy = new Proxy(target, handler); 68desc = {value: 1, writable: true, configurable: false, enumerable: true}; 69assertThrows("Object.defineProperty(proxy, 'foo', desc)", TypeError); 70// No exception is thrown if a non-configurable property exists on the target. 71Object.defineProperty(target, "nonconf", 72 {value: 1, writable: true, configurable: false}); 73Object.defineProperty(proxy, "nonconf", {value: 2, configurable: false}); 74 75// Step 16a: Trap returns true for non-compatible property descriptor. 76Object.defineProperty(target, "foo", 77 {value: 1, writable: false, configurable: false}); 78assertThrows("Object.defineProperty(proxy, 'foo', {value: 2})", TypeError); 79 80// Step 16b: Trap returns true for overwriting a configurable property 81// with a non-configurable descriptor. 82target.bar = "baz"; 83assertThrows("Object.defineProperty(proxy, 'bar', {configurable: false})", 84 TypeError); 85