Clean up some existing constructor checks; eliminate duplicate checks

This commit is contained in:
Rick Waldron 2020-10-02 10:46:09 -04:00
parent c644ede430
commit 12ed905003
16 changed files with 265 additions and 111 deletions

View File

@ -0,0 +1,27 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-ecmascript-standard-built-in-objects
description: >
BigInt does not implement [[Construct]]
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
includes: [isConstructor.js]
features: [BigInt, Reflect.construct, arrow-function]
---*/
assert.sameValue(
isConstructor(BigInt),
false,
'isConstructor(BigInt) must return false'
);
assert.throws(TypeError, () => {
new BigInt(1n);
}, '`new BigInt(1n)` throws TypeError');

View File

@ -6,16 +6,19 @@ description: >
Tests that Date.prototype.toJSON meets the requirements
for built-in objects defined by the introduction of chapter 17 of
the ECMAScript Language Specification.
includes: [isConstructor.js]
features: [Reflect.construct]
---*/
var toJSON = Date.prototype.toJSON;
assert(Object.isExtensible(toJSON));
assert.sameValue(typeof toJSON, 'function');
assert.sameValue(Object.prototype.toString.call(toJSON), '[object Function]');
assert.sameValue(Object.getPrototypeOf(toJSON), Function.prototype);
assert.sameValue(toJSON.hasOwnProperty('prototype'), false);
assert.sameValue(isConstructor(toJSON), false);
assert(Object.isExtensible(Date.prototype.toJSON), 'Object.isExtensible(Date.prototype.toJSON) must return true');
assert.sameValue(typeof Date.prototype.toJSON, 'function', 'The value of `typeof Date.prototype.toJSON` is "function"');
assert.sameValue(
Object.prototype.toString.call(Date.prototype.toJSON),
'[object Function]',
'Object.prototype.toString.call(Date.prototype.toJSON) must return "[object Function]"'
);
assert.sameValue(
Object.getPrototypeOf(Date.prototype.toJSON),
Function.prototype,
'Object.getPrototypeOf(Date.prototype.toJSON) must return the value of Function.prototype'
);
assert.sameValue(Date.prototype.toJSON.hasOwnProperty('prototype'), false, 'Date.prototype.toJSON.hasOwnProperty("prototype") must return false');

View File

@ -5,15 +5,24 @@ esid: sec-json.parse
description: >
Requirements for built-in functions, defined in introduction of chapter 17,
are satisfied.
includes: [isConstructor.js]
features: [Reflect.construct]
---*/
var parse = JSON.parse;
assert(Object.isExtensible(parse));
assert.sameValue(typeof parse, 'function');
assert.sameValue(Object.prototype.toString.call(parse), '[object Function]');
assert.sameValue(Object.getPrototypeOf(parse), Function.prototype);
assert.sameValue(parse.hasOwnProperty('prototype'), false);
assert.sameValue(isConstructor(parse), false);
assert(Object.isExtensible(parse), 'Object.isExtensible(parse) must return true');
assert.sameValue(typeof parse, 'function', 'The value of `typeof parse` is "function"');
assert.sameValue(
Object.prototype.toString.call(parse),
'[object Function]',
'Object.prototype.toString.call("JSON.parse") must return "[object Function]"'
);
assert.sameValue(
Object.getPrototypeOf(parse),
Function.prototype,
'Object.getPrototypeOf("JSON.parse") must return the value of Function.prototype'
);
assert.sameValue(
parse.hasOwnProperty('prototype'),
false,
'parse.hasOwnProperty("prototype") must return false'
);

View File

