mirror of https://github.com/tc39/test262.git
Update tests for Proxy.[[SetPrototypeOf]] (#716)
* Update tests for Proxy.[[SetPrototypeOf]] Expand coverage for proxies' [[SetPrototypeOf]] and update tests to verify that target's [[IsExtensible]] is not called anymore if trap returns a falsy value. Ref tc39/ecma262#331
This commit is contained in:
parent
2c5138a4c7
commit
e8e0fb9d34
|
@ -1,28 +0,0 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 9.5.2
|
||||
description: >
|
||||
Return a boolean trap result if target is extensible.
|
||||
info: >
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
...
|
||||
13. If extensibleTarget is true, return booleanTrapResult.
|
||||
...
|
||||
flags: [onlyStrict]
|
||||
features: [Reflect]
|
||||
---*/
|
||||
|
||||
var target = {};
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return v.attr;
|
||||
}
|
||||
});
|
||||
|
||||
var result = Reflect.setPrototypeOf(p, { attr: 0 });
|
||||
assert.sameValue(result, false);
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: 1 });
|
||||
assert.sameValue(result, true);
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Calls target.[[GetPrototypeOf]] after trap result as false and not extensible
|
||||
target
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
|
||||
9. If booleanTrapResult is false, return false.
|
||||
10. Let extensibleTarget be ? IsExtensible(target).
|
||||
11. If extensibleTarget is true, return true.
|
||||
12. Let targetProto be ? target.[[GetPrototypeOf]]().
|
||||
features: [Reflect.setPrototypeOf]
|
||||
---*/
|
||||
|
||||
var calls = [];
|
||||
var proto = {};
|
||||
|
||||
var target = new Proxy(Object.create(proto), {
|
||||
isExtensible: function() {
|
||||
calls.push("target.[[IsExtensible]]");
|
||||
return false;
|
||||
},
|
||||
getPrototypeOf: function() {
|
||||
calls.push("target.[[GetPrototypeOf]]");
|
||||
return proto;
|
||||
}
|
||||
});
|
||||
|
||||
// Proxy must report same extensiblitity as target
|
||||
Object.preventExtensions(target);
|
||||
|
||||
var proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
calls.push("proxy.[[setPrototypeOf]]");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.sameValue(Reflect.setPrototypeOf(proxy, proto), false);
|
||||
assert.sameValue(calls.length, 3);
|
||||
assert.sameValue(calls[0], "proxy.[[setPrototypeOf]]");
|
||||
assert.sameValue(calls[1], "target.[[IsExtensible]]");
|
||||
assert.sameValue(calls[2], "target.[[GetPrototypeOf]]");
|
|
@ -21,18 +21,33 @@ info: >
|
|||
16. If booleanTrapResult is true and SameValue(V, targetProto) is false,
|
||||
throw a TypeError exception.
|
||||
...
|
||||
|
||||
features: [Reflect.setPrototypeOf]
|
||||
---*/
|
||||
|
||||
var target = {};
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return true;
|
||||
}
|
||||
var target, proxy;
|
||||
target = {};
|
||||
proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Object.preventExtensions(target);
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Object.setPrototypeOf(p, {});
|
||||
Reflect.setPrototypeOf(proxy, {});
|
||||
}, "target prototype is different");
|
||||
|
||||
var proto = {};
|
||||
target = Object.setPrototypeOf({}, proto);
|
||||
proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
Object.setPrototypeOf(target, {});
|
||||
Object.preventExtensions(target);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Reflect.setPrototypeOf(proxy, proto);
|
||||
}, "target prototype is changed inside trap handler");
|
||||
|
|
|
@ -1,20 +1,55 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
es6id: 9.5.2
|
||||
description: >
|
||||
Return true if boolean trap result is true, target is not extensible, and
|
||||
given parameter is the same as target prototype.
|
||||
features: [Reflect]
|
||||
Handler can only return true for non-extensible targets if the given prototype
|
||||
is the same as target's prototype
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
12. Let targetProto be ? target.[[GetPrototypeOf]]().
|
||||
13. If SameValue(V, targetProto) is false, throw a TypeError exception.
|
||||
14. Return true.
|
||||
features: [Reflect.setPrototypeOf]
|
||||
---*/
|
||||
|
||||
var target = Object.create(Array.prototype);
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
var proto = {};
|
||||
var target = Object.setPrototypeOf({}, proto);
|
||||
|
||||
Object.preventExtensions(target);
|
||||
|
||||
assert(Reflect.setPrototypeOf(p, Array.prototype));
|
||||
var proxy;
|
||||
|
||||
proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.sameValue(
|
||||
Reflect.setPrototypeOf(proxy, proto),
|
||||
true,
|
||||
"prototype arg is the same in target"
|
||||
);
|
||||
|
||||
var outro = {};
|
||||
proxy = new Proxy(outro, {
|
||||
setPrototypeOf: function(t, p) {
|
||||
Object.setPrototypeOf(t, p);
|
||||
Object.preventExtensions(t);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.sameValue(
|
||||
Reflect.setPrototypeOf(proxy, proto),
|
||||
true,
|
||||
"prototype is set to target inside handler trap"
|
||||
);
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(outro),
|
||||
proto,
|
||||
"target has the custom set prototype"
|
||||
);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 9.5.2
|
||||
description: >
|
||||
Return false if boolean trap result is false.
|
||||
features: [Reflect]
|
||||
---*/
|
||||
|
||||
var target = [];
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
Object.preventExtensions(target);
|
||||
|
||||
assert.sameValue(Reflect.setPrototypeOf(p, {}), false);
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 9.5.2
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist
|
||||
description: >
|
||||
Return abrupt getting handler trap
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
6. Let trap be ? GetMethod(handler, "setPrototypeOf").
|
||||
---*/
|
||||
|
||||
var handler = Object.defineProperty({}, "setPrototypeOf", {
|
||||
get: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
|
||||
var proxy = new Proxy({}, handler);
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
Object.setPrototypeOf(proxy, {});
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Return abrupt from IsExtensible(target)
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
10. Let extensibleTarget be ? IsExtensible(target).
|
||||
---*/
|
||||
|
||||
var target = new Proxy({}, {
|
||||
isExtensible: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
|
||||
var proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
Object.setPrototypeOf(proxy, {});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Return abrupt from target.[[GetPrototypeOf]]()
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
12. Let targetProto be ? target.[[GetPrototypeOf]]().
|
||||
---*/
|
||||
|
||||
var target = new Proxy({}, {
|
||||
getPrototypeOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
|
||||
Object.preventExtensions(target);
|
||||
|
||||
var proxy = new Proxy(target, {
|
||||
setPrototypeOf: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
Object.setPrototypeOf(proxy, {});
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Return false if ToBoolean(trap result) is false, without checking
|
||||
target.[[IsExtensible]]
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
|
||||
9. If booleanTrapResult is false, return false.
|
||||
10. Let extensibleTarget be ? IsExtensible(target).
|
||||
11. If extensibleTarget is true, return true.
|
||||
features: [Reflect.setPrototypeOf]
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
|
||||
var target = new Proxy({}, {
|
||||
isExtensible: function() {
|
||||
called += 1;
|
||||
}
|
||||
});
|
||||
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return v.attr;
|
||||
}
|
||||
});
|
||||
|
||||
var result;
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: false });
|
||||
assert.sameValue(result, false, "false");
|
||||
assert.sameValue(called, 0, "false - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: "" });
|
||||
assert.sameValue(result, false, "the empty string");
|
||||
assert.sameValue(called, 0, "the empty string - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: 0 });
|
||||
assert.sameValue(result, false, "0");
|
||||
assert.sameValue(called, 0, "0 - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: -0 });
|
||||
assert.sameValue(result, false, "-0");
|
||||
assert.sameValue(called, 0, "-0 - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: null });
|
||||
assert.sameValue(result, false, "null");
|
||||
assert.sameValue(called, 0, "null - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: undefined });
|
||||
assert.sameValue(result, false, "undefined");
|
||||
assert.sameValue(called, 0, "undefined - isExtensible is not called");
|
||||
|
||||
result = Reflect.setPrototypeOf(p, { attr: NaN });
|
||||
assert.sameValue(result, false, "NaN");
|
||||
assert.sameValue(called, 0, "NaN - isExtensible is not called");
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Return true if ToBoolean(trap result) is true, and target.[[IsExtensible]] is
|
||||
true
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
|
||||
9. If booleanTrapResult is false, return false.
|
||||
10. Let extensibleTarget be ? IsExtensible(target).
|
||||
11. If extensibleTarget is true, return true.
|
||||
features: [Reflect.setPrototypeOf, Symbol]
|
||||
---*/
|
||||
|
||||
var called;
|
||||
var target = new Proxy({}, {
|
||||
isExtensible: function() {
|
||||
called += 1;
|
||||
return true;
|
||||
},
|
||||
getPrototypeOf: function() {
|
||||
throw new Test262Error("target.[[GetPrototypeOf]] is not called");
|
||||
}
|
||||
});
|
||||
|
||||
var p = new Proxy(target, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
return v.attr;
|
||||
}
|
||||
});
|
||||
|
||||
var result;
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: true });
|
||||
assert.sameValue(result, true, "true");
|
||||
assert.sameValue(called, 1, "true - isExtensible is called");
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: "false" });
|
||||
assert.sameValue(result, true, "string");
|
||||
assert.sameValue(called, 1, "string - isExtensible is called");
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: 42 });
|
||||
assert.sameValue(result, true, "42");
|
||||
assert.sameValue(called, 1, "number - isExtensible is called");
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: p });
|
||||
assert.sameValue(result, true, "p");
|
||||
assert.sameValue(called, 1, "object - isExtensible is called");
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: [] });
|
||||
assert.sameValue(result, true, "[]");
|
||||
assert.sameValue(called, 1, "[] - isExtensible is called");
|
||||
|
||||
called = 0;
|
||||
result = Reflect.setPrototypeOf(p, { attr: Symbol(1) });
|
||||
assert.sameValue(result, true, "symbol");
|
||||
assert.sameValue(called, 1, "symbol - isExtensible is called");
|
|
@ -18,6 +18,7 @@ info: >
|
|||
2. Let func be GetV(O, P).
|
||||
5. If IsCallable(func) is false, throw a TypeError exception.
|
||||
...
|
||||
features: [Reflect.setPrototypeOf]
|
||||
---*/
|
||||
|
||||
var target = {};
|
||||
|
@ -26,7 +27,7 @@ var p = new Proxy(target, {
|
|||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Object.setPrototypeOf(p, {
|
||||
Reflect.setPrototypeOf(p, {
|
||||
value: 1
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 9.5.2
|
||||
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
|
||||
description: >
|
||||
Return target.[[SetPrototypeOf]] (V) if trap is undefined or null.
|
||||
info: |
|
||||
[[SetPrototypeOf]] (V)
|
||||
|
||||
6. Let trap be ? GetMethod(handler, "setPrototypeOf").
|
||||
7. If trap is undefined, then
|
||||
a. Return ? target.[[SetPrototypeOf]](V).
|
||||
|
||||
GetMethod (V, P)
|
||||
|
||||
2. Let func be ? GetV(V, P).
|
||||
3. If func is either undefined or null, return undefined.
|
||||
---*/
|
||||
|
||||
var proxy, called, value;
|
||||
var target = new Proxy({}, {
|
||||
setPrototypeOf: function(t, v) {
|
||||
called += 1;
|
||||
value = v;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
var proto = {};
|
||||
|
||||
proxy = new Proxy(target, {});
|
||||
called = 0;
|
||||
value = false;
|
||||
Object.setPrototypeOf(proxy, proto);
|
||||
assert.sameValue(called, 1, "undefined, target.[[SetPrototypeOf]] is called");
|
||||
assert.sameValue(value, proto, "undefined, called with V");
|
||||
|
||||
proxy = new Proxy(target, {
|
||||
setPrototypeOf: null
|
||||
});
|
||||
called = 0;
|
||||
value = false;
|
||||
Object.setPrototypeOf(proxy, proto);
|
||||
assert.sameValue(called, 1, "null, target.[[SetPrototypeOf]] is called");
|
||||
assert.sameValue(value, proto, "null, called with V");
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 9.5.2
|
||||
description: >
|
||||
Return target.[[SetPrototypeOf]] (V) if trap is undefined.
|
||||
---*/
|
||||
|
||||
var target = {};
|
||||
var p = new Proxy(target, {});
|
||||
|
||||
Object.setPrototypeOf(p, {attr: 1});
|
||||
|
||||
assert.sameValue(target.attr, 1);
|
Loading…
Reference in New Issue