Add tests for Promise Resolve Functions

Remove files that tested both PerformPromiseThen and
PromiseResolveFunction in favor of new tests that test
PromiseResolveFunction more directly and completely.
This commit is contained in:
Mike Pennisi 2015-12-30 14:15:01 -05:00 committed by Gorkem Yakin
parent a5bf19486a
commit b1b4f04494
47 changed files with 1984 additions and 378 deletions

View File

@ -0,0 +1,74 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value
es6id: 25.4.4.1
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
d. If next is false,
[...]
iii. If remainingElementsCount.[[value]] is 0,
1. Let valuesArray be CreateArrayFromList(values).
2. Let resolveResult be Call(resultCapability.[[Resolve]],
undefined, «valuesArray»).
3. ReturnIfAbrupt(resolveResult)
iv. Return resultCapability.[[Promise]].
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var v1 = {};
var v2 = {};
var v3 = {};
Promise.all([v1, v2, v3])
.then(function(values) {
if (!values) {
$DONE('The promise should be resolved with a value.');
return;
}
if (values.constructor !== Array) {
$DONE('The promise should be resolved with an Array instance.');
return;
}
if (values.length !== 3) {
$DONE('The promise should be resolved with an array of proper length.');
return;
}
if (values[0] !== v1) {
$DONE('The promise should be resolved with the correct element values (#1)');
return;
}
if (values[1] !== v2) {
$DONE('The promise should be resolved with the correct element values (#2)');
return;
}
if (values[2] !== v3) {
$DONE('The promise should be resolved with the correct element values (#3)');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,70 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property
es6id: 25.4.4.1
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
d. If next is false,
[...]
iii. If remainingElementsCount.[[value]] is 0,
1. Let valuesArray be CreateArrayFromList(values).
2. Let resolveResult be Call(resultCapability.[[Resolve]],
undefined, «valuesArray»).
3. ReturnIfAbrupt(resolveResult)
iv. Return resultCapability.[[Promise]].
7.3.16 CreateArrayFromList (elements)
[...]
2. Let array be ArrayCreate(0) (see 9.4.2.2).
9.4.2.2 ArrayCreate(length, proto)
[...]
4. If the proto argument was not passed, let proto be the intrinsic object
%ArrayPrototype%.
5. Let A be a newly created Array exotic object.
[...]
8. Set the [[Prototype]] internal slot of A to proto.
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var promise;
try {
Object.defineProperty(Array.prototype, 'then', {
get: function() {
throw value;
},
configurable: true
});
promise = Promise.all([]);
} finally {
delete Array.prototype.then;
}
promise.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(val) {
if (val !== value) {
$DONE('The promise should be rejected with the expected value.');
return;
}
$DONE();
});

View File

@ -0,0 +1,72 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value
es6id: 25.4.4.1
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
d. If next is false,
[...]
iii. If remainingElementsCount.[[value]] is 0,
1. Let valuesArray be CreateArrayFromList(values).
2. Let resolveResult be Call(resultCapability.[[Resolve]],
undefined, «valuesArray»).
3. ReturnIfAbrupt(resolveResult)
iv. Return resultCapability.[[Promise]].
7.3.16 CreateArrayFromList (elements)
[...]
2. Let array be ArrayCreate(0) (see 9.4.2.2).
9.4.2.2 ArrayCreate(length, proto)
[...]
4. If the proto argument was not passed, let proto be the intrinsic object
%ArrayPrototype%.
5. Let A be a newly created Array exotic object.
[...]
8. Set the [[Prototype]] internal slot of A to proto.
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var promise;
try {
Array.prototype.then = function(resolve) {
resolve(value);
};
promise = Promise.all([]);
} finally {
delete Array.prototype.then;
}
promise.then(function(val) {
if (val !== value) {
$DONE('The promise should be resolved with the expected value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -1,70 +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: 25.4.5.3
description: The return value of the `onFulfilled` method is a fulfilled promise
info: >
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«fulfillReaction, value»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
resolution, thenAction»)
13. Return undefined.
---*/
var executor1Counter = 0;
var thenCounter = 0;
var executor2Counter = 0;
var promise = new Promise(function(resolve) {
resolve();
assert.sameValue(executor1Counter, 0);
assert.sameValue(thenCounter, 0);
assert.sameValue(executor2Counter, 0);
executor1Counter += 1;
});
promise.then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 0);
assert.sameValue(executor2Counter, 0);
thenCounter += 1;
return new Promise(function(resolve) {
resolve();
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 1);
assert.sameValue(executor2Counter, 0);
executor2Counter += 1;
});
}).then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 1);
assert.sameValue(executor2Counter, 1);
$DONE();
}, function() {
$DONE('The promise should not be rejected');
});

