Improve Promise constructor coverage (#2158)

* Add constructor descriptor test

* Rename & improve non-callable executor test

* Rename & simplify executor call context tests

* Remove duplicate reject via abrupt test

* Deduplicate undefined NewTarget tests

* Add basic constructor test

* Add abrupt prototype getting tests
This commit is contained in:
Aleksey Shvayka 2019-05-23 00:33:09 +03:00 committed by Leo Balter
parent a9abd418cc
commit ee960aefb5
17 changed files with 200 additions and 181 deletions

View File

@ -1,16 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise is the Promise property of the global object
es6id: S25.4.3.1_A1.1_T1
author: Sam Mikes
description: Promise === global.Promise
---*/
var global = this;
if (Promise !== global.Promise) {
$ERROR("Expected Promise === global.Promise.");
}

View File

@ -1,14 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise throws TypeError when 'this' is not Object
es6id: S25.4.3.1_A2.1_T1
author: Sam Mikes
description: Promise.call("non-object") throws TypeError
---*/
assert.throws(TypeError, function() {
Promise.call("non-object", function() {});
});

View File

@ -1,16 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise throws TypeError when 'this' is constructed but unsettled promise
es6id: S25.4.3.1_A2.2_T1
author: Sam Mikes
description: Promise.call(new Promise()) throws TypeError
---*/
var p = new Promise(function() {});
assert.throws(TypeError, function() {
Promise.call(p, function() {});
});

View File

@ -1,25 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise throws TypeError when 'this' is resolved promise
es6id: S25.4.3.1_A2.3_T1
author: Sam Mikes
description: Promise.call(resolved Promise) throws TypeError
flags: [async]
---*/
var p = new Promise(function(resolve) {
resolve(1);
});
p.then(function() {
Promise.call(p, function() {});
}).then(function() {
$ERROR("Unexpected resolution - expected TypeError");
}, function(err) {
if (!(err instanceof TypeError)) {
$ERROR("Expected TypeError, got " + err);
}
}).then($DONE, $DONE);

View File

@ -1,25 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise throws TypeError when 'this' is rejected promise
es6id: S25.4.3.1_A2.4_T1
author: Sam Mikes
description: Promise.call(rejected Promise) throws TypeError
flags: [async]
---*/
var p = new Promise(function(resolve, reject) {
reject(1)
});
p.catch(function() {
Promise.call(p, function() {});
}).then(function() {
$ERROR("Unexpected resolution - expected TypeError");
}, function(err) {
if (!(err instanceof TypeError)) {
$ERROR("Expected TypeError, got " + err);
}
}).then($DONE, $DONE);

View File

@ -1,14 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise throws TypeError when executor is not callable
es6id: S25.4.3.1_A3.1_T1
author: Sam Mikes
description: new Promise("not callable") throws TypeError
---*/
assert.throws(TypeError, function() {
new Promise("not callable");
});

View File

@ -1,25 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise catches exceptions thrown from executor and turns
them into reject
es6id: S25.4.3.1_A4.1_T1
author: Sam Mikes
description: new Promise(function () { throw }) should reject
flags: [async]
---*/
var errorObject = {},
p = new Promise(function() {
throw errorObject;
});
p.then(function() {
$ERROR("Unexpected fulfill -- promise should reject.");
}, function(err) {
if (err !== errorObject) {
$ERROR("Expected promise rejection reason to be thrown errorObject, actually " + err);
}
}).then($DONE, $DONE);

View File

@ -1,23 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise executor has predictable environment
'this' should be global object in sloppy mode,
undefined in strict mode
es6id: S25.4.3.1_A5.1_T1
author: Sam Mikes
description: Promise executor gets default handling for 'this'
flags: [async, noStrict]
---*/
var expectedThis = this;
var p = new Promise(function(resolve) {
if (this !== expectedThis) {
$ERROR("'this' must be global object, got " + this);
}
resolve();
}).then($DONE, $DONE);

View File

@ -1,23 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: |
Promise executor has predictable environment
'this' should be global object in sloppy mode,
undefined in strict mode
es6id: S25.4.3.1_A5.1_T2
author: Sam Mikes
description: Promise executor gets default handling for 'this'
flags: [async, onlyStrict]
---*/
var expectedThis = undefined;
var p = new Promise(function(resolve) {
if (this !== expectedThis) {
$ERROR("'this' must be undefined, got " + this);
}
resolve();
}).then($DONE, $DONE);

View File

@ -0,0 +1,9 @@
// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
description: >
The Promise constructor is a built-in function
---*/
assert.sameValue(typeof Promise, 'function');

View File

@ -0,0 +1,22 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
author: Sam Mikes
description: >
Promise executor is called in global object context in sloppy mode.
info: |
25.6.3.1 Promise ( executor )
[...]
9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
flags: [noStrict]
---*/
var _this;
new Promise(function() {
_this = this;
});
assert.sameValue(_this, this);

View File

@ -0,0 +1,22 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
author: Sam Mikes
description: >
Promise executor is called in `undefined` context in strict mode.
info: |
25.6.3.1 Promise ( executor )
[...]
9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
flags: [onlyStrict]
---*/
var _this;
new Promise(function() {
_this = this;
});
assert.sameValue(_this, undefined);

View File

@ -0,0 +1,29 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
author: Sam Mikes
description: >
Promise constructor throws TypeError if executor is not callable.
info: |
25.6.3.1 Promise ( executor )
[...]
2. If IsCallable(executor) is false, throw a TypeError exception.
---*/
assert.throws(TypeError, function() {
new Promise('not callable');
});
assert.throws(TypeError, function() {
new Promise(1);
});
assert.throws(TypeError, function() {
new Promise(null);
});
assert.throws(TypeError, function() {
new Promise({});
});

View File

@ -0,0 +1,35 @@
// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
description: >
Promise constructor gets prototype after checking that executor is callable.
info: |
25.6.3.1 Promise ( executor )
[...]
2. If IsCallable(executor) is false, throw a TypeError exception.
3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
9.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
[...]
2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
9.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
[...]
3. Let proto be ? Get(constructor, "prototype").
features: [Reflect, Reflect.construct]
---*/
var bound = (function() {}).bind();
Object.defineProperty(bound, 'prototype', {
get: function() {
throw new Test262Error();
},
});
assert.throws(TypeError, function() {
Reflect.construct(Promise, [], bound);
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
description: >
Promise constructor rethrows errors raised at getting prototype.
info: |
25.6.3.1 Promise ( executor )
[...]
3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
9.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
[...]
2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
9.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
[...]
3. Let proto be ? Get(constructor, "prototype").
features: [Reflect, Reflect.construct]
---*/
var bound = (function() {}).bind();
Object.defineProperty(bound, 'prototype', {
get: function() {
throw new Test262Error();
},
});
assert.throws(Test262Error, function() {
Reflect.construct(Promise, [function() {}], bound);
});

View File

@ -0,0 +1,25 @@
// Copyright 2019 Aleksey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-constructor
description: >
Property descriptor of Promise
info: |
25.6.3 The Promise Constructor
* is the initial value of the Promise property of the global object.
17 ECMAScript Standard Built-in Objects
Every other data property described in clauses 18 through 26 and in Annex B.2
has the attributes { [[Writable]]: true, [[Enumerable]]: false,
[[Configurable]]: true } unless otherwise specified.
includes: [propertyHelper.js]
---*/
verifyProperty(this, 'Promise', {
value: Promise,
writable: true,
enumerable: false,
configurable: true,
});

View File

@ -0,0 +1,24 @@
// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise-executor
description: >
Throws a TypeError if Promise is called without a NewTarget.
info: |
25.6.3.1 Promise ( executor )
1. If NewTarget is undefined, throw a TypeError exception.
---*/
assert.throws(TypeError, function() {
Promise(function() {});
});
assert.throws(TypeError, function() {
Promise.call(null, function() {});
});
var p = new Promise(function() {});
assert.throws(TypeError, function() {
Promise.call(p, function() {});
});