Merge pull request #701 from bocoup/audit2016-section-25-promises

Extend coverage for Section 25 - Promises
This commit is contained in:
Tom Care 2016-10-20 13:02:49 -07:00 committed by GitHub
commit f39b7cfb7a
57 changed files with 1376 additions and 85 deletions

View File

@ -0,0 +1,69 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.all
es6id: 25.4.4.1
description: >
Iterator is not closed when the "resolve" capability returns an abrupt
completion.
info: |
1. Let C be the this value.
[...]
3. Let promiseCapability be ? NewPromiseCapability(C).
[...]
7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
8. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
d. If next is false, then
[...]
iii. If remainingElementsCount.[[Value]] is 0, then
1. Let valuesArray be CreateArrayFromList(values).
2. Perform ? Call(resultCapability.[[Resolve]], undefined, «
valuesArray »).
25.4.1.1.1 IfAbruptRejectPromise
IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that
use a PromiseCapability Record. An algorithm step of the form:
1. IfAbruptRejectPromise(value, capability).
means the same thing as:
1. If value is an abrupt completion, then
a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
b. Return capability.[[Promise]].
2. Else if value is a Completion Record, let value be value.[[Value]].
features: [Symbol.iterator]
---*/
var returnCount = 0;
var iter = {};
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: true };
},
return: function() {
returnCount += 1;
return {};
}
};
};
var P = function(executor) {
return new Promise(function(_, reject) {
executor(function() { throw new Test262Error(); }, reject);
});
};
Promise.all.call(P, iter);
assert.sameValue(returnCount, 0);

View File

@ -0,0 +1,64 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.all
es6id: 25.4.4.1
description: >
Promise is rejected when the "resolve" capability returns an abrupt
completion.
info: |
1. Let C be the this value.
[...]
3. Let promiseCapability be ? NewPromiseCapability(C).
[...]
7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
8. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
d. If next is false, then
[...]
iii. If remainingElementsCount.[[Value]] is 0, then
1. Let valuesArray be CreateArrayFromList(values).
2. Perform ? Call(resultCapability.[[Resolve]], undefined, «
valuesArray »).
25.4.1.1.1 IfAbruptRejectPromise
IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that
use a PromiseCapability Record. An algorithm step of the form:
1. IfAbruptRejectPromise(value, capability).
means the same thing as:
1. If value is an abrupt completion, then
a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
b. Return capability.[[Promise]].
2. Else if value is a Completion Record, let value be value.[[Value]].
flags: [async]
---*/
var thrown = new Test262Error();
var P = function(executor) {
return new Promise(function(_, reject) {
executor(function() { throw thrown; }, reject);
});
};
Promise.all.call(P, [])
.then(function() {
$DONE('Promise incorrectly fulfilled.');
}, function(reason) {
if (reason !== thrown) {
$DONE('Promise rejected with incorrect "reason."');
return;
}
$DONE();
});

View File

@ -4,8 +4,9 @@
/*--- /*---
description: > description: >
Explicit iterator closing in response to error Explicit iterator closing in response to error
esid: sec-promise.all
es6id: 25.4.4.1 es6id: 25.4.4.1
info: > info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

View File

@ -0,0 +1,39 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Promise rejection in response to error
esid: sec-promise.all
es6id: 25.4.4.1
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
j. ReturnIfAbrupt(nextPromise ).
flags: [async]
---*/
var thrown = new Test262Error();
Promise.resolve = function() {
throw thrown;
};
Promise.all([1])
.then(function() {
$ERROR('The promise should not be fulfilled.');
}, function(reason) {
if (reason !== thrown) {
$ERROR('The promise should be rejected with the thrown error object');
}
}).then($DONE, $DONE);

View File

@ -0,0 +1,49 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error retrieving the constructor's `resolve` method (closing iterator)
esid: sec-performpromiseall
es6id: 25.4.4.1
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
j. ReturnIfAbrupt(nextPromise ).
features: [Symbol.iterator]
---*/
var iter = {};
var returnCount = 0;
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
returnCount += 1;
return {};
}
};
};
Object.defineProperty(Promise, 'resolve', {
get: function() {
throw new Test262Error();
}
});
Promise.all(iter);
assert.sameValue(returnCount, 1);

View File

