diff --git a/test/language/expressions/object/dstr/object-rest-proxy-get-not-called-on-dontenum-keys.js b/test/language/expressions/object/dstr/object-rest-proxy-get-not-called-on-dontenum-keys.js new file mode 100644 index 0000000000..cfb0df25ff --- /dev/null +++ b/test/language/expressions/object/dstr/object-rest-proxy-get-not-called-on-dontenum-keys.js @@ -0,0 +1,69 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-destructuring-binding-patterns-runtime-semantics-restbindinginitialization +description: > + Proxy's "get" trap is not invoked for non-enumerable keys. +info: | + BindingRestProperty : ... BindingIdentifier + + [...] + 3. Perform ? CopyDataProperties(restObj, value, excludedNames). + + CopyDataProperties ( target, source, excludedItems ) + + [...] + 5. Let keys be ? from.[[OwnPropertyKeys]](). + 6. For each element nextKey of keys in List order, do + [...] + c. If excluded is false, then + i. Let desc be ? from.[[GetOwnProperty]](nextKey). + ii. If desc is not undefined and desc.[[Enumerable]] is true, then + 1. Let propValue be ? Get(from, nextKey). + 2. Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue). + + [[OwnPropertyKeys]] ( ) + + [...] + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + [...] + 23. Return trapResult. +features: [object-rest, destructuring-binding, Proxy, Symbol] +includes: [compareArray.js, propertyHelper.js] +---*/ + +var VALUE_GOPD = "VALUE_GOPD"; +var VALUE_GET = "VALUE_GET"; + +var dontEnumSymbol = Symbol("dont_enum_symbol"); +var enumerableSymbol = Symbol("enumerable_symbol"); + +var dontEnumKeys = [dontEnumSymbol, "dontEnumString", "0"]; +var enumerableKeys = [enumerableSymbol, "enumerableString", "1"]; +var ownKeysResult = [...dontEnumKeys, ...enumerableKeys]; + +var getOwnKeys = []; +var getKeys = []; +var proxy = new Proxy({}, { + getOwnPropertyDescriptor: function(_target, key) { + getOwnKeys.push(key); + var isEnumerable = enumerableKeys.indexOf(key) !== -1; + return {value: VALUE_GOPD, writable: false, enumerable: isEnumerable, configurable: true}; + }, + get: function(_target, key) { + getKeys.push(key); + return VALUE_GET; + }, + ownKeys: function() { + return ownKeysResult; + }, +}); + +var {...rest} = proxy; +assert.compareArray(getOwnKeys, ownKeysResult); +assert.compareArray(getKeys, enumerableKeys); + +verifyProperty(rest, enumerableSymbol, {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); +verifyProperty(rest, "enumerableString", {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); +verifyProperty(rest, "1", {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); diff --git a/test/language/expressions/object/dstr/object-rest-proxy-gopd-not-called-on-excluded-keys.js b/test/language/expressions/object/dstr/object-rest-proxy-gopd-not-called-on-excluded-keys.js new file mode 100644 index 0000000000..a6149a3211 --- /dev/null +++ b/test/language/expressions/object/dstr/object-rest-proxy-gopd-not-called-on-excluded-keys.js @@ -0,0 +1,53 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-destructuring-binding-patterns-runtime-semantics-restbindinginitialization +description: > + Proxy's "getOwnPropertyDescriptor" trap is not invoked for excluded keys. +info: | + BindingRestProperty : ... BindingIdentifier + + [...] + 3. Perform ? CopyDataProperties(restObj, value, excludedNames). + + CopyDataProperties ( target, source, excludedItems ) + + [...] + 5. Let keys be ? from.[[OwnPropertyKeys]](). + 6. For each element nextKey of keys in List order, do + b. For each element e of excludedItems, do + i. If SameValue(e, nextKey) is true, then + 1. Set excluded to true. + c. If excluded is false, then + i. Let desc be ? from.[[GetOwnProperty]](nextKey). + + [[OwnPropertyKeys]] ( ) + + [...] + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + [...] + 23. Return trapResult. +features: [object-rest, destructuring-binding, Proxy, Symbol] +includes: [compareArray.js] +---*/ + +var excludedSymbol = Symbol("excluded_symbol"); +var includedSymbol = Symbol("included_symbol"); + +var excludedKeys = [excludedSymbol, "excludedString", "0"]; +var includedKeys = [includedSymbol, "includedString", "1"]; +var ownKeysResult = [...excludedKeys, ...includedKeys]; + +var getOwnKeys = []; +var proxy = new Proxy({}, { + getOwnPropertyDescriptor: function(_target, key) { + getOwnKeys.push(key); + }, + ownKeys: function() { + return ownKeysResult; + }, +}); + +var {[excludedSymbol]: _, excludedString, 0: excludedIndex, ...rest} = proxy; +assert.compareArray(getOwnKeys, includedKeys); diff --git a/test/language/expressions/object/object-spread-proxy-get-not-called-on-dontenum-keys.js b/test/language/expressions/object/object-spread-proxy-get-not-called-on-dontenum-keys.js new file mode 100644 index 0000000000..867d4b6acc --- /dev/null +++ b/test/language/expressions/object/object-spread-proxy-get-not-called-on-dontenum-keys.js @@ -0,0 +1,71 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-object-initializer-runtime-semantics-propertydefinitionevaluation +description: > + Proxy's "get" trap is not invoked for non-enumerable keys. +info: | + PropertyDefinition : ... AssignmentExpression + + [...] + 3. Let excludedNames be a new empty List. + 4. Return ? CopyDataProperties(object, fromValue, excludedNames). + + CopyDataProperties ( target, source, excludedItems ) + + [...] + 5. Let keys be ? from.[[OwnPropertyKeys]](). + 6. For each element nextKey of keys in List order, do + [...] + c. If excluded is false, then + i. Let desc be ? from.[[GetOwnProperty]](nextKey). + ii. If desc is not undefined and desc.[[Enumerable]] is true, then + 1. Let propValue be ? Get(from, nextKey). + 2. Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue). + + [[OwnPropertyKeys]] ( ) + + [...] + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + [...] + 23. Return trapResult. +features: [object-spread, Proxy, Symbol] +includes: [compareArray.js, propertyHelper.js] +---*/ + +var VALUE_LITERAL = "VALUE_LITERAL"; +var VALUE_GOPD = "VALUE_GOPD"; +var VALUE_GET = "VALUE_GET"; + +var dontEnumSymbol = Symbol("dont_enum_symbol"); +var enumerableSymbol = Symbol("enumerable_symbol"); + +var dontEnumKeys = [dontEnumSymbol, "dontEnumString", "0"]; +var enumerableKeys = [enumerableSymbol, "enumerableString", "1"]; +var ownKeysResult = [...dontEnumKeys, ...enumerableKeys]; + +var getOwnKeys = []; +var getKeys = []; +var proxy = new Proxy({}, { + getOwnPropertyDescriptor: function(_target, key) { + getOwnKeys.push(key); + var isEnumerable = enumerableKeys.indexOf(key) !== -1; + return {value: VALUE_GOPD, writable: false, enumerable: isEnumerable, configurable: true}; + }, + get: function(_target, key) { + getKeys.push(key); + return VALUE_GET; + }, + ownKeys: function() { + return ownKeysResult; + }, +}); + +var result = {[enumerableSymbol]: VALUE_LITERAL, enumerableString: VALUE_LITERAL, [1]: VALUE_LITERAL, ...proxy}; +assert.compareArray(getOwnKeys, ownKeysResult); +assert.compareArray(getKeys, enumerableKeys); + +verifyProperty(result, enumerableSymbol, {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); +verifyProperty(result, "enumerableString", {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); +verifyProperty(result, "1", {value: VALUE_GET, writable: true, enumerable: true, configurable: true}); diff --git a/test/language/expressions/object/object-spread-proxy-no-excluded-keys.js b/test/language/expressions/object/object-spread-proxy-no-excluded-keys.js new file mode 100644 index 0000000000..3ea6676f8c --- /dev/null +++ b/test/language/expressions/object/object-spread-proxy-no-excluded-keys.js @@ -0,0 +1,47 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-object-initializer-runtime-semantics-propertydefinitionevaluation +description: > + Proxy's "getOwnPropertyDescriptor" trap is invoked for all keys. +info: | + PropertyDefinition : ... AssignmentExpression + + [...] + 3. Let excludedNames be a new empty List. + 4. Return ? CopyDataProperties(object, fromValue, excludedNames). + + CopyDataProperties ( target, source, excludedItems ) + + [...] + 5. Let keys be ? from.[[OwnPropertyKeys]](). + 6. For each element nextKey of keys in List order, do + [...] + c. If excluded is false, then + i. Let desc be ? from.[[GetOwnProperty]](nextKey). + + [[OwnPropertyKeys]] ( ) + + [...] + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + [...] + 23. Return trapResult. +features: [object-spread, Proxy, Symbol] +includes: [compareArray.js] +---*/ + +var sym = Symbol(); +var getOwnKeys = []; +var ownKeysResult = [sym, "foo", "0"]; +var proxy = new Proxy({}, { + getOwnPropertyDescriptor: function(_target, key) { + getOwnKeys.push(key); + }, + ownKeys: function() { + return ownKeysResult; + }, +}); + +({[sym]: 0, foo: 0, [0]: 0, ...proxy}); +assert.compareArray(getOwnKeys, ownKeysResult); diff --git a/test/language/expressions/object/object-spread-proxy-ownkeys-returned-keys-order.js b/test/language/expressions/object/object-spread-proxy-ownkeys-returned-keys-order.js index c4c5f0a161..30de6c23f9 100644 --- a/test/language/expressions/object/object-spread-proxy-ownkeys-returned-keys-order.js +++ b/test/language/expressions/object/object-spread-proxy-ownkeys-returned-keys-order.js @@ -8,6 +8,7 @@ info: | PropertyDefinition : ... AssignmentExpression [...] + 3. Let excludedNames be a new empty List. 4. Return ? CopyDataProperties(object, fromValue, excludedNames). CopyDataProperties ( target, source, excludedItems )