View File

@ -1,84 +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: 25.4.5.3
description: The return value of the `onFulfilled` method is a pending promise
info: >
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«fulfillReaction, value»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
resolution, thenAction»)
13. Return undefined.
---*/
var executor1Counter = 0;
var then1Counter = 0;
var executor2Counter = 0;
var then2Counter = 0;
var promise = new Promise(function(resolve) {
resolve();
assert.sameValue(executor1Counter, 0);
assert.sameValue(then1Counter, 0);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
executor1Counter += 1;
});
promise.then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 0);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
then1Counter += 1;
return new Promise(function(resolve) {
promise.then(function() {
resolve();
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 1);
assert.sameValue(then2Counter, 0);
then2Counter += 1;
});
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
executor2Counter += 1;
});
}).then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 1);
assert.sameValue(then2Counter, 1);
$DONE();
}, function() {
$DONE('The promise should not be rejected');
});

View File

@ -1,84 +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: 25.4.5.3
description: The return value of the `onFulfilled` method is a pending promise
info: >
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«fulfillReaction, value»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
resolution, thenAction»)
13. Return undefined.
---*/
var executor1Counter = 0;
var then1Counter = 0;
var executor2Counter = 0;
var then2Counter = 0;
var promise = new Promise(function(resolve) {
resolve();
assert.sameValue(executor1Counter, 0);
assert.sameValue(then1Counter, 0);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
executor1Counter += 1;
});
promise.then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 0);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
then1Counter += 1;
return new Promise(function(_, reject) {
promise.then(function() {
reject();
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 1);
assert.sameValue(then2Counter, 0);
then2Counter += 1;
});
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 0);
assert.sameValue(then2Counter, 0);
executor2Counter += 1;
});
}).then(function() {
$DONE('The promise should not be fulfilled');
}, function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(then1Counter, 1);
assert.sameValue(executor2Counter, 1);
assert.sameValue(then2Counter, 1);
$DONE();
});

View File

@ -1,70 +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: 25.4.5.3
description: The return value of the `onFulfilled` method is a rejected promise
info: >
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«fulfillReaction, value»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
resolution, thenAction»)
13. Return undefined.
---*/
var executor1Counter = 0;
var thenCounter = 0;
var executor2Counter = 0;
var promise = new Promise(function(resolve) {
resolve();
assert.sameValue(executor1Counter, 0);
assert.sameValue(thenCounter, 0);
assert.sameValue(executor2Counter, 0);
executor1Counter += 1;
});
promise.then(function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 0);
assert.sameValue(executor2Counter, 0);
thenCounter += 1;
return new Promise(function(_, reject) {
reject();
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 1);
assert.sameValue(executor2Counter, 0);
executor2Counter += 1;
});
}).then(function() {
$DONE('The promise should not be fulfilled');
}, function() {
assert.sameValue(executor1Counter, 1);
assert.sameValue(thenCounter, 1);
assert.sameValue(executor2Counter, 1);
$DONE();
});

View File