@ -3,9 +3,10 @@
/*--- /*---
description: > description: >
Error retrieving the constructor's `resolve` method Error retrieving the constructor's `resolve` method (rejecting promise)
esid: sec-performpromiseall
es6id: 25.4.4.1 es6id: 25.4.4.1
info: > info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be
@ -26,7 +27,7 @@ flags: [async]
var error = new Test262Error(); var error = new Test262Error();
Object.defineProperty(Promise, 'resolve', { Object.defineProperty(Promise, 'resolve', {
get: function() { get: function() {
throw error; throw error;
} }
}); });

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: >
Error thrown when invoking the instance's `then` method (closing iterator)
esid: sec-performpromiseall
es6id: 25.4.4.1
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
r. Let result be Invoke(nextPromise, "then", «resolveElement,
resultCapability.[[Reject]]»).
s. ReturnIfAbrupt(result).
features: [Symbol.iterator]
---*/
var promise = new Promise(function() {});
var returnCount = 0;
var iter = {};
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false, value: promise };
},
return: function() {
returnCount += 1;
return {};
}
};
};
promise.then = function() {
throw new Test262Error();
};
Promise.all(iter);
assert.sameValue(returnCount, 1);

View File

@ -3,9 +3,10 @@
/*--- /*---
description: > description: >
Error thrown when invoking the instance's `then` method Error thrown when invoking the instance's `then` method (rejecting Promise)
esid: sec-performpromiseall
es6id: 25.4.4.1 es6id: 25.4.4.1
info: > info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

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: >
Error thrown when accesing the instance's `then` method (closing iterator)
esid: sec-performpromiseall
es6id: 25.4.4.1
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
r. Let result be Invoke(nextPromise, "then", «resolveElement,
resultCapability.[[Reject]]»).
s. ReturnIfAbrupt(result).
features: [Symbol.iterator]
---*/
var promise = new Promise(function() {});
var returnCount = 0;
var iter = {};
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false, value: promise };
},
return: function() {
returnCount += 1;
return {};
}
};
};
Object.defineProperty(promise, 'then', {
get: function() {
throw new Test262Error();
}
});
Promise.all(iter);
assert.sameValue(returnCount, 1);

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: >
Error thrown when accessing the instance's `then` method (rejecting Promise)
esid: sec-performpromiseall
es6id: 25.4.4.1
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
r. Let result be Invoke(nextPromise, "then", «resolveElement,
resultCapability.[[Reject]]»).
s. ReturnIfAbrupt(result).
flags: [async]
---*/
var promise = new Promise(function() {});
var error = new Test262Error();
Object.defineProperty(promise, 'then', {
get: function() {
throw error;
}
});
Promise.all([promise]).then(function() {
$ERROR('The promise should be rejected');
}, function(reason) {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,56 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.all
es6id: 25.4.4.1
description: >
Error when accessing an iterator result's `value` property (not closing
iterator)
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
[...]
e. Let nextValue be IteratorValue(next).
f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
true.
g. ReturnIfAbrupt(nextValue).
features: [Symbol.iterator]
---*/
var iterNextValThrows = {};
var returnCount = 0;
var poisonedVal = {
done: false
};
var error = new Test262Error();
Object.defineProperty(poisonedVal, 'value', {
get: function() {
throw error;
}
});
iterNextValThrows[Symbol.iterator] = function() {
return {
next: function() {
return poisonedVal;
},
return: function() {
returnCount += 1;
return {};
}
};
};
Promise.all(iterNextValThrows);
assert.sameValue(returnCount, 0);

View File

@ -2,10 +2,12 @@
// This code is governed by the BSD license found in the LICENSE file. // This code is governed by the BSD license found in the LICENSE file.
/*--- /*---
description: > esid: sec-promise.all
Error when accessing an iterator result's `value` property
es6id: 25.4.4.1 es6id: 25.4.4.1
info: > description: >
Error when accessing an iterator result's `value` property (rejecting
promise)
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

View File

@ -0,0 +1,58 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.all
es6id: 25.4.4.1
description: >
Error when advancing the provided iterable (not closing iterator)
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
[...]
6. Repeat
a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
b. If next is an abrupt completion, set iteratorRecord.[[done]] to
true.
c. ReturnIfAbrupt(next).
features: [Symbol.iterator]
---*/
var iterStepThrows = {};
var poisonedDone = {};
var returnCount = 0;
var error = new Test262Error();
Object.defineProperty(poisonedDone, 'done', {
get: function() {
throw error;
}
});
Object.defineProperty(poisonedDone, 'value', {
get: function() {
$ERROR('The `value` property should not be accessed.');
}
});
iterStepThrows[Symbol.iterator] = function() {
return {
next: function() {
return poisonedDone;
},
return: function() {
returnCount += 1;
return {};
}
};
};
Promise.all(iterStepThrows);
assert.sameValue(returnCount, 0);

View File

@ -2,10 +2,11 @@
// This code is governed by the BSD license found in the LICENSE file. // This code is governed by the BSD license found in the LICENSE file.
/*--- /*---
description: > esid: sec-promise.all
Error when advancing the provided iterable
es6id: 25.4.4.1 es6id: 25.4.4.1
info: > description: >
Error when advancing the provided iterable (rejecting promise)
info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

View File

@ -1,14 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: >
Promise prototype object is an ordinary object
es6id: S25.4.5_A1.1_T1
author: Sam Mikes
description: Promise prototype does not have [[PromiseState]] internal slot
---*/
assert.throws(TypeError, function() {
Promise.call(Promise.prototype, function () {});
});

View File

@ -1,15 +0,0 @@
// Copyright 2014 Cubane Canada, Inc. All rights reserved.
// See LICENSE for details.
/*---
info: >
Promise prototype object is an ordinary object
es6id: S25.4.5_A2.1_T1
author: Sam Mikes
description: Promise prototype is a standard built-in Object
---*/
if (!(Promise.prototype instanceof Object)) {
$ERROR("Expected Promise.prototype to be an Object");
}

View File

@ -0,0 +1,31 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.prototype.catch
es6id: 25.4.5.1
description: >
Promise.prototype.catch called with a non-object-coercible `this` value
info: |
1. Let promise be the this value.
2. Return ? Invoke(promise, "then", «undefined, onRejected»).
7.3.18 Invoke
1. Assert: IsPropertyKey(P) is true.
2. If argumentsList was not passed, let argumentsList be a new empty List.
3. Let func be ? GetV(V, P).
4. Return ? Call(func, V, argumentsList).
7.3.2 GetV
1. Assert: IsPropertyKey(P) is true.
2. Let O be ? ToObject(V).
---*/
assert.throws(TypeError, function() {
Promise.prototype.catch.call(undefined);
}, 'undefined');
assert.throws(TypeError, function() {
Promise.prototype.catch.call(null);
}, 'null');

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.
/*---
esid: sec-promise.prototype.catch
es6id: 25.4.5.1
description: >
Promise.prototype.catch called with an object-coercible `this` value
info: |
1. Let promise be the this value.
2. Return ? Invoke(promise, "then", «undefined, onRejected»).
7.3.18 Invoke
1. Assert: IsPropertyKey(P) is true.
2. If argumentsList was not passed, let argumentsList be a new empty List.
3. Let func be ? GetV(V, P).
4. Return ? Call(func, V, argumentsList).
7.3.2 GetV
1. Assert: IsPropertyKey(P) is true.
2. Let O be ? ToObject(V).
features: [Symbol]
---*/
var booleanCount = 0;
Boolean.prototype.then = function() { booleanCount += 1; };
Promise.prototype.catch.call(true);
assert.sameValue(booleanCount, 1, 'boolean');
var numberCount = 0;
Number.prototype.then = function() { numberCount += 1; };
Promise.prototype.catch.call(34);
assert.sameValue(numberCount, 1, 'number');
var stringCount = 0;
String.prototype.then = function() { stringCount += 1; };
Promise.prototype.catch.call('');
assert.sameValue(stringCount, 1, 'string');
var symbolCount = 0;
Symbol.prototype.then = function() { symbolCount += 1; };
Promise.prototype.catch.call(Symbol());
assert.sameValue(symbolCount, 1, 'symbol');

View File

@ -0,0 +1,62 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.prototype.catch
es6id: 25.4.5.1
description: >
Promise.prototype.catch called with a `this` value that does not define a
callable `this` property
info: |
1. Let promise be the this value.
2. Return ? Invoke(promise, "then", «undefined, onRejected»).
7.3.18 Invoke
1. Assert: IsPropertyKey(P) is true.
2. If argumentsList was not passed, let argumentsList be a new empty List.
3. Let func be ? GetV(V, P).
4. Return ? Call(func, V, argumentsList).
7.3.2 GetV
1. Assert: IsPropertyKey(P) is true.
2. Let O be ? ToObject(V).
3. Return ? O.[[Get]](P, V).
7.3.12 Call (F, V [ , argumentsList ])
1. If argumentsList was not passed, let argumentsList be a new empty List.
2. If IsCallable(F) is false, throw a TypeError exception.
3. Return ? F.[[Call]](V, argumentsList).
features: [Symbol]
---*/
var symbol = Symbol();
assert.throws(TypeError, function() {
Promise.prototype.catch.call({});
}, 'undefined');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: null });
}, 'null');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: 1 });
}, 'number');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: '' });
}, 'string');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: true });
}, 'boolean');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: symbol });
}, 'symbol');
assert.throws(TypeError, function() {
Promise.prototype.catch.call({ then: {} });
}, 'ordinary object');

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.
/*---
esid: sec-promise.prototype.catch
es6id: 25.4.5.1
description: >
Promise.prototype.catch called with a `this` value whose `then` property is
an accessor property that returns an abrupt completion
info: |
1. Let promise be the this value.
2. Return ? Invoke(promise, "then", «undefined, onRejected»).
7.3.18 Invoke
1. Assert: IsPropertyKey(P) is true.
2. If argumentsList was not passed, let argumentsList be a new empty List.
3. Let func be ? GetV(V, P).
7.3.2 GetV
1. Assert: IsPropertyKey(P) is true.
2. Let O be ? ToObject(V).
3. Return ? O.[[Get]](P, V).
---*/
var poisonedThen = Object.defineProperty({}, 'then', {
get: function() {
throw new Test262Error();
}
});
assert.throws(Test262Error, function() {
Promise.prototype.catch.call(poisonedThen);
});

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.
/*---
esid: sec-promise.prototype.catch
es6id: 25.4.5.1
description: >
Promise.prototype.catch called with a `this` value that defines a `then`
method which returns an abrupt completion.
info: |
1. Let promise be the this value.
2. Return ? Invoke(promise, "then", «undefined, onRejected»).
7.3.18 Invoke
1. Assert: IsPropertyKey(P) is true.
2. If argumentsList was not passed, let argumentsList be a new empty List.
3. Let func be ? GetV(V, P).
4. Return ? Call(func, V, argumentsList).
7.3.2 GetV
1. Assert: IsPropertyKey(P) is true.
2. Let O be ? ToObject(V).
3. Return ? O.[[Get]](P, V).
7.3.12 Call (F, V [ , argumentsList ])
1. If argumentsList was not passed, let argumentsList be a new empty List.
2. If IsCallable(F) is false, throw a TypeError exception.
3. Return ? F.[[Call]](V, argumentsList).
---*/
var thrower = {
then: function() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
Promise.prototype.catch.call(thrower);
});

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.
/*---
esid: sec-properties-of-the-promise-prototype-object
es6id: 25.4.5
description: Promise.prototype does not have a [[PromiseState]] internal slot
info: |
The Promise prototype object is the intrinsic object %PromisePrototype%. The
value of the [[Prototype]] internal slot of the Promise prototype object is
the intrinsic object %ObjectPrototype%. The Promise prototype object is an
ordinary object. It does not have a [[PromiseState]] internal slot or any of
the other internal slots of Promise instances.
25.4.5.3 Promise.prototype.then
1. Let promise be the this value.
2. If IsPromise(promise) is false, throw a TypeError exception.
25.4.1.6 IsPromise
1. If Type(x) is not Object, return false.
2. If x does not have a [[PromiseState]] internal slot, return false.
---*/
assert.throws(TypeError, function() {
Promise.prototype.then.call(Promise.prototype, function() {}, function() {});
});

