| // 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: --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(); |