@ -6,12 +6,22 @@ description: >
Tests that JSON.stringify meets the requirements
for built-in objects defined by the introduction of chapter 17 of
the ECMAScript Language Specification.
includes: [isConstructor.js]
features: [Reflect.construct]
---*/
assert(Object.isExtensible(JSON.stringify));
assert.sameValue(Object.prototype.toString.call(JSON.stringify), '[object Function]');
assert.sameValue(Object.getPrototypeOf(JSON.stringify), Function.prototype);
assert.sameValue(JSON.stringify.hasOwnProperty('prototype'), false);
assert.sameValue(isConstructor(JSON.stringify), false);
assert(Object.isExtensible(JSON.stringify), 'Object.isExtensible(JSON.stringify) must return true');
assert.sameValue(
Object.prototype.toString.call(JSON.stringify),
'[object Function]',
'Object.prototype.toString.call(JSON.stringify) must return "[object Function]"'
);
assert.sameValue(
Object.getPrototypeOf(JSON.stringify),
Function.prototype,
'Object.getPrototypeOf(JSON.stringify) must return the value of Function.prototype'
);
assert.sameValue(
JSON.stringify.hasOwnProperty('prototype'),
false,
'JSON.stringify.hasOwnProperty("prototype") must return false'
);

View File

@ -7,12 +7,25 @@ description: >
Tests that Object.prototype.isPrototypeOf meets the requirements
for built-in objects defined by the introduction of chapter 17 of
the ECMAScript Language Specification.
includes: [isConstructor.js]
features: [Reflect.construct]
---*/
assert(Object.isExtensible(Object.prototype.isPrototypeOf));
assert.sameValue(Object.prototype.toString.call(Object.prototype.isPrototypeOf), "[object Function]");
assert.sameValue(Object.getPrototypeOf(Object.prototype.isPrototypeOf), Function.prototype);
assert.sameValue(Object.prototype.isPrototypeOf.hasOwnProperty("prototype"), false);
assert.sameValue(isConstructor(Object.prototype.isPrototypeOf), false);
assert(
Object.isExtensible(Object.prototype.isPrototypeOf),
'Object.isExtensible(Object.prototype.isPrototypeOf) must return true'
);
assert.sameValue(
Object.prototype.toString.call(Object.prototype.isPrototypeOf),
"[object Function]",
'Object.prototype.toString.call(Object.prototype.isPrototypeOf) must return "[object Function]"'
);
assert.sameValue(
Object.getPrototypeOf(Object.prototype.isPrototypeOf),
Function.prototype,
'Object.getPrototypeOf(Object.prototype.isPrototypeOf) must return the value of Function.prototype'
);
assert.sameValue(
Object.prototype.isPrototypeOf.hasOwnProperty("prototype"),
false,
'Object.prototype.isPrototypeOf.hasOwnProperty("prototype") must return false'
);

View File