View File

@ -0,0 +1,15 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.prototype
es6id: 25.4.4.2
description: Property descriptor of 'prototype' property
info: >
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
false, [[Configurable]]: false }.
includes: [propertyHelper.js]
---*/
verifyNotEnumerable(Promise, 'prototype');
verifyNotWritable(Promise, 'prototype');
verifyNotConfigurable(Promise, 'prototype');

View File

@ -0,0 +1,15 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-properties-of-the-promise-prototype-object
es6id: 25.4.5
description: Promise.prototype [[Prototype]] is %ObjectPrototype%
info: |
The Promise prototype object is the intrinsic object %PromisePrototype%. The
value of the [[Prototype]] internal slot of the Promise prototype object is
the intrinsic object %ObjectPrototype%. The Promise prototype object is an
ordinary object. It does not have a [[PromiseState]] internal slot or any of
the other internal slots of Promise instances.
---*/
assert.sameValue(Object.getPrototypeOf(Promise.prototype), Object.prototype);

View File

@ -0,0 +1,47 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Explicit iterator closing in response to error from `Promise.resolve`
esid: sec-promise.race
es6id: 25.4.4.3
info: |
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
12. If result is an abrupt completion, then
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator,result).
b. IfAbruptRejectPromise(result, promiseCapability).
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
i. ReturnIfAbrupt(nextPromise).
features: [Symbol.iterator]
---*/
var iterDoneSpy = {};
var returnCount = 0;
iterDoneSpy[Symbol.iterator] = function() {
return {
next: function() {
return { value: null, done: false };
},
return: function() {
returnCount += 1;
return {};
}
};
};
Promise.resolve = function() {
throw err;
};
Promise.race(iterDoneSpy);
assert.sameValue(returnCount, 1);

