Add some more Proxy/ownKeys invariants tests (#2413)

* Defer making [[ProxyTarget]] non-extensible

* Fix typo in method name

* Add last Object.keys with Proxy invariant test

* Add Object.getOwnPropertySymbols with Proxy invariants tests

* Add Object.getOwnPropertyNames with Proxy invariants tests

* Replace "es6id" with "esid" in Object.getOwnPropertySymbols tests
This commit is contained in:
Alexey Shvayka 2019-11-11 22:02:07 +02:00 committed by Leo Balter
parent 600245fcd3
commit da9612db98
15 changed files with 440 additions and 8 deletions

View File

@ -0,0 +1,54 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertynames
description: >
Proxy [[OwnPropertyKeys]] trap does not skip symbol keys when validating invariant:
* The result List must contain the keys of all non-configurable own properties of
the target object.
info: |
Object.getOwnPropertyNames ( O )
1. Return ? GetOwnPropertyKeys(O, String).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
...
15. Let targetNonconfigurableKeys be a new empty List.
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
i. Append key as an element of targetNonconfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
19. For each key that is an element of targetNonconfigurableKeys, do
a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
features: [Proxy, Symbol]
---*/
var target = {};
var symbol = Symbol();
Object.defineProperty(target, symbol, {
value: 1,
writable: true,
enumerable: true,
configurable: false,
});
var proxy = new Proxy(target, {
ownKeys: function() {
return [];
},
});
assert.throws(TypeError, function() {
Object.getOwnPropertyNames(proxy);
});

View File

@ -0,0 +1,36 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertynames
description: >
Proxy [[OwnPropertyKeys]] trap does not skip symbol keys when validating invariant:
* The returned List contains no duplicate entries.
info: |
Object.getOwnPropertyNames ( O )
1. Return ? GetOwnPropertyKeys(O, String).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
9. If trapResult contains any duplicate entries, throw a TypeError exception.
features: [Proxy, Symbol]
---*/
var symbol = Symbol();
var proxy = new Proxy({}, {
ownKeys: function() {
return [symbol, symbol];
},
});
assert.throws(TypeError, function() {
Object.getOwnPropertyNames(proxy);
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertynames
description: >
Proxy [[OwnPropertyKeys]] trap does not skip symbol keys when validating invariant:
* If the target object is not extensible, then the result List must contain all the keys of
the own properties of the target object and no other values.
info: |
Object.getOwnPropertyNames ( O )
1. Return ? GetOwnPropertyKeys(O, String).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
...
c. Else,
i. Append key as an element of targetConfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
...
21. For each key that is an element of targetConfigurableKeys, do
a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
features: [Proxy, Symbol]
---*/
var target = {};
var symbol = Symbol();
target[symbol] = 2;
var proxy = new Proxy(target, {
ownKeys: function() {
return [];
},
});
Object.preventExtensions(target);
assert.throws(TypeError, function() {
Object.getOwnPropertyNames(proxy);
});

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertynames
description: >
Proxy [[OwnPropertyKeys]] trap does not skip symbol keys when validating invariant:
* If the target object is not extensible, then the result List must contain all the keys of
the own properties of the target object and no other values.
info: |
Object.getOwnPropertyNames ( O )
1. Return ? GetOwnPropertyKeys(O, String).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
...
c. Else,
i. Append key as an element of targetConfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
...
22. If uncheckedResultKeys is not empty, throw a TypeError exception.
features: [Proxy, Symbol]
---*/
var target = {};
var symbol = Symbol();
var proxy = new Proxy(target, {
ownKeys: function() {
return [symbol];
},
});
Object.preventExtensions(target);
assert.throws(TypeError, function() {
Object.getOwnPropertyNames(proxy);
});

View File

@ -2,7 +2,7 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 19.1.2.8
esid: sec-object.getownpropertysymbols
description: >
Object.getOwnPropertySymbols.length is 1.
info: |

View File

@ -2,7 +2,7 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 19.1.2.8
esid: sec-object.getownpropertysymbols
description: >
Object.getOwnPropertySymbols.name is "getOwnPropertySymbols".
info: |

View File

@ -1,7 +1,7 @@
// Copyright (C) 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 19.1.2.8
esid: sec-object.getownpropertysymbols
description: >
Object.getOwnPropertySymbols returns all symbol properties that have descriptions
features: [Symbol]

View File

@ -1,7 +1,7 @@
// Copyright (C) 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 19.1.2.8
esid: sec-object.getownpropertysymbols
description: >
Object.getOwnPropertySymbols returns all symbol properties that do not have descriptions
features: [Symbol]

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertysymbols
description: >
Proxy [[OwnPropertyKeys]] trap does not skip string keys when validating invariant:
* The result List must contain the keys of all non-configurable own properties of
the target object.
info: |
Object.getOwnPropertySymbols ( O )
1. Return ? GetOwnPropertyKeys(O, Symbol).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
...
15. Let targetNonconfigurableKeys be a new empty List.
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
i. Append key as an element of targetNonconfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
19. For each key that is an element of targetNonconfigurableKeys, do
a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
features: [Proxy]
---*/
var target = {};
Object.defineProperty(target, 'prop', {
value: 1,
writable: true,
enumerable: true,
configurable: false,
});
var proxy = new Proxy(target, {
ownKeys: function() {
return [];
},
});
assert.throws(TypeError, function() {
Object.getOwnPropertySymbols(proxy);
});

View File

@ -0,0 +1,35 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertysymbols
description: >
Proxy [[OwnPropertyKeys]] trap does not skip string keys when validating invariant:
* The returned List contains no duplicate entries.
info: |
Object.getOwnPropertySymbols ( O )
1. Return ? GetOwnPropertyKeys(O, Symbol).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
9. If trapResult contains any duplicate entries, throw a TypeError exception.
features: [Proxy]
---*/
var proxy = new Proxy({}, {
ownKeys: function() {
return ['a', 'a'];
},
});
assert.throws(TypeError, function() {
Object.getOwnPropertySymbols(proxy);
});

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertysymbols
description: >
Proxy [[OwnPropertyKeys]] trap does not skip string keys when validating invariant:
* If the target object is not extensible, then the result List must contain all the keys of
the own properties of the target object and no other values.
info: |
Object.getOwnPropertySymbols ( O )
1. Return ? GetOwnPropertyKeys(O, Symbol).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
...
c. Else,
i. Append key as an element of targetConfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
...
21. For each key that is an element of targetConfigurableKeys, do
a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
features: [Proxy]
---*/
var target = {prop: 2};
var proxy = new Proxy(target, {
ownKeys: function() {
return [];
},
});
Object.preventExtensions(target);
assert.throws(TypeError, function() {
Object.getOwnPropertySymbols(proxy);
});

View File

@ -0,0 +1,48 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.getownpropertysymbols
description: >
Proxy [[OwnPropertyKeys]] trap does not skip string keys when validating invariant:
* If the target object is not extensible, then the result List must contain all the keys of
the own properties of the target object and no other values.
info: |
Object.getOwnPropertySymbols ( O )
1. Return ? GetOwnPropertyKeys(O, Symbol).
GetOwnPropertyKeys ( O, type )
...
2. Let keys be ? obj.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
...
c. Else,
i. Append key as an element of targetConfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
...
22. If uncheckedResultKeys is not empty, throw a TypeError exception.
features: [Proxy]
---*/
var target = {};
var proxy = new Proxy(target, {
ownKeys: function() {
return ['prop'];
},
});
Object.preventExtensions(target);
assert.throws(TypeError, function() {
Object.getOwnPropertySymbols(proxy);
});

View File

@ -43,7 +43,6 @@ Object.defineProperty(target, 'prop', {
enumerable: false,
configurable: true,
});
Object.preventExtensions(target);
var proxy = new Proxy(target, {
ownKeys: function() {
@ -51,6 +50,8 @@ var proxy = new Proxy(target, {
},
});
Object.preventExtensions(target);
assert.throws(TypeError, function() {
Object.keys(proxy);
});

View File

@ -0,0 +1,55 @@
// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-object.keys
description: >
Proxy [[OwnPropertyKeys]] trap does not skip non-enumerable keys when validating invariant:
* If the target object is not extensible, then the result List must contain all the keys of
the own properties of the target object and no other values.
info: |
Object.keys ( O )
...
2. Let nameList be ? EnumerableOwnPropertyNames(obj, "key").
EnumerableOwnPropertyNames ( O, kind )
...
2. Let ownKeys be ? O.[[OwnPropertyKeys]]().
[[OwnPropertyKeys]] ( )
...
11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
16. For each element key of targetKeys, do
a. Let desc be ? target.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Configurable]] is false, then
...
c. Else,
i. Append key as an element of targetConfigurableKeys.
...
18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
...
22. If uncheckedResultKeys is not empty, throw a TypeError exception.
features: [Proxy]
---*/
var target = {};
Object.defineProperty(target, 'prop', {
value: 3,
writable: true,
enumerable: false,
configurable: true,
});
var proxy = new Proxy(target, {
ownKeys: function() {
return ['prop'];
},
});
Object.preventExtensions(target);
var keys = Object.keys(proxy);
assert.sameValue(keys.length, 0);

View File

@ -5,7 +5,7 @@ esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
description: >
[[OwnPropertyKeys]] ( )
8. Let trapResultArray be Call(trap, handler, «target»).
7. Let trapResultArray be ? Call(trap, handler, « target »).
features: [Proxy]
---*/
@ -18,12 +18,12 @@ var handler = {
ownKeys: function(t) {
_handler = this;
_target = t;
return Object.getOwnPropertyNames(t);
return Object.keys(t);
}
};
var p = new Proxy(target, handler);
var keys = Object.getOwnPropertyNames(p);
var keys = Object.keys(p);
assert.sameValue(keys[0], "foo");
assert.sameValue(keys[1], "bar");