Improve Proxy/construct coverage (#2159)

This commit is contained in:
Aleksey Shvayka 2019-05-29 22:49:41 +03:00 committed by Leo Balter
parent 465d0b587e
commit 1265a60017
24 changed files with 413 additions and 101 deletions

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
trap is called with handler object as its context, and parameters are:

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Return the result from the trap method.
@ -11,16 +12,14 @@ info: |
features: [Proxy]
---*/
function Target(a, b) {
this.sum = a + b;
};
var handler = {
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function(t, c, args) {
return {
sum: 42
};
}
};
var P = new Proxy(Target, handler);
});
assert.sameValue((new P(1, 2)).sum, 42);

View File

@ -0,0 +1,20 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
[[Construct]] (argumentsList, newTarget)
1. Let handler be O.[[ProxyHandler]].
2. If handler is null, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var p = OProxy.revocable(function() {}, {});
p.revoke();
assert.throws(TypeError, function() {
new p.proxy();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
[[Construct]] ( argumentsList, newTarget)

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Return abrupt from constructor call.

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: Boolean
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return true;
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws a TypeError if trap result is not an Object: Boolean
@ -11,10 +12,9 @@ info: |
features: [Proxy]
---*/
function Target() {
this.attr = "done";
};
var P = new Proxy(Target, {
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return true;
}

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: null
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return null;
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: null
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [Proxy]
---*/
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return null;
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: Number
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return 1;
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws a TypeError if trap result is not an Object: Number
@ -11,10 +12,11 @@ info: |
features: [Proxy]
---*/
function Target() {
this.attr = "done";
};
var P = new Proxy(Target, {
function Target() {}
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return 0;
}

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: String
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return '';
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws a TypeError if trap result is not an Object: String
@ -11,10 +12,11 @@ info: |
features: [Proxy]
---*/
function Target() {
this.attr = "done";
};
var P = new Proxy(Target, {
function Target() {}
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return "";
}

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: Symbol
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return Symbol();
},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws a TypeError if trap result is not an Object: Symbol
@ -11,10 +12,11 @@ info: |
features: [Proxy, Symbol]
---*/
function Target() {
this.attr = "done";
};
var P = new Proxy(Target, {
function Target() {}
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {
return Symbol();
}

View File

@ -0,0 +1,25 @@
// Copyright (C) 2019 Aleksey Shvayka. 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-construct-argumentslist-newtarget
description: >
Throws a TypeError if trap result is not an Object: undefined
(honoring the Realm of the current execution context)
info: |
[[Construct]] (argumentsList, newTarget)
[...]
11. If Type(newObj) is not Object, throw a TypeError exception.
features: [cross-realm, Proxy]
---*/
var OProxy = $262.createRealm().global.Proxy;
var P = new OProxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {},
});
assert.throws(TypeError, function() {
new P();
});

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws a TypeError if trap result is not an Object: undefined
@ -11,13 +12,10 @@ info: |
features: [Proxy]
---*/
function Target() {
this.attr = "done";
};
var P = new Proxy(Target, {
construct: function() {
return undefined;
}
var P = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function() {}
});
assert.throws(TypeError, function() {

View File

@ -1,6 +1,7 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
Throws if trap is not callable.

View File

@ -21,24 +21,31 @@ info: |
...
3. If func is either undefined or null, return undefined.
...
features: [new.target, Proxy, Reflect, Reflect.construct]
features: [Proxy, Reflect, Reflect.construct]
---*/
var calls = 0;
var _NewTarget;
function NewTarget() {}
function Target(a, b) {
assert.sameValue(new.target, NewTarget);
calls += 1;
return {
sum: a + b
};
}
var Target = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function(_Target, args, NewTarget) {
calls += 1;
_NewTarget = NewTarget;
return {
sum: args[0] + args[1]
};
}
})
var P = new Proxy(Target, {
construct: null
});
var NewTarget = function() {};
var obj = Reflect.construct(P, [3, 4], NewTarget);
assert.sameValue(obj.sum, 7, "`construct` trap is `null`");
assert.sameValue(calls, 1, "target is called once");
assert.sameValue(calls, 1, "construct is null: [[Construct]] is invoked once");
assert.sameValue(_NewTarget, NewTarget, "construct is null: NewTarget is passed to [[Construct]]");
assert.sameValue(obj.sum, 7, "construct is null: result of [[Construct]] is returned");

View File

@ -8,24 +8,40 @@ description: >
info: |
[[Construct]] (argumentsList, newTarget)
7. If trap is undefined, then
b. Return Construct(target, argumentsList, newTarget).
features: [new.target, Proxy, Reflect, Reflect.construct]
...
5. Let trap be ? GetMethod(handler, "construct").
6. If trap is undefined, then
a. Assert: target has a [[Construct]] internal method.
b. Return ? Construct(target, argumentsList, newTarget).
...
GetMethod ( V, P )
...
3. If func is either undefined or null, return undefined.
...
features: [Proxy, Reflect, Reflect.construct]
---*/
var calls = 0;
var _NewTarget;
function NewTarget() {}
function Target(a, b) {
assert.sameValue(new.target, NewTarget);
calls += 1;
return {
sum: a + b
};
}
var Target = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function(_Target, args, NewTarget) {
calls += 1;
_NewTarget = NewTarget;
return {
sum: args[0] + args[1]
};
}
})
var P = new Proxy(Target, {});
var obj = Reflect.construct(P, [1, 2], NewTarget);
assert.sameValue(obj.sum, 3, "`construct` trap is missing");
assert.sameValue(calls, 1, "target is called once");
var NewTarget = function() {};
var obj = Reflect.construct(P, [3, 4], NewTarget);
assert.sameValue(calls, 1, "construct is missing: [[Construct]] is invoked once");
assert.sameValue(_NewTarget, NewTarget, "construct is missing: NewTarget is passed to [[Construct]]");
assert.sameValue(obj.sum, 7, "construct is missing: result of [[Construct]] is returned");

View File

@ -0,0 +1,47 @@
// 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-construct-argumentslist-newtarget
description: >
If trap is undefined, propagate [[Construct]] to target,
passing correct newTarget parameter
info: |
[[Construct]] ( argumentsList, newTarget )
[...]
7. If trap is undefined, then
b. Return ? Construct(target, argumentsList, newTarget).
Construct ( F [ , argumentsList [ , newTarget ] ] )
[...]
5. Return ? F.[[Construct]](argumentsList, newTarget).
[[Construct]] ( argumentsList, newTarget )
[...]
5. If kind is "base", then
a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
[...]
2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
3. Return ObjectCreate(proto, internalSlotsList).
GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
[...]
3. Let proto be ? Get(constructor, "prototype").
[...]
5. Return proto.
features: [cross-realm, Proxy, Reflect, Reflect.construct]
---*/
var other = $262.createRealm().global;
var C = new other.Function();
var P = new Proxy(function() {}, {});
var p = Reflect.construct(P, [], C);
assert.sameValue(Object.getPrototypeOf(p), C.prototype);

View File

@ -1,33 +0,0 @@
// 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-construct-argumentslist-newtarget
es6id: 9.5.14
description: >
If trap is undefined, propagate the construct to the target object,
honoring the Realm of the newTarget value
info: |
[[Construct]] ( argumentsList, newTarget)
7. If trap is undefined, then
b. Return Construct(target, argumentsList, newTarget).
9.1.14 GetPrototypeFromConstructor
[...]
3. Let proto be ? Get(constructor, "prototype").
4. If Type(proto) is not Object, then
a. Let realm be ? GetFunctionRealm(constructor).
b. Let proto be realm's intrinsic object named intrinsicDefaultProto.
[...]
features: [cross-realm, Proxy, Reflect, Reflect.construct]
---*/
var other = $262.createRealm().global;
var C = new other.Function();
var P = new Proxy(function() {}, {});
var p = Reflect.construct(P, [], C);
assert.sameValue(Object.getPrototypeOf(Object.getPrototypeOf(p)), other.Object.prototype);

View File

@ -0,0 +1,56 @@
// 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-construct-argumentslist-newtarget
description: >
If trap is undefined, propagate [[Construct]] to target,
passing correct newTarget parameter
info: |
[[Construct]] ( argumentsList, newTarget )
[...]
7. If trap is undefined, then
b. Return ? Construct(target, argumentsList, newTarget).
Construct ( F [ , argumentsList [ , newTarget ] ] )
[...]
5. Return ? F.[[Construct]](argumentsList, newTarget).
[[Construct]] ( argumentsList, newTarget )
[...]
5. If kind is "base", then
a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
[...]
2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
3. Return ObjectCreate(proto, internalSlotsList).
GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
[...]
3. Let proto be ? Get(constructor, "prototype").
4. If Type(proto) is not Object, then
a. Let realm be ? GetFunctionRealm(constructor).
b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
5. Return proto.
GetFunctionRealm ( obj )
[...]
2. If obj has a [[Realm]] internal slot, then
a. Return obj.[[Realm]].
features: [cross-realm, Proxy, Reflect, Reflect.construct]
---*/
var other = $262.createRealm().global;
var C = new other.Function();
C.prototype = null;
var P = new Proxy(function() {}, {});
var p = Reflect.construct(P, [], C);
assert.sameValue(Object.getPrototypeOf(p), other.Object.prototype);

View File

@ -21,24 +21,31 @@ info: |
...
3. If func is either undefined or null, return undefined.
...
features: [new.target, Proxy, Reflect, Reflect.construct]
features: [Proxy, Reflect, Reflect.construct]
---*/
var calls = 0;
var _NewTarget;
function NewTarget() {}
function Target(a, b) {
assert.sameValue(new.target, NewTarget);
calls += 1;
return {
sum: a + b
};
}
var Target = new Proxy(function() {
throw new Test262Error('target should not be called');
}, {
construct: function(_Target, args, NewTarget) {
calls += 1;
_NewTarget = NewTarget;
return {
sum: args[0] + args[1]
};
},
});
var P = new Proxy(Target, {
construct: undefined
});
var NewTarget = function() {};
var obj = Reflect.construct(P, [3, 4], NewTarget);
assert.sameValue(obj.sum, 7, "`construct` trap is `undefined`");
assert.sameValue(calls, 1, "target is called once");
assert.sameValue(calls, 1, "construct is undefined: [[Construct]] is invoked once");
assert.sameValue(_NewTarget, NewTarget, "construct is undefined: NewTarget is passed to [[Construct]]");
assert.sameValue(obj.sum, 7, "construct is undefined: result of [[Construct]] is returned");