View File

@ -2,10 +2,11 @@
// This code is governed by the BSD license found in the LICENSE file. // This code is governed by the BSD license found in the LICENSE file.
/*--- /*---
description: > description: Promise rejection in response to error from `Promise.resolve`
Explicit iterator closing in response to error esid: sec-promise.race
es6id: 25.4.4.3 es6id: 25.4.4.3
info: > info: |
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
12. If result is an abrupt completion, then 12. If result is an abrupt completion, then
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be
@ -19,37 +20,22 @@ info: >
[...] [...]
h. Let nextPromise be Invoke(C, "resolve", «nextValue»). h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
i. ReturnIfAbrupt(nextPromise). i. ReturnIfAbrupt(nextPromise).
features: [Symbol.iterator]
flags: [async] flags: [async]
---*/ ---*/
var err = new Test262Error(); var err = new Test262Error();
var iterDoneSpy = {};
var callCount = 0;
var CustomPromise = function(executor) { var CustomPromise = function(executor) {
return new Promise(executor); return new Promise(executor);
}; };
iterDoneSpy[Symbol.iterator] = function() {
return {
next: function() {
return { value: null, done: false };
},
return: function() {
callCount += 1;
}
};
};
CustomPromise.resolve = function() { CustomPromise.resolve = function() {
throw err; throw err;
}; };
Promise.race.call(CustomPromise, iterDoneSpy) Promise.race.call(CustomPromise, [1])
.then(function() { .then(function() {
$ERROR('The promise should be rejected.'); $ERROR('The promise should be rejected.');
}, function(reason) { }, function(reason) {
assert.sameValue(reason, err); assert.sameValue(reason, err);
$DONE(); $DONE();
}); });
assert.sameValue(callCount, 1);

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: >
Error retrieving the constructor's `resolve` method (iterator closing)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
i. ReturnIfAbrupt(nextPromise).
features: [Symbol.iterator]
---*/
var iter = {};
var returnCount = 0;
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
returnCount += 1;
return {};
}
};
};
Object.defineProperty(Promise, 'resolve', {
get: function() {
throw new Test262Error();
}
});
Promise.race(iter);
assert.sameValue(returnCount, 1);

