// Copyright 2016 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: --harmony-object-own-property-descriptors // Flags: --allow-natives-syntax function DataDescriptor(value) { return { "enumerable": true, "configurable": true, "writable": true, value }; } function TestMeta() { assertEquals(1, Object.getOwnPropertyDescriptors.length); assertEquals(Function.prototype, Object.getPrototypeOf(Object.getOwnPropertyDescriptors)); assertEquals( 'getOwnPropertyDescriptors', Object.getOwnPropertyDescriptors.name); var desc = Reflect.getOwnPropertyDescriptor( Object, 'getOwnPropertyDescriptors'); assertFalse(desc.enumerable); assertTrue(desc.writable); assertTrue(desc.configurable); } TestMeta(); function TestToObject() { assertThrows(function() { Object.getOwnPropertyDescriptors(null); }, TypeError); assertThrows(function() { Object.getOwnPropertyDescriptors(undefined); }, TypeError); assertThrows(function() { Object.getOwnPropertyDescriptors(); }, TypeError); } TestToObject(); function TestPrototypeProperties() { function F() {}; F.prototype.a = "A"; F.prototype.b = "B"; var F2 = new F(); Object.defineProperties(F2, { "b": { enumerable: false, configurable: true, writable: false, value: "Shadowed 'B'" }, "c": { enumerable: false, configurable: true, writable: false, value: "C" } }); assertEquals({ "b": { enumerable: false, configurable: true, writable: false, value: "Shadowed 'B'" }, "c": { enumerable: false, configurable: true, writable: false, value: "C" } }, Object.getOwnPropertyDescriptors(F2)); } TestPrototypeProperties(); function TestPrototypeProperties() { function F() {}; F.prototype.a = "A"; F.prototype.b = "B"; var F2 = new F(); Object.defineProperties(F2, { "b": { enumerable: false, configurable: true, writable: false, value: "Shadowed 'B'" }, "c": { enumerable: false, configurable: true, writable: false, value: "C" } }); assertEquals({ "b": { enumerable: false, configurable: true, writable: false, value: "Shadowed 'B'" }, "c": { enumerable: false, configurable: true, writable: false, value: "C" } }, Object.getOwnPropertyDescriptors(F2)); } TestPrototypeProperties(); function TestTypeFilteringAndOrder() { var log = []; var sym = Symbol("foo"); var psym = %CreatePrivateSymbol("private"); var O = { 0: 0, [sym]: 3, "a": 2, [psym]: 4, 1: 1, }; var P = new Proxy(O, { ownKeys(target) { log.push("ownKeys()"); return Reflect.ownKeys(target); }, getOwnPropertyDescriptor(target, name) { log.push(`getOwnPropertyDescriptor(${String(name)})`); return Reflect.getOwnPropertyDescriptor(target, name); }, get(target, name) { assertUnreachable(); }, set(target, name, value) { assertUnreachable(); }, deleteProperty(target, name) { assertUnreachable(); }, defineProperty(target, name, desc) { assertUnreachable(); } }); var result1 = Object.getOwnPropertyDescriptors(O); assertEquals({ 0: DataDescriptor(0), 1: DataDescriptor(1), "a": DataDescriptor(2), [sym]: DataDescriptor(3) }, result1); var result2 = Object.getOwnPropertyDescriptors(P); assertEquals([ "ownKeys()", "getOwnPropertyDescriptor(0)", "getOwnPropertyDescriptor(1)", "getOwnPropertyDescriptor(a)", "getOwnPropertyDescriptor(Symbol(foo))" ], log); assertEquals({ 0: DataDescriptor(0), 1: DataDescriptor(1), "a": DataDescriptor(2), [sym]: DataDescriptor(3) }, result2); } TestTypeFilteringAndOrder(); function TestDuplicateKeys() { var i = 0; var log = []; var P = new Proxy({}, { ownKeys() { log.push(`ownKeys()`); return ["A", "A"]; }, getOwnPropertyDescriptor(t, name) { log.push(`getOwnPropertyDescriptor(${name})`); if (i++) return; return { configurable: true, writable: false, value: "VALUE" }; }, get(target, name) { assertUnreachable(); }, set(target, name, value) { assertUnreachable(); }, deleteProperty(target, name) { assertUnreachable(); }, defineProperty(target, name, desc) { assertUnreachable(); } }); var result = Object.getOwnPropertyDescriptors(P); assertEquals({ "A": { "value": "VALUE", "writable": false, "enumerable": false, "configurable": true } }, result); assertTrue(result.hasOwnProperty("A")); assertEquals([ "ownKeys()", "getOwnPropertyDescriptor(A)", "getOwnPropertyDescriptor(A)" ], log); } TestDuplicateKeys(); function TestFakeProperty() { var log = []; var P = new Proxy({}, { ownKeys() { log.push(`ownKeys()`); return ["fakeProperty"]; }, getOwnPropertyDescriptor(target, name) { log.push(`getOwnPropertyDescriptor(${name})`); return; } }); var result = Object.getOwnPropertyDescriptors(P); assertEquals({}, result); assertFalse(result.hasOwnProperty("fakeProperty")); assertEquals([ "ownKeys()", "getOwnPropertyDescriptor(fakeProperty)" ], log); } TestFakeProperty();