@ -1,70 +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: 25.4.5.3
description: The return value of the `onFulfilled` method is a "thenable" object
info: >
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«fulfillReaction, value»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
resolution, thenAction»)
13. Return undefined.
---*/
var callCount = 0;
var promise = new Promise(function(resolve) {
resolve();
});
var thenable = {
then: function(resolve, reject) {
assert.sameValue(
this, thenable, 'method invoked with correct `this` value'
);
assert.sameValue(typeof resolve, 'function', 'type of first argument');
assert.sameValue(
resolve.length,
1,
'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
);
assert.sameValue(typeof reject, 'function', 'type of second argument');
assert.sameValue(
reject.length,
1,
'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
);
assert.sameValue(arguments.length, 2, 'total number of arguments');
resolve();
callCount += 1;
}
};
promise.then(function() {
return thenable;
}).then(function() {
assert.sameValue(callCount, 1);
$DONE();
}, function() {
$DONE('This promise should not be rejected');
});

View File

@ -0,0 +1,42 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value from a pending promise that is later fulfilled
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
a. Append fulfillReaction as the last element of the List that is the
value of promise's [[PromiseFulfillReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var resolve;
var p1 = new Promise(function(_resolve) { resolve = _resolve; });
var p2;
p2 = p1.then(function() {
return 23;
});
p2.then(function(value) {
if (value !== 23) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve();

View File

@ -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.
/*---
description: Resolving with a non-thenable object value from a pending promise that is later fulfilled
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
a. Append fulfillReaction as the last element of the List that is the
value of promise's [[PromiseFulfillReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var resolve;
var p1 = new Promise(function(_resolve) { resolve = _resolve; });
var p2;
p2 = p1.then(function() {
return nonThenable;
});
p2.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve();

View File

@ -0,0 +1,50 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property from a pending promise that is later fulfilled
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
a. Append fulfillReaction as the last element of the List that is the
value of promise's [[PromiseFulfillReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var resolve;
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var p1 = new Promise(function(_resolve) { resolve = _resolve; });
var p2;
p2 = p1.then(function() {
return poisonedThen;
});
p2.then(function(x) {
$DONE('The promise should not be fulfilled.');
}, function(x) {
if (x !== value) {
$DONE('The promise should be rejected with the thrown exception.');
return;
}
$DONE();
});
resolve();

View File

@ -0,0 +1,49 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself from a pending promise that is later fulfilled
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
a. Append fulfillReaction as the last element of the List that is the
value of promise's [[PromiseFulfillReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var resolve;
var p1 = new Promise(function(_resolve) { resolve = _resolve; });
var p2;
p2 = p1.then(function() {
return p2;
});
p2.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(reason) {
if (!reason) {
$DONE('The promise should be rejected with a value.');
return;
}
if (reason.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});
resolve();

View File

@ -0,0 +1,51 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value from a pending promise that is later fulfilled
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
a. Append fulfillReaction as the last element of the List that is the
value of promise's [[PromiseFulfillReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var resolve;
var thenable = new Promise(function(resolve) { resolve(value); });
var p1 = new Promise(function(_resolve) { resolve = _resolve; });
var p2;
p2 = p1.then(function() {
return thenable;
});
p2.then(function(x) {
if (x !== value) {
$DONE('The promise should be fulfilled with the resolution value of the provided promise.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve();

View File

@ -0,0 +1,43 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value from a pending promise that is later rejected
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
[...]
b. Append rejectReaction as the last element of the List that is the
value of promise's [[PromiseRejectReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var reject;
var p1 = new Promise(function(_, _reject) { reject = _reject; });
var p2;
p2 = p1.then(function() {}, function() {
return 23;
});
p2.then(function(value) {
if (value !== 23) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
reject();

View File

@ -0,0 +1,49 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value from a pending promise that is later rejected
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
[...]
b. Append rejectReaction as the last element of the List that is the
value of promise's [[PromiseRejectReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var reject;
var p1 = new Promise(function(_, _reject) { reject = _reject; });
var p2;
p2 = p1.then(function() {}, function() {
return nonThenable;
});
p2.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
reject();

View File

@ -0,0 +1,51 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property from a pending promise that is later rejected
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
[...]
b. Append rejectReaction as the last element of the List that is the
value of promise's [[PromiseRejectReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var reject;
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var p1 = new Promise(function(_, _reject) { reject = _reject; });
var p2;
p2 = p1.then(function() {}, function() {
return poisonedThen;
});
p2.then(function(x) {
$DONE('The promise should not be fulfilled.');
}, function(x) {
if (x !== value) {
$DONE('The promise should be rejected with the thrown exception.');
return;
}
$DONE();
});
reject();

View File

@ -0,0 +1,50 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself from a pending promise that is later rejected
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
[...]
b. Append rejectReaction as the last element of the List that is the
value of promise's [[PromiseRejectReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var reject;
var p1 = new Promise(function(_, _reject) { reject = _reject; });
var p2;
p2 = p1.then(function() {}, function() {
return p2;
});
p2.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(reason) {
if (!reason) {
$DONE('The promise should be rejected with a value.');
return;
}
if (reason.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});
reject();

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value from a pending promise that is later rejected
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
7. If the value of promise's [[PromiseState]] internal slot is "pending",
[...]
b. Append rejectReaction as the last element of the List that is the
value of promise's [[PromiseRejectReactions]] internal slot.
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var reject;
var thenable = new Promise(function(resolve) { resolve(value); });
var p1 = new Promise(function(_, _reject) { reject = _reject; });
var p2;
p2 = p1.then(function() {}, function() {
return thenable;
});
p2.then(function(x) {
if (x !== value) {
$DONE('The promise should be fulfilled with the resolution value of the provided promise.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
reject();

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value from a fulfilled promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
value»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var p1 = new Promise(function(resolve) { resolve(); });
var p2;
p2 = p1.then(function() {
return 23;
});
p2.then(function(value) {
if (value !== 23) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value from a fulfilled promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
value»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var p1 = new Promise(function(resolve) { resolve(); });
var p2;
p2 = p1.then(function() {
return nonThenable;
});
p2.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,54 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property from a fulfilled promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
value»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var p1 = new Promise(function(resolve) { resolve(); });
var p2;
p2 = p1.then(function() {
return poisonedThen;
});
p2.then(function(x) {
$DONE('The promise should not be fulfilled.');
}, function(x) {
if (x !== value) {
$DONE('The promise should be rejected with the thrown exception.');
return;
}
$DONE();
});

View File

@ -0,0 +1,53 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself from a fulfilled promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
value»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var p1 = new Promise(function(resolve) { resolve(); });
var p2;
p2 = p1.then(function() {
return p2;
});
p2.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(reason) {
if (!reason) {
$DONE('The promise should be rejected with a value.');
return;
}
if (reason.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});

View File

@ -0,0 +1,55 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value from a fulfilled promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
8. Else if the value of promise's [[PromiseState]] internal slot is
"fulfilled",
a. Let value be the value of promise's [[PromiseResult]] internal slot.
b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
value»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var thenable = new Promise(function(resolve) { resolve(value); });
var p1 = new Promise(function(resolve) { resolve(); });
var p2;
p2 = p1.then(function() {
return thenable;
});
p2.then(function(x) {
if (x !== value) {
$DONE('The promise should be fulfilled with the resolution value of the provided promise.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value from a rejected promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
9. Else if the value of promise's [[PromiseState]] internal slot is
"rejected",
a. Let reason be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«rejectReaction, reason»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var p1 = new Promise(function(_, reject) { reject(); });
var p2;
p2 = p1.then(function() {}, function() {
return 23;
});
p2.then(function(value) {
if (value !== 23) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value from a rejected promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
9. Else if the value of promise's [[PromiseState]] internal slot is
"rejected",
a. Let reason be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«rejectReaction, reason»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var p1 = new Promise(function(_, reject) { reject(); });
var p2;
p2 = p1.then(function() {}, function() {
return nonThenable;
});
p2.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,54 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property from a rejected promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
9. Else if the value of promise's [[PromiseState]] internal slot is
"rejected",
a. Let reason be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«rejectReaction, reason»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var p1 = new Promise(function(_, reject) { reject(); });
var p2;
p2 = p1.then(function() {}, function() {
return poisonedThen;
});
p2.then(function(x) {
$DONE('The promise should not be fulfilled.');
}, function(x) {
if (x !== value) {
$DONE('The promise should be rejected with the thrown exception.');
return;
}
$DONE();
});

View File

@ -0,0 +1,53 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself from a rejected promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
9. Else if the value of promise's [[PromiseState]] internal slot is
"rejected",
a. Let reason be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«rejectReaction, reason»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var p1 = new Promise(function(_, reject) { reject(); });
var p2;
p2 = p1.then(function() {}, function() {
return p2;
});
p2.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(reason) {
if (!reason) {
$DONE('The promise should be rejected with a value.');
return;
}
if (reason.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});

View File

@ -0,0 +1,55 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value from a rejected promise
es6id: 25.4.5.3
info: >
[...]
7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
resultCapability).
25.4.5.3.1 PerformPromiseThen
[...]
9. Else if the value of promise's [[PromiseState]] internal slot is
"rejected",
a. Let reason be the value of promise's [[PromiseResult]] internal slot.
b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
«rejectReaction, reason»).
25.4.2.1 PromiseReactionJob
[...]
8. Let status be Call(promiseCapability.[[Resolve]], undefined,
«handlerResult.[[value]]»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var thenable = new Promise(function(resolve) { resolve(value); });
var p1 = new Promise(function(_, reject) { reject(); });
var p2;
p2 = p1.then(function() {}, function() {
return thenable;
});
p2.then(function(x) {
if (x !== value) {
$DONE('The promise should be fulfilled with the resolution value of the provided promise.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value
es6id: 25.4.4.3
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var thenable = {
then: function(resolve) {
resolve(23);
}
};
Promise.race([thenable])
.then(function(value) {
if (value !== 23) {
$DONE('The promise should be resolved with the correct value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,45 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value
es6id: 25.4.4.3
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var value = {};
var thenable = {
then: function(resolve) {
resolve(value);
}
};
Promise.race([thenable])
.then(function(val) {
if (val !== value) {
$DONE('The promise should be resolved with the correct value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,46 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" `then` property
es6id: 25.4.4.3
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var thenable = {
then: function(resolve) {
resolve(poisonedThen);
}
};
Promise.race([thenable])
.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(val) {
if (val !== value) {
$DONE('The promise should be rejected with the correct value.');
return;
}
$DONE();
});

View File

@ -0,0 +1,54 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself
es6id: 25.4.4.3
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var self, resolve;
var builtinResolve = Promise.resolve;
var thenable = {
then: function(r) {
resolve = r;
}
};
try {
Promise.resolve = function(v) { return v; };
self = Promise.race([thenable]);
} finally {
Promise.resolve = builtinResolve;
}
resolve(self);
self.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(value) {
if (!value) {
$DONE('The promise should be rejected with a value.');
return;
}
if (value.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value
es6id: 25.4.4.3
info: >
[...]
6. Let promiseCapability be NewPromiseCapability(C).
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var thenableValue = {
then: function(resolve) {
resolve(value);
}
};
var thenable = {
then: function(resolve) {
resolve(thenableValue);
}
};
Promise.race([thenable])
.then(function(val) {
if (val !== value) {
$DONE('The promise should be resolved with the correct value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with a non-object value after invocation of the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var resolve;
var promise = new Promise(function(_resolve) {
resolve = _resolve;
});
promise.then(function(value) {
if (value !== 45) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve(45);

View File

@ -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.
/*---
description: Resolving with a non-object value from within the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var promise = new Promise(function(resolve) {
resolve(45);
});
promise.then(function(value) {
if (value !== 45) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with a non-thenable object value after invocation of the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var resolve;
var promise = new Promise(function(_resolve) {
resolve = _resolve;
});
promise.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve(nonThenable);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with a non-thenable object value from within the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var nonThenable = { then: null };
var promise = new Promise(function(resolve) {
resolve(nonThenable);
});
promise.then(function(value) {
if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,41 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with an object with a "poisoned" `then` property after invocation
of the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var value = {};
var resolve;
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var promise = new Promise(function(_resolve) {
resolve = _resolve;
});
promise.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(val) {
if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
});
resolve(poisonedThen);

View File

@ -0,0 +1,38 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with an object with a "poisoned" `then` property from within the
executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
var value = {};
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
var promise = new Promise(function(resolve) {
resolve(poisonedThen);
});
promise.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(val) {
if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
});

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var resolve;
var promise = new Promise(function(_resolve) {
resolve = _resolve;
});
promise.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(reason) {
if (!reason) {
$DONE('The promise should be rejected with a value.');
return;
}
if (reason.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});
resolve(promise);

View File

@ -0,0 +1,44 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with a thenable object value after execution of the executor
function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var resolve;
var thenable = new Promise(function(resolve) { resolve(value); });
var promise = new Promise(function(_resolve) {
resolve = _resolve;
});
promise.then(function(val) {
if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});
resolve(thenable);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolving with a thenable object value from within the executor function
es6id: 25.4.3.1
info: >
[...]
8. Let resolvingFunctions be CreateResolvingFunctions(promise).
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var thenable = new Promise(function(resolve) { resolve(value); });
var promise = new Promise(function(resolve) {
resolve(thenable);
});
promise.then(function(val) {
if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,27 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-object value
es6id: 25.4.4.5
info: >
[...]
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
«x»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
7. If Type(resolution) is not Object, then
a. Return FulfillPromise(promise, resolution).
---*/
Promise.resolve(23).then(function(value) {
if (value !== 23) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,33 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a non-thenable object value
es6id: 25.4.4.5
info: >
[...]
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
«x»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
a. Return FulfillPromise(promise, resolution).
---*/
var value = {};
Promise.resolve(value).then(function(value) {
if (value !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});

View File

@ -0,0 +1,36 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with an object with a "poisoned" then property
es6id: 25.4.4.5
info: >
[...]
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
«x»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
a. Return RejectPromise(promise, then.[[value]]).
---*/
var value = {};
var resolve;
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw value;
}
});
Promise.resolve(poisonedThen).then(function() {
$DONE('The promise should not be fulfilled.');
}, function(val) {
if (val !== value) {
$DONE('The promise should be rejected with the provided value.');
return;
}
$DONE();
});

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a reference to the promise itself
es6id: 25.4.4.5
info: >
1. Let C be the this value.
[...]
4. Let promiseCapability be NewPromiseCapability(C).
[...]
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
«x»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
6. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Return RejectPromise(promise, selfResolutionError).
---*/
var resolve, reject;
var promise = new Promise(function(_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
var P = function(executor) {
executor(resolve, reject);
return promise;
};
Promise.resolve.call(P, promise)
.then(function() {
$DONE('The promise should not be fulfilled.');
}, function(value) {
if (!value) {
$DONE('The promise should be rejected with a value.');
return;
}
if (value.constructor !== TypeError) {
$DONE('The promise should be rejected with a TypeError instance.');
return;
}
$DONE();
});

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Resolving with a thenable object value
es6id: 25.4.4.5
info: >
[...]
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
«x»).
[...]
25.4.1.3.2 Promise Resolve Functions
[...]
8. Let then be Get(resolution, "then").
9. If then is an abrupt completion, then
[...]
10. Let thenAction be then.[[value]].
11. If IsCallable(thenAction) is false, then
[...]
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
«promise, resolution, thenAction»)
---*/
var value = {};
var thenable = {
then: function(resolve) {
resolve(value);
}
};
Promise.resolve(thenable).then(function(val) {
if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.');
return;
}
$DONE();
}, function() {
$DONE('The promise should not be rejected.');
});