View File

@ -3,9 +3,10 @@
/*--- /*---
description: > description: >
Error retrieving the constructor's `resolve` method Error retrieving the constructor's `resolve` method (promise rejection)
esid: sec-promise.race
es6id: 25.4.4.3 es6id: 25.4.4.3
info: > info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be
@ -25,7 +26,7 @@ flags: [async]
var error = new Test262Error(); var error = new Test262Error();
Object.defineProperty(Promise, 'resolve', { Object.defineProperty(Promise, 'resolve', {
get: function() { get: function() {
throw error; throw error;
} }
}); });

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: >
Error thrown when invoking the instance's `then` method (closing iterator)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
k. ReturnIfAbrupt(result).
features: [Symbol.iterator]
---*/
var promise = new Promise(function() {});
var iter = {};
var returnCount = 0;
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false, value: promise };
},
return: function() {
returnCount += 1;
return {};
}
};
};
promise.then = function() {
throw new Test262Error();
};
Promise.race(iter);
assert.sameValue(returnCount, 1);

View File

@ -3,9 +3,10 @@
/*--- /*---
description: > description: >
Error thrown when invoking the instance's `then` method Error thrown when invoking the instance's `then` method (rejecting promise)
esid: sec-promise.race
es6id: 25.4.4.3 es6id: 25.4.4.3
info: > info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

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: >
Error thrown when accessing the instance's `then` method (closing iterator)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
k. ReturnIfAbrupt(result).
features: [Symbol.iterator]
---*/
var promise = new Promise(function() {});
var iter = {};
var returnCount = 0;
iter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false, value: promise };
},
return: function() {
returnCount += 1;
return {};
}
};
};
Object.defineProperty(promise, 'then', {
get: function() {
throw new Test262Error();
}
});
Promise.race(iter);
assert.sameValue(returnCount, 1);

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: >
Error thrown when accessing the instance's `then` method (rejecting promise)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
j. Let result be Invoke(nextPromise, "then",
«promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
k. ReturnIfAbrupt(result).
flags: [async]
---*/
var promise = new Promise(function() {});
var error = new Test262Error();
Object.defineProperty(promise, 'then', {
get: function() {
throw error;
}
});
Promise.race([promise]).then(function() {
$ERROR('The promise should be rejected');
}, function(reason) {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

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: >
Error when accessing an iterator result's `value` property (not closing
iterator)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability).
[...]
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
[...]
e. Let nextValue be IteratorValue(next).
f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
true.
g. ReturnIfAbrupt(nextValue).
features: [Symbol.iterator]
---*/
var iterNextValThrows = {};
var returnCount = 0;
var poisonedVal = {
done: false
};
var error = new Test262Error();
Object.defineProperty(poisonedVal, 'value', {
get: function() {
throw error;
}
});
iterNextValThrows[Symbol.iterator] = function() {
return {
next: function() {
return poisonedVal;
},
return: function() {
returnCount += 1;
}
};
};
Promise.race(iterNextValThrows);
assert.sameValue(returnCount, 0);

View File

@ -3,9 +3,11 @@
/*--- /*---
description: > description: >
Error when accessing an iterator result's `value` property Error when accessing an iterator result's `value` property (rejecting
promise)
esid: sec-promise.race
es6id: 25.4.4.3 es6id: 25.4.4.3
info: > info: |
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
a. If iteratorRecord.[[done]] is false, let result be a. If iteratorRecord.[[done]] is false, let result be

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: >
Error when advancing the provided iterable (not closing iterator)
esid: sec-promise.race
es6id: 25.4.4.3
info: |
[...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
12. If result is an abrupt completion, then
a. If iteratorRecord.[[done]] is false, let result be
IteratorClose(iterator,result).
b. IfAbruptRejectPromise(result, promiseCapability).
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
1. Repeat
a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
c. ReturnIfAbrupt(next).
features: [Symbol.iterator]
---*/
var iterStepThrows = {};
var poisonedDone = {};
var returnCount = 0;
var error = new Test262Error();
Object.defineProperty(poisonedDone, 'done', {
get: function() {
throw error;
}
});
Object.defineProperty(poisonedDone, 'value', {
get: function() {
$ERROR('The `value` property should not be accessed.');
}
});
iterStepThrows[Symbol.iterator] = function() {
return {
next: function() {
return poisonedDone;
},
return: function() {
returnCount += 1;
}
};
};
Promise.race(iterStepThrows);
assert.sameValue(returnCount, 0);

View File

@ -3,9 +3,10 @@
/*--- /*---
description: > description: >
Error when advancing the provided iterable Error when advancing the provided iterable (rejecting promise)
esid: sec-promise.race
es6id: 25.4.4.3 es6id: 25.4.4.3
info: > info: |
[...] [...]
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
12. If result is an abrupt completion, then 12. If result is an abrupt completion, then

View File

@ -21,6 +21,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var thenable = new Promise(function() {}); var thenable = new Promise(function() {});
var resolve, reject; var resolve, reject;
var p = new Promise(function(_resolve, _reject) { var p = new Promise(function(_resolve, _reject) {
@ -35,4 +36,6 @@ p.then(function() {
}); });
resolve(); resolve();
reject(thenable); returnValue = reject(thenable);
assert.sameValue(returnValue, undefined, '"reject" function return value');

View File

@ -21,12 +21,15 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var thenable = new Promise(function() {}); var thenable = new Promise(function() {});
var p = new Promise(function(resolve, reject) { var p = new Promise(function(resolve, reject) {
resolve(); resolve();
reject(thenable); returnValue = reject(thenable);
}); });
assert.sameValue(returnValue, undefined, '"reject" function return value');
p.then(function() { p.then(function() {
$DONE(); $DONE();
}, function() { }, function() {

View File

@ -18,6 +18,7 @@ flags: [async]
---*/ ---*/
var thenable = new Promise(function() {}); var thenable = new Promise(function() {});
var returnValue = null;
var reject; var reject;
var p = new Promise(function(_, _reject) { var p = new Promise(function(_, _reject) {
reject = _reject; reject = _reject;
@ -34,4 +35,6 @@ p.then(function() {
$DONE(); $DONE();
}); });
reject(thenable); returnValue = reject(thenable);
assert.sameValue(returnValue, undefined, '"reject" function return value');

View File

@ -18,10 +18,13 @@ flags: [async]
---*/ ---*/
var thenable = new Promise(function() {}); var thenable = new Promise(function() {});
var returnValue = null;
var p = new Promise(function(_, reject) { var p = new Promise(function(_, reject) {
reject(thenable); returnValue = reject(thenable);
}); });
assert.sameValue(returnValue, undefined, '"reject" function return value');
p.then(function() { p.then(function() {
$DONE('The promise should not be fulfilled.'); $DONE('The promise should not be fulfilled.');
}, function(x) { }, function(x) {

View File

@ -0,0 +1,32 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Abrupt completion returned by "reject" capability
esid: sec-promise.reject
es6id: 25.4.4.4
info: |
1. Let C be the this value.
[...]
3. Let promiseCapability be ? NewPromiseCapability(C).
4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
25.4.1.5 NewPromiseCapability
[...]
6. Let promise be Construct(C, «executor»).
7. ReturnIfAbrupt(promise).
---*/
var P = function(executor) {
return new Promise(function() {
executor(
function() {},
function() {
throw new Test262Error();
}
);
});
};
assert.throws(Test262Error, function() {
Promise.reject.call(P);
});

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: Invocation of "reject" capability
esid: sec-promise.reject
es6id: 25.4.4.4
info: |
1. Let C be the this value.
[...]
3. Let promiseCapability be ? NewPromiseCapability(C).
4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
[...]
25.4.1.5 NewPromiseCapability
[...]
6. Let promise be Construct(C, «executor»).
7. ReturnIfAbrupt(promise).
---*/
var expectedThis = (function() { return this; })();
var resolveCount = 0;
var thisValue, args;
var P = function(executor) {
return new Promise(function() {
executor(
function() {
resolveCount += 1;
},
function() {
thisValue = this;
args = arguments;
}
);
});
};
Promise.reject.call(P, 24601);
assert.sameValue(resolveCount, 0);
assert.sameValue(thisValue, expectedThis);
assert.sameValue(typeof args, 'object');
assert.sameValue(args.length, 1);
assert.sameValue(args[0], 24601);

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: >
Rejected promises ignore resolution after deferred invocation of the
provided reject function
esid: sec-promise-executor
es6id: 25.4.3.1
info: >
[...]
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
10. If completion is an abrupt completion, then
[...]
11. Return promise.
25.4.1.3.2 Promise Resolve Functions
[...]
3. Let alreadyResolved be F.[[AlreadyResolved]].
4. If alreadyResolved.[[Value]] is true, return undefined.
flags: [async]
---*/
var returnValue = null;
var thenable = new Promise(function() {});
var resolve, reject;
var p = new Promise(function(_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
p.then(function() {
$DONE('The promise should not be fulfilled.');
}, function() {
$DONE();
});
reject(thenable);
returnValue = resolve();
assert.sameValue(returnValue, undefined, '"resolve" function return value');

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: >
Rejected promises ignore resolution after immediate invocation of the
provided reject function
esid: sec-promise-executor
es6id: 25.4.3.3
info: >
[...]
9. Let completion be Call(executor, undefined,
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
10. If completion is an abrupt completion, then
[...]
11. Return promise.
25.4.1.3.2 Promise Resolve Functions
[...]
3. Let alreadyResolved be F.[[AlreadyResolved]].
4. If alreadyResolved.[[Value]] is true, return undefined.
flags: [async]
---*/
var returnValue = null;
var thenable = new Promise(function() {});
var p = new Promise(function(resolve, reject) {
reject(thenable);
returnValue = resolve();
});
assert.sameValue(returnValue, undefined, '"reject" function return value');
p.then(function() {
$DONE('The promise should not be fulfilled.');
}, function() {
$DONE();
});

View File

@ -16,6 +16,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var resolve; var resolve;
var promise = new Promise(function(_resolve) { var promise = new Promise(function(_resolve) {
resolve = _resolve; resolve = _resolve;
@ -32,4 +33,6 @@ promise.then(function(value) {
$DONE('The promise should not be rejected.'); $DONE('The promise should not be rejected.');
}); });
resolve(45); returnValue = resolve(45);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -15,10 +15,13 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var promise = new Promise(function(resolve) { var promise = new Promise(function(resolve) {
resolve(45); returnValue = resolve(45);
}); });
assert.sameValue(returnValue, undefined, '"resolve" return value');
promise.then(function(value) { promise.then(function(value) {
if (value !== 45) { if (value !== 45) {
$DONE('The promise should be fulfilled with the provided value.'); $DONE('The promise should be fulfilled with the provided value.');

View File

@ -21,6 +21,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var nonThenable = { then: null }; var nonThenable = { then: null };
var resolve; var resolve;
var promise = new Promise(function(_resolve) { var promise = new Promise(function(_resolve) {
@ -38,4 +39,6 @@ promise.then(function(value) {
$DONE('The promise should not be rejected.'); $DONE('The promise should not be rejected.');
}); });
resolve(nonThenable); returnValue = resolve(nonThenable);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -21,11 +21,14 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var nonThenable = { then: null }; var nonThenable = { then: null };
var promise = new Promise(function(resolve) { var promise = new Promise(function(resolve) {
resolve(nonThenable); returnValue = resolve(nonThenable);
}); });
assert.sameValue(returnValue, undefined, '"resolve" return value');
promise.then(function(value) { promise.then(function(value) {
if (value !== nonThenable) { if (value !== nonThenable) {
$DONE('The promise should be fulfilled with the provided value.'); $DONE('The promise should be fulfilled with the provided value.');

View File

@ -17,6 +17,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var resolve; var resolve;
var poisonedThen = Object.defineProperty({}, 'then', { var poisonedThen = Object.defineProperty({}, 'then', {
@ -39,4 +40,6 @@ promise.then(function() {
$DONE(); $DONE();
}); });
resolve(poisonedThen); returnValue = resolve(poisonedThen);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -17,6 +17,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var poisonedThen = Object.defineProperty({}, 'then', { var poisonedThen = Object.defineProperty({}, 'then', {
get: function() { get: function() {
@ -24,9 +25,11 @@ var poisonedThen = Object.defineProperty({}, 'then', {
} }
}); });
var promise = new Promise(function(resolve) { var promise = new Promise(function(resolve) {
resolve(poisonedThen); returnValue = resolve(poisonedThen);
}); });
assert.sameValue(returnValue, undefined, '"resolve" return value');
promise.then(function() { promise.then(function() {
$DONE('The promise should not be fulfilled.'); $DONE('The promise should not be fulfilled.');
}, function(val) { }, function(val) {

View File

@ -23,6 +23,7 @@ info: >
«promise, resolution, thenAction») «promise, resolution, thenAction»)
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var resolve; var resolve;
var thenable = new Promise(function(resolve) { resolve(); }); var thenable = new Promise(function(resolve) { resolve(); });
@ -45,4 +46,6 @@ promise.then(function(val) {
$DONE('The promise should not be rejected.'); $DONE('The promise should not be rejected.');
}); });
resolve(thenable); returnValue = resolve(thenable);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -23,6 +23,7 @@ info: >
«promise, resolution, thenAction») «promise, resolution, thenAction»)
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var lateCallCount = 0; var lateCallCount = 0;
var thenable = new Promise(function(resolve) { resolve(); }); var thenable = new Promise(function(resolve) { resolve(); });
@ -32,9 +33,11 @@ thenable.then = function(resolve) {
}; };
var promise = new Promise(function(resolve) { var promise = new Promise(function(resolve) {
resolve(thenable); returnValue = resolve(thenable);
}); });
assert.sameValue(returnValue, undefined, '"resolve" return value');
thenable.then = function() { thenable.then = function() {
lateCallCount += 1; lateCallCount += 1;
}; };

View File

@ -17,6 +17,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var resolve; var resolve;
var promise = new Promise(function(_resolve) { var promise = new Promise(function(_resolve) {
resolve = _resolve; resolve = _resolve;
@ -38,4 +39,6 @@ promise.then(function() {
$DONE(); $DONE();
}); });
resolve(promise); returnValue = resolve(promise);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -24,6 +24,7 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var resolve; var resolve;
var thenable = new Promise(function(resolve) { resolve(value); }); var thenable = new Promise(function(resolve) { resolve(value); });
@ -42,4 +43,6 @@ promise.then(function(val) {
$DONE('The promise should not be rejected.'); $DONE('The promise should not be rejected.');
}); });
resolve(thenable); returnValue = resolve(thenable);
assert.sameValue(returnValue, undefined, '"resolve" return value');

View File

@ -23,12 +23,15 @@ info: >
flags: [async] flags: [async]
---*/ ---*/
var returnValue = null;
var value = {}; var value = {};
var thenable = new Promise(function(resolve) { resolve(value); }); var thenable = new Promise(function(resolve) { resolve(value); });
var promise = new Promise(function(resolve) { var promise = new Promise(function(resolve) {
resolve(thenable); returnValue = resolve(thenable);
}); });
assert.sameValue(returnValue, undefined, '"resolve" return value');
promise.then(function(val) { promise.then(function(val) {
if (val !== value) { if (val !== value) {
$DONE('The promise should be fulfilled with the provided value.'); $DONE('The promise should be fulfilled with the provided value.');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Abrupt completion returned by "resolve" capability
esid: sec-promise.resolve
es6id: 25.4.4.5
info: |
1. Let C be the this value.
[...]
4. Let promiseCapability be ? NewPromiseCapability(C).
5. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
25.4.1.5 NewPromiseCapability
[...]
6. Let promise be Construct(C, «executor»).
7. ReturnIfAbrupt(promise).
---*/
var P = function(executor) {
return new Promise(function() {
executor(
function() {
throw new Test262Error();
},
function() {}
);
});
};
assert.throws(Test262Error, function() {
Promise.resolve.call(P);
});

View File

@ -16,16 +16,23 @@ info: >
... ...
---*/ ---*/
var expectedThisValue = (function() { return this; }());
var callCount = 0; var callCount = 0;
var object = {}; var object = {};
var thisValue, args;
Promise.resolve.call(function(executor) { Promise.resolve.call(function(executor) {
function resolve(v) { function resolve(v) {
callCount += 1; callCount += 1;
assert.sameValue(v, object); thisValue = this;
args = arguments;
} }
executor(resolve, $ERROR); executor(resolve, $ERROR);
assert.sameValue(callCount, 0, "callCount before returning from constructor"); assert.sameValue(callCount, 0, "callCount before returning from constructor");
}, object); }, object);
assert.sameValue(callCount, 1, "callCount after call to resolve()"); assert.sameValue(callCount, 1, "callCount after call to resolve()");
assert.sameValue(typeof args, "object");
assert.sameValue(args.length, 1);
assert.sameValue(args[0], object);
assert.sameValue(thisValue, expectedThisValue);