@ -9,7 +9,7 @@ info: |
...
7. Let reject be ! CreateBuiltinFunction(stepsReject, « [[Promise]], [[AlreadyResolved]] »).
features: [Reflect.construct]
features: [Reflect.construct, arrow-function]
includes: [isConstructor.js]
flags: [async]
---*/
@ -20,9 +20,13 @@ Promise.resolve(1).then(function() {
var then = Promise.prototype.then;
Promise.prototype.then = function(resolve, reject) {
assert(!isConstructor(reject));
assert.sameValue(reject.length, 1);
assert.sameValue(reject.name, '');
assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
assert.throws(TypeError, () => {
new reject();
}, '`new reject()` throws TypeError');
assert.sameValue(reject.length, 1, 'The value of reject.length is 1');
assert.sameValue(reject.name, '', 'The value of reject.name is ""');
return then.call(this, resolve, reject);
};

View File

@ -9,7 +9,7 @@ info: |
...
3. Let resolve be ! CreateBuiltinFunction(stepsResolve, « [[Promise]], [[AlreadyResolved]] »).
features: [Reflect.construct]
features: [Reflect.construct, arrow-function]
includes: [isConstructor.js]
flags: [async]
---*/
@ -20,9 +20,13 @@ Promise.resolve(1).then(function() {
var then = Promise.prototype.then;
Promise.prototype.then = function(resolve, reject) {
assert(!isConstructor(resolve));
assert.sameValue(resolve.length, 1);
assert.sameValue(resolve.name, '');
assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
assert.throws(TypeError, () => {
new resolve();
}, '`new resolve()` throws TypeError');
assert.sameValue(resolve.length, 1, 'The value of resolve.length is 1');
assert.sameValue(resolve.name, '', 'The value of resolve.name is ""');
return then.call(this, resolve, reject);
};

View File

@ -10,7 +10,7 @@ info: |
implement the [[Construct]] internal method unless otherwise specified
in the description of a particular function.
includes: [isConstructor.js]
features: [Reflect.construct]
features: [Reflect.construct, arrow-function]
---*/
var executorFunction;
@ -21,5 +21,14 @@ function NotPromise(executor) {
}
Promise.resolve.call(NotPromise);
assert.sameValue(Object.prototype.hasOwnProperty.call(executorFunction, "prototype"), false);
assert.sameValue(isConstructor(executorFunction), false);
assert.sameValue(
Object.prototype.hasOwnProperty.call(executorFunction, "prototype"),
false,
'Object.prototype.hasOwnProperty.call(executorFunction, "prototype") must return false'
);
assert.sameValue(isConstructor(executorFunction), false, 'isConstructor(executorFunction) must return false');
assert.throws(TypeError, () => {
new executorFunction();
}, '`new executorFunction()` throws TypeError');

View File

@ -4,7 +4,7 @@
author: Jordan Harband
description: Promise.prototype.finally invokes `then` method
esid: sec-promise.prototype.finally
features: [Promise.prototype.finally, Reflect.construct]
features: [Promise.prototype.finally, Reflect.construct, arrow-function]
includes: [isConstructor.js]
---*/
@ -13,16 +13,16 @@ var returnValue = {};
var callCount = 0;
var thisValue = null;
var argCount = null;
var firstArg = null;
var secondArg = null;
var resolve = null;
var reject = null;
target.then = function(a, b) {
callCount += 1;
thisValue = this;
argCount = arguments.length;
firstArg = a;
secondArg = b;
resolve = a;
reject = b;
return returnValue;
};
@ -30,31 +30,38 @@ target.then = function(a, b) {
var originalFinallyHandler = function() {};
var result = Promise.prototype.finally.call(target, originalFinallyHandler, 2, 3);
assert.sameValue(callCount, 1, 'Invokes `then` method exactly once');
assert.sameValue(callCount, 1, 'The value of `callCount` is 1');
assert.sameValue(
thisValue,
target,
'Invokes `then` method with the instance as the `this` value'
'The value of `thisValue` is expected to equal the value of target'
);
assert.sameValue(argCount, 2, 'Invokes `then` method with exactly two single arguments');
assert.sameValue(argCount, 2, 'The value of `argCount` is 2');
assert.sameValue(
typeof firstArg,
typeof resolve,
'function',
'Invokes `then` method with a function as the first argument'
'The value of `typeof resolve` is "function"'
);
assert.notSameValue(firstArg, originalFinallyHandler, 'Invokes `then` method with a different fulfillment handler');
assert.sameValue(firstArg.length, 1, 'fulfillment handler has a length of 1');
assert.sameValue(firstArg.name, '', 'fulfillment handler is anonymous');
assert(!isConstructor(firstArg), 'fulfillment handler is not constructor');
assert.notSameValue(resolve, originalFinallyHandler, 'The value of `resolve` is expected to not equal the value of `originalFinallyHandler`');
assert.sameValue(resolve.length, 1, 'The value of resolve.length is 1');
assert.sameValue(resolve.name, '', 'The value of resolve.name is ""');
assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
assert.throws(TypeError, () => {
new resolve();
}, '`new resolve()` throws TypeError');
assert.sameValue(
typeof secondArg,
typeof reject,
'function',
'Invokes `then` method with a function as the second argument'
'The value of `typeof reject` is "function"'
);
assert.notSameValue(secondArg, originalFinallyHandler, 'Invokes `then` method with a different rejection handler');
assert.sameValue(secondArg.length, 1, 'rejection handler has a length of 1');
assert.sameValue(secondArg.name, '', 'rejection handler is anonymous');
assert(!isConstructor(secondArg), 'rejection handler is not constructor');
assert.notSameValue(reject, originalFinallyHandler, 'The value of `reject` is expected to not equal the value of `originalFinallyHandler`');
assert.sameValue(reject.length, 1, 'The value of reject.length is 1');
assert.sameValue(reject.name, '', 'The value of reject.name is ""');
assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
assert.throws(TypeError, () => {
new reject();
}, '`new reject()` throws TypeError');
assert.sameValue(result, returnValue, 'Returns the result of the invocation of `then`');
assert.sameValue(result, returnValue, 'The value of `result` is expected to equal the value of returnValue');

View File

@ -12,7 +12,7 @@ info: |
9. Return ? Invoke(promise, "then", « thrower »).
The "length" property of a Catch Finally function is 1.
features: [Promise.prototype.finally, Reflect.construct]
features: [Promise.prototype.finally, Reflect.construct, class, arrow-function]
includes: [isConstructor.js]
flags: [async]
---*/
@ -40,11 +40,23 @@ var expected = [
var then = Promise.prototype.then;
Promise.prototype.then = function(resolve, reject) {
assert(!isConstructor(resolve));
assert.sameValue(resolve.length, expected[calls].length);
assert.sameValue(resolve.name, expected[calls].name);
assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
assert.throws(TypeError, () => {
new reject();
}, '`new reject()` throws TypeError');
assert.sameValue(
resolve.length,
expected[calls].length,
'The value of resolve.length is expected to equal the value of expected[calls].length'
);
assert.sameValue(
resolve.name,
expected[calls].name,
'The value of resolve.name is expected to equal the value of expected[calls].name'
);
if (calls === 0) {
assert.throws(MyError, resolve);
assert.throws(MyError, resolve, '`resolve()` throws `MyError`');
}
calls += 1;

View File

@ -12,7 +12,7 @@ info: |
9. Return ? Invoke(promise, "then", « valueThunk »).
The "length" property of a Then Finally function is 1.
features: [Promise.prototype.finally, Reflect.construct]
features: [Promise.prototype.finally, Reflect.construct, arrow-function]
includes: [isConstructor.js]
flags: [async]
---*/
@ -31,11 +31,23 @@ var expected = [
var then = Promise.prototype.then;
Promise.prototype.then = function(resolve) {
assert(!isConstructor(resolve));
assert.sameValue(resolve.length, expected[calls].length);
assert.sameValue(resolve.name, expected[calls].name);
assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
assert.throws(TypeError, () => {
new resolve();
}, '`new resolve()` throws TypeError');
assert.sameValue(
resolve.length,
expected[calls].length,
'The value of resolve.length is expected to equal the value of expected[calls].length'
);
assert.sameValue(
resolve.name,
expected[calls].name,
'The value of resolve.name is expected to equal the value of expected[calls].name'
);
if (calls === 0) {
assert.sameValue(resolve(), value);
assert.sameValue(resolve(), value, 'resolve() must return the value of value');
}
calls += 1;
return then.call(this, resolve);

View File

@ -0,0 +1,31 @@
// 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-proxycreate
description: >
A Proxy exotic object only accepts a constructor call if target is
constructor.
info: |
ProxyCreate ( target, handler )
If IsCallable(target) is true, then
Set P.[[Call]] as specified in 9.5.12.
If IsConstructor(target) is true, then
Set P.[[Construct]] as specified in 9.5.13.
...
Runtime Semantics: EvaluateNew(constructProduction, arguments)
8. If IsConstructor (constructor) is false, throw a TypeError exception.
includes: [isConstructor.js]
features: [Proxy, Reflect.construct, arrow-function]
---*/
var proxy = new Proxy(eval, {});
proxy(); // the Proxy object is callable
assert.sameValue(isConstructor(proxy), false, 'isConstructor(proxy) must return false');
assert.throws(TypeError, () => {
new proxy();
}, '`new proxy()` throws TypeError');

View File

@ -1,29 +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.15
description: >
A Proxy exotic object only accepts a constructor call if target is
constructor.
info: |
Proxy ( target, handler )
7. If IsCallable(target) is true, then
b. If target has a [[Construct]] internal method, then
i. Set the [[Construct]] internal method of P as specified in
9.5.14.
...
12.3.3.1.1 Runtime Semantics: EvaluateNew(constructProduction, arguments)
8. If IsConstructor (constructor) is false, throw a TypeError exception.
features: [Proxy]
---*/
var p = new Proxy(eval, {});
p(); // the Proxy object is callable
assert.throws(TypeError, function() {
new p();
});

View File

@ -5,14 +5,24 @@ esid: sec-proxy.revocable
description: >
Requirements for built-in functions, defined in introduction of chapter 17,
are satisfied.
includes: [isConstructor.js]
features: [Proxy, Reflect.construct]
---*/
assert(Object.isExtensible(Proxy.revocable));
assert.sameValue(typeof Proxy.revocable, 'function');
assert.sameValue(Object.prototype.toString.call(Proxy.revocable), '[object Function]');
assert.sameValue(Object.getPrototypeOf(Proxy.revocable), Function.prototype);
assert(Object.isExtensible(Proxy.revocable), 'Object.isExtensible(Proxy.revocable) must return true');
assert.sameValue(typeof Proxy.revocable, 'function', 'The value of `typeof Proxy.revocable` is "function"');
assert.sameValue(
Object.prototype.toString.call(Proxy.revocable),
'[object Function]',
'Object.prototype.toString.call(Proxy.revocable) must return "[object Function]"'
);
assert.sameValue(
Object.getPrototypeOf(Proxy.revocable),
Function.prototype,
'Object.getPrototypeOf(Proxy.revocable) must return the value of Function.prototype'
);
assert.sameValue(Proxy.revocable.hasOwnProperty('prototype'), false);
assert.sameValue(isConstructor(Proxy.revocable), false);
assert.sameValue(
Proxy.revocable.hasOwnProperty('prototype'),
false,
'Proxy.revocable.hasOwnProperty(\'prototype\') must return false'
);

View File

@ -0,0 +1,23 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-ecmascript-standard-built-in-objects
description: >
Proxy.revocable does not implement [[Construct]]
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
includes: [isConstructor.js]
features: [Reflect.construct, Reflect, arrow-function, Proxy]
---*/
assert.sameValue(isConstructor(Proxy.revocable), false, 'isConstructor(Proxy.revocable) must return false');
assert.throws(TypeError, () => {
new Proxy.revocable({}, {});
}, '`new Proxy.revocable({}, {})` throws TypeError');

View File

@ -10,10 +10,19 @@ info: |
implement the [[Construct]] internal method unless otherwise specified
in the description of a particular function.
includes: [isConstructor.js]
features: [Proxy, Reflect.construct]
features: [Proxy, Reflect.construct, arrow-function]
---*/
var revocationFunction = Proxy.revocable({}, {}).revoke;
assert.sameValue(Object.prototype.hasOwnProperty.call(revocationFunction, "prototype"), false);
assert.sameValue(isConstructor(revocationFunction), false);
assert.sameValue(
Object.prototype.hasOwnProperty.call(revocationFunction, "prototype"),
false,
'Object.prototype.hasOwnProperty.call(revocationFunction, "prototype") must return false'
);
assert.sameValue(isConstructor(revocationFunction), false, 'isConstructor(revocationFunction) must return false');
assert.throws(TypeError, () => {
new revocationFunction();
}, '`new revocationFunction()` throws TypeError');