mirror of https://github.com/tc39/test262.git
Extend test coverage for Promise built-in
This commit is contained in:
parent
f4e17963f8
commit
2bb1003ab1
|
@ -0,0 +1,25 @@
|
|||
// 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.4.6
|
||||
description: Promise `Symbol.species` property
|
||||
info: >
|
||||
Promise[@@species] is an accessor property whose set accessor function is
|
||||
undefined.
|
||||
|
||||
ES6 Section 17:
|
||||
|
||||
Every accessor property described in clauses 18 through 26 and in Annex B.2
|
||||
has the attributes {[[Enumerable]]: false, [[Configurable]]: true } unless
|
||||
otherwise specified.
|
||||
features: [Symbol.species]
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
|
||||
|
||||
assert.sameValue(desc.set, undefined);
|
||||
assert.sameValue(typeof desc.get, 'function');
|
||||
|
||||
verifyNotEnumerable(Promise, Symbol.species);
|
||||
verifyConfigurable(Promise, Symbol.species);
|
|
@ -0,0 +1,14 @@
|
|||
// 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.4.6
|
||||
description: Promise `Symbol.species` accessor function return value
|
||||
info: >
|
||||
1. Return the this value.
|
||||
features: [Symbol.species]
|
||||
---*/
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
|
||||
var thisValue = {};
|
||||
|
||||
assert.sameValue(desc.get.call(thisValue), thisValue);
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.all` invoked on a constructor value
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
[...]
|
||||
6. Let promiseCapability be NewPromiseCapability(C).
|
||||
[...]
|
||||
10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
|
||||
[...]
|
||||
13. Return Completion(result).
|
||||
features: [class]
|
||||
---*/
|
||||
|
||||
var executor = null;
|
||||
var callCount = 0;
|
||||
|
||||
class SubPromise extends Promise {
|
||||
constructor(a) {
|
||||
super(a);
|
||||
executor = a;
|
||||
callCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var instance = Promise.all.call(SubPromise);
|
||||
|
||||
assert.sameValue(instance.constructor, SubPromise);
|
||||
assert.sameValue(instance instanceof SubPromise, true);
|
||||
|
||||
assert.sameValue(callCount, 1);
|
||||
assert.sameValue(typeof executor, 'function');
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.all` invoked on a non-constructor value
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
[...]
|
||||
6. Let promiseCapability be NewPromiseCapability(C).
|
||||
7. ReturnIfAbrupt(promiseCapability).
|
||||
|
||||
25.4.1.5 NewPromiseCapability ( C )
|
||||
|
||||
1. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(eval);
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.all` invoked on a non-object value
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(undefined, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(null, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(86, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call('string', []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(true, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.all.call(Symbol(), []);
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
// 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
|
||||
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 ).
|
||||
---*/
|
||||
|
||||
var error = new Test262Error();
|
||||
Object.defineProperty(Promise, 'resolve', {
|
||||
get: function() {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
Promise.all([new Promise(function() {})]).then(function() {
|
||||
$ERROR('The promise should be rejected');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Invocation of the constructor's `resolve` method
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
|
||||
|
||||
[...]
|
||||
|
||||
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
|
||||
|
||||
[...]
|
||||
6. Repeat
|
||||
[...]
|
||||
i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
|
||||
---*/
|
||||
|
||||
var p1 = new Promise(function() {});
|
||||
var p2 = new Promise(function() {});
|
||||
var p3 = new Promise(function() {});
|
||||
var resolve = Promise.resolve;
|
||||
var callCount = 0;
|
||||
var current = p1;
|
||||
var next = p2;
|
||||
var afterNext = p3;
|
||||
|
||||
Promise.resolve = function(nextValue) {
|
||||
assert.sameValue(
|
||||
nextValue, current, '`resolve` invoked with next iterated value'
|
||||
);
|
||||
assert.sameValue(
|
||||
arguments.length, 1, '`resolve` invoked with a single argument'
|
||||
);
|
||||
assert.sameValue(this, Promise, '`this` value is the constructor');
|
||||
|
||||
current = next;
|
||||
next = afterNext;
|
||||
afterNext = null;
|
||||
|
||||
callCount += 1;
|
||||
|
||||
return resolve.apply(Promise, arguments);
|
||||
};
|
||||
|
||||
Promise.all([p1, p2, p3]);
|
||||
|
||||
assert.sameValue(
|
||||
callCount, 3, '`resolve` invoked once for each iterated value'
|
||||
);
|
|
@ -0,0 +1,38 @@
|
|||
// 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 thrown when invoking the instance's `then` method
|
||||
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).
|
||||
---*/
|
||||
|
||||
var promise = new Promise(function() {});
|
||||
var error = new Test262Error();
|
||||
|
||||
promise.then = function() {
|
||||
throw error;
|
||||
};
|
||||
|
||||
Promise.all([promise]).then(function() {
|
||||
$ERROR('The promise should be rejected');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Invocation of the instance's `then` method
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
|
||||
|
||||
[...]
|
||||
|
||||
25.4.4.1.1 Runtime Semantics: PerformPromiseAll
|
||||
|
||||
[...]
|
||||
6. Repeat
|
||||
[...]
|
||||
r. Let result be Invoke(nextPromise, "then", «resolveElement,
|
||||
resultCapability.[[Reject]]»).
|
||||
---*/
|
||||
|
||||
var p1 = new Promise(function() {});
|
||||
var p2 = new Promise(function() {});
|
||||
var p3 = new Promise(function() {});
|
||||
var callCount = 0;
|
||||
var currentThis = p1;
|
||||
var nextThis = p2;
|
||||
var afterNextThis = p3;
|
||||
|
||||
p1.then = p2.then = p3.then = function(a, b) {
|
||||
assert.sameValue(typeof a, 'function', 'type of first argument');
|
||||
assert.sameValue(
|
||||
a.length,
|
||||
1,
|
||||
'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
|
||||
);
|
||||
assert.sameValue(typeof b, 'function', 'type of second argument');
|
||||
assert.sameValue(
|
||||
b.length,
|
||||
1,
|
||||
'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
|
||||
);
|
||||
assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
|
||||
assert.sameValue(this, currentThis, '`this` value');
|
||||
|
||||
currentThis = nextThis;
|
||||
nextThis = afterNextThis;
|
||||
afterNextThis = null;
|
||||
|
||||
callCount += 1;
|
||||
};
|
||||
|
||||
Promise.all([p1, p2, p3]);
|
||||
|
||||
assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (C) 2015 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
|
||||
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 iterDoneSpy = {};
|
||||
var callCount = 0;
|
||||
iterDoneSpy[Symbol.iterator] = function() {
|
||||
return {
|
||||
next: function() {
|
||||
return { value: null, done: false };
|
||||
},
|
||||
return: function() {
|
||||
callCount += 1;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Promise.resolve = function() {
|
||||
throw new Error();
|
||||
};
|
||||
|
||||
Promise.all(iterDoneSpy);
|
||||
|
||||
assert.sameValue(callCount, 1);
|
|
@ -0,0 +1,51 @@
|
|||
// 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 when accessing an iterator result's `value` property
|
||||
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
|
||||
[...]
|
||||
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 poisonedVal = {
|
||||
done: false
|
||||
};
|
||||
var error = new Test262Error();
|
||||
Object.defineProperty(poisonedVal, 'value', {
|
||||
get: function() {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
iterNextValThrows[Symbol.iterator] = function() {
|
||||
return {
|
||||
next: function() {
|
||||
return poisonedVal;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Promise.all(iterNextValThrows).then(function() {
|
||||
$ERROR('The promise should be rejected.');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,25 @@
|
|||
// 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 thrown when retrieving `Symbol.species` property of the `this` value
|
||||
es6id: 25.4.4.1
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
3. Let S be Get(C, @@species).
|
||||
4. ReturnIfAbrupt(S).
|
||||
features: [Symbol.species]
|
||||
---*/
|
||||
|
||||
var C = {};
|
||||
Object.defineProperty(C, Symbol.species, {
|
||||
get: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
Promise.all.call(C);
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
// 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.3.1
|
||||
description: Promise executor is invoked synchronously
|
||||
info: >
|
||||
9. Let completion be Call(executor, undefined,
|
||||
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
|
||||
|
||||
25.4.1.3.2 Promise Resolve Functions
|
||||
|
||||
The length property of a promise resolve function is 1.
|
||||
|
||||
25.4.1.3.1 Promise Reject Functions
|
||||
|
||||
The length property of a promise reject function is 1.
|
||||
---*/
|
||||
|
||||
var callCount = 0;
|
||||
var resolve, reject, argCount;
|
||||
|
||||
new Promise(function(a, b) {
|
||||
resolve = a;
|
||||
reject = b;
|
||||
argCount = arguments.length;
|
||||
});
|
||||
|
||||
assert.sameValue(typeof resolve, 'function', 'type of first argument');
|
||||
assert.sameValue(resolve.length, 1, 'length of first argument');
|
||||
assert.sameValue(typeof reject, 'function', 'type of second argument');
|
||||
assert.sameValue(reject.length, 1, 'length of second argument');
|
||||
assert.sameValue(argCount, 2);
|
|
@ -0,0 +1,52 @@
|
|||
// 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.1
|
||||
description: Promise.prototype.catch invokes `then` method
|
||||
info: >
|
||||
1. Let promise be the this value.
|
||||
2. Return Invoke(promise, "then", «undefined, onRejected»).
|
||||
---*/
|
||||
|
||||
var target = {};
|
||||
var returnValue = {};
|
||||
var callCount = 0;
|
||||
var thisValue = null;
|
||||
var argCount = null;
|
||||
var firstArg = null;
|
||||
var secondArg = null;
|
||||
var result = null;
|
||||
|
||||
target.then = function(a, b) {
|
||||
callCount += 1;
|
||||
|
||||
thisValue = this;
|
||||
argCount = arguments.length;
|
||||
firstArg = a;
|
||||
secondArg = b;
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
result = Promise.prototype.catch.call(target, 1, 2, 3);
|
||||
|
||||
assert.sameValue(callCount, 1, 'Invokes `then` method exactly once');
|
||||
assert.sameValue(
|
||||
thisValue,
|
||||
target,
|
||||
'Invokes `then` method with the instance as the `this` value'
|
||||
);
|
||||
assert.sameValue(
|
||||
argCount, 2, 'Invokes `then` method with exactly two single arguments'
|
||||
);
|
||||
assert.sameValue(
|
||||
firstArg,
|
||||
undefined,
|
||||
'Invokes `then` method with `undefined` as the first argument'
|
||||
);
|
||||
assert.sameValue(
|
||||
secondArg, 1, 'Invokes `then` method with the provided argument'
|
||||
);
|
||||
assert.sameValue(
|
||||
result, returnValue, 'Returns the result of the invocation of `then`'
|
||||
);
|
|
@ -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.
|
||||
/*---
|
||||
es6id: 25.4.5.3
|
||||
description: The constructor defined by Symbol.species takes precedence
|
||||
info: >
|
||||
1. Let promise be the this value.
|
||||
2. If IsPromise(promise) is false, throw a TypeError exception.
|
||||
3. Let C be SpeciesConstructor(promise, %Promise%).
|
||||
4. ReturnIfAbrupt(C).
|
||||
5. Let resultCapability be NewPromiseCapability(C).
|
||||
features: [Symbol.species, class]
|
||||
---*/
|
||||
|
||||
var callCount = 0;
|
||||
var thisValue, firstArg, argLength, getCapabilitiesExecutor;
|
||||
var executor = function() {};
|
||||
var p1 = new Promise(function() {});
|
||||
var SpeciesConstructor = class extends Promise {
|
||||
constructor(a) {
|
||||
super(a);
|
||||
callCount += 1;
|
||||
thisValue = this;
|
||||
getCapabilitiesExecutor = a;
|
||||
argLength = arguments.length;
|
||||
}
|
||||
};
|
||||
var p2;
|
||||
|
||||
p1.constructor = function() {};
|
||||
p1.constructor[Symbol.species] = SpeciesConstructor;
|
||||
|
||||
p2 = p1.then();
|
||||
|
||||
assert.sameValue(callCount, 1, 'The constructor is invoked exactly once');
|
||||
assert(thisValue instanceof SpeciesConstructor);
|
||||
assert.sameValue(
|
||||
argLength, 1, 'The constructor is invoked with a single argument'
|
||||
);
|
||||
assert.sameValue(typeof getCapabilitiesExecutor, 'function');
|
||||
assert.sameValue(
|
||||
getCapabilitiesExecutor.length,
|
||||
2,
|
||||
'ES6 25.4.1.5.1: The length property of a GetCapabilitiesExecutor function is 2.'
|
||||
);
|
||||
assert(
|
||||
p2 instanceof SpeciesConstructor,
|
||||
'The returned object is an instance of the constructor'
|
||||
);
|
|
@ -0,0 +1,20 @@
|
|||
// 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: >
|
||||
A TypeError is thrown when the `this` value has a non-object `constructor` property
|
||||
info: >
|
||||
1. Let promise be the this value.
|
||||
2. If IsPromise(promise) is false, throw a TypeError exception.
|
||||
3. Let C be SpeciesConstructor(promise, %Promise%).
|
||||
4. ReturnIfAbrupt(C).
|
||||
5. Let resultCapability be NewPromiseCapability(C).
|
||||
---*/
|
||||
|
||||
var p = new Promise(function() {});
|
||||
p.constructor = null;
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
p.then();
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
// 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 Promise built-in is used when the `this` value has no `constructor` property
|
||||
info: >
|
||||
1. Let promise be the this value.
|
||||
2. If IsPromise(promise) is false, throw a TypeError exception.
|
||||
3. Let C be SpeciesConstructor(promise, %Promise%).
|
||||
4. ReturnIfAbrupt(C).
|
||||
5. Let resultCapability be NewPromiseCapability(C).
|
||||
---*/
|
||||
|
||||
var p1 = new Promise(function() {});
|
||||
delete p1.constructor;
|
||||
|
||||
var p2 = p1.then();
|
||||
|
||||
assert(p2 instanceof Promise);
|
|
@ -0,0 +1,46 @@
|
|||
// 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: >
|
||||
Access error for the `then` property of the object returned from the "on fulfilled" handler
|
||||
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]]).
|
||||
---*/
|
||||
|
||||
var poisonedThen = {};
|
||||
var error = new Test262Error();
|
||||
Object.defineProperty(poisonedThen, 'then', {
|
||||
get: function() {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
var p = new Promise(function(r) { r(); });
|
||||
|
||||
p.then(function() {
|
||||
return poisonedThen;
|
||||
}).then(function() {
|
||||
$DONE('The promise should not be fulfilled');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
|
||||
$DONE();
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
// 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');
|
||||
});
|
84
test/built-ins/Promise/prototype/then/on-fulfilled-return-prms-pending-to-fulfilled.js
vendored
Normal file
84
test/built-ins/Promise/prototype/then/on-fulfilled-return-prms-pending-to-fulfilled.js
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// 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');
|
||||
});
|
84
test/built-ins/Promise/prototype/then/on-fulfilled-return-prms-pending-to-rejected.js
vendored
Normal file
84
test/built-ins/Promise/prototype/then/on-fulfilled-return-prms-pending-to-rejected.js
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// 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();
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
// 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();
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
// 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
|
||||
|
||||
[...]
|
||||
6. If SameValue(resolution, promise) is true, then
|
||||
a. Let selfResolutionError be a newly created TypeError object.
|
||||
b. Return RejectPromise(promise, selfResolutionError).
|
||||
---*/
|
||||
|
||||
var promise1 = new Promise(function(resolve) {
|
||||
resolve();
|
||||
});
|
||||
|
||||
var promise2 = promise1.then(function() {
|
||||
return promise2;
|
||||
});
|
||||
|
||||
promise2.then(function() {
|
||||
$DONE('This promise should not be resolved');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason.constructor, TypeError);
|
||||
|
||||
$DONE();
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
// 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');
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
// 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 `onFulfilled` method throws an error
|
||||
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.
|
||||
|
||||
25.4.2.2 PromiseResolveThenableJob
|
||||
|
||||
2. Let thenCallResult be Call(then, thenable,
|
||||
«resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
|
||||
3. If thenCallResult is an abrupt completion,
|
||||
a. Let status be Call(resolvingFunctions.[[Reject]], undefined,
|
||||
«thenCallResult.[[value]]»).
|
||||
b. NextJob Completion(status).
|
||||
---*/
|
||||
|
||||
var error = new Test262Error();
|
||||
var promiseFulfilled = false;
|
||||
var promiseRejected = false;
|
||||
var promise = new Promise(function(resolve) {
|
||||
resolve();
|
||||
});
|
||||
|
||||
promise.then(function() {
|
||||
throw error;
|
||||
}).then(function() {
|
||||
$DONE('This promise should not be fulfilled');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
|
||||
$DONE();
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
// 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 `onRejected` method
|
||||
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»).
|
||||
---*/
|
||||
|
||||
var returnVal = {};
|
||||
var promise = new Promise(function(_, reject) {
|
||||
reject();
|
||||
});
|
||||
|
||||
promise.then(null, function() {
|
||||
return returnVal;
|
||||
}).then(function(result) {
|
||||
assert.sameValue(result, returnVal);
|
||||
|
||||
$DONE();
|
||||
}, function() {
|
||||
$DONE('The promise should not be rejected');
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
// 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 `onRejected` method throws an error
|
||||
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»).
|
||||
---*/
|
||||
|
||||
var error = new Test262Error();
|
||||
var promise = new Promise(function(_, reject) {
|
||||
reject();
|
||||
});
|
||||
|
||||
promise.then(null, function() {
|
||||
throw error;
|
||||
}).then(function(result) {
|
||||
$DONE('This promise should not be fulfilled');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
|
||||
$DONE();
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.race` invoked on a constructor value
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
[...]
|
||||
6. Let promiseCapability be NewPromiseCapability(C).
|
||||
[...]
|
||||
10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
|
||||
[...]
|
||||
13. Return Completion(result).
|
||||
features: [class]
|
||||
---*/
|
||||
|
||||
var executor = null;
|
||||
var callCount = 0;
|
||||
|
||||
class SubPromise extends Promise {
|
||||
constructor(a) {
|
||||
super(a);
|
||||
executor = a;
|
||||
callCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var instance = Promise.race.call(SubPromise);
|
||||
|
||||
assert.sameValue(instance.constructor, SubPromise);
|
||||
assert.sameValue(instance instanceof SubPromise, true);
|
||||
|
||||
assert.sameValue(callCount, 1);
|
||||
assert.sameValue(typeof executor, 'function');
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.race` invoked on a non-constructor value
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
[...]
|
||||
6. Let promiseCapability be NewPromiseCapability(C).
|
||||
7. ReturnIfAbrupt(promiseCapability).
|
||||
|
||||
25.4.1.5 NewPromiseCapability ( C )
|
||||
|
||||
1. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(eval);
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.race` invoked on a non-object value
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(undefined, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(null, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(86, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call('string', []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(true, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.race.call(Symbol(), []);
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// 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
|
||||
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).
|
||||
---*/
|
||||
|
||||
var error = new Test262Error();
|
||||
Object.defineProperty(Promise, 'resolve', {
|
||||
get: function() {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
Promise.race([new Promise(function() {})]).then(function() {
|
||||
$ERROR('The promise should be rejected');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Invocation of the constructor's `resolve` method
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
|
||||
|
||||
[...]
|
||||
|
||||
25.4.4.3.1 Runtime Semantics: PerformPromiseRace
|
||||
|
||||
1. Repeat
|
||||
[...]
|
||||
h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
|
||||
---*/
|
||||
|
||||
var p1 = new Promise(function() {});
|
||||
var p2 = new Promise(function() {});
|
||||
var p3 = new Promise(function() {});
|
||||
var resolve = Promise.resolve;
|
||||
var callCount = 0;
|
||||
var current = p1;
|
||||
var next = p2;
|
||||
var afterNext = p3;
|
||||
|
||||
Promise.resolve = function(nextValue) {
|
||||
assert.sameValue(
|
||||
nextValue, current, '`resolve` invoked with next iterated value'
|
||||
);
|
||||
assert.sameValue(
|
||||
arguments.length, 1, '`resolve` invoked with a single argument'
|
||||
);
|
||||
assert.sameValue(this, Promise, '`this` value set to the constructor');
|
||||
|
||||
current = next;
|
||||
next = afterNext;
|
||||
afterNext = null;
|
||||
|
||||
callCount += 1;
|
||||
|
||||
return resolve.apply(Promise, arguments);
|
||||
};
|
||||
|
||||
Promise.race([p1, p2, p3]);
|
||||
|
||||
assert.sameValue(
|
||||
callCount, 3, '`resolve` invoked once for each iterated value'
|
||||
);
|
|
@ -0,0 +1,37 @@
|
|||
// 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 thrown when invoking the instance's `then` method
|
||||
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).
|
||||
---*/
|
||||
|
||||
var promise = new Promise(function() {});
|
||||
var error = new Test262Error();
|
||||
|
||||
promise.then = function() {
|
||||
throw error;
|
||||
};
|
||||
|
||||
Promise.race([promise]).then(function() {
|
||||
$ERROR('The promise should be rejected');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
Invocation of the instance's `then` method
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
11. Let result be PerformPromiseRace(iteratorRecord, C, 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).
|
||||
---*/
|
||||
|
||||
var p1 = new Promise(function() {});
|
||||
var p2 = new Promise(function() {});
|
||||
var p3 = new Promise(function() {});
|
||||
var callCount = 0;
|
||||
var currentThis = p1;
|
||||
var nextThis = p2;
|
||||
var afterNextThis = p3;
|
||||
|
||||
p1.then = p2.then = p3.then = function(a, b) {
|
||||
assert.sameValue(typeof a, 'function', 'type of first argument');
|
||||
assert.sameValue(
|
||||
a.length,
|
||||
1,
|
||||
'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
|
||||
);
|
||||
assert.sameValue(typeof b, 'function', 'type of second argument');
|
||||
assert.sameValue(
|
||||
b.length,
|
||||
1,
|
||||
'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
|
||||
);
|
||||
assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
|
||||
assert.sameValue(this, currentThis, '`this` value');
|
||||
|
||||
currentThis = nextThis;
|
||||
nextThis = afterNextThis;
|
||||
afterNextThis = null;
|
||||
|
||||
callCount += 1;
|
||||
};
|
||||
|
||||
Promise.race([p1, p2, p3]);
|
||||
|
||||
assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
|
|
@ -0,0 +1,50 @@
|
|||
// 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 when accessing an iterator result's `value` property
|
||||
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 poisonedVal = {
|
||||
done: false
|
||||
};
|
||||
var error = new Test262Error();
|
||||
Object.defineProperty(poisonedVal, 'value', {
|
||||
get: function() {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
iterNextValThrows[Symbol.iterator] = function() {
|
||||
return {
|
||||
next: function() {
|
||||
return poisonedVal;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Promise.race(iterNextValThrows).then(function() {
|
||||
$ERROR('The promise should be rejected.');
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, error);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,25 @@
|
|||
// 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 thrown when retrieving `Symbol.species` property of the `this` value
|
||||
es6id: 25.4.4.3
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
3. Let S be Get(C, @@species).
|
||||
4. ReturnIfAbrupt(S).
|
||||
features: [Symbol.species]
|
||||
---*/
|
||||
|
||||
var C = {};
|
||||
Object.defineProperty(C, Symbol.species, {
|
||||
get: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
Promise.race.call(C);
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.reject` invoked on a constructor value
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
[...]
|
||||
3. Let promiseCapability be NewPromiseCapability(C).
|
||||
[...]
|
||||
7. Return promiseCapability.[[Promise]].
|
||||
features: [class]
|
||||
---*/
|
||||
|
||||
var executor = null;
|
||||
var callCount = 0;
|
||||
|
||||
class SubPromise extends Promise {
|
||||
constructor(a) {
|
||||
super(a);
|
||||
executor = a;
|
||||
callCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var instance = Promise.reject.call(SubPromise);
|
||||
|
||||
assert.sameValue(instance.constructor, SubPromise);
|
||||
assert.sameValue(instance instanceof SubPromise, true);
|
||||
|
||||
assert.sameValue(callCount, 1);
|
||||
assert.sameValue(typeof executor, 'function');
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.reject` invoked on a non-constructor value
|
||||
es6id: 25.4.4.4
|
||||
info: >
|
||||
[...]
|
||||
3. Let promiseCapability be NewPromiseCapability(C).
|
||||
4. ReturnIfAbrupt(promiseCapability).
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(eval);
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked on a non-object value
|
||||
es6id: 25.4.4.4
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(undefined, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(null, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(86, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call('string', []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(true, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.reject.call(Symbol(), []);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked with an object whose `then` property is not callable
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
|
||||
«x»).
|
||||
|
||||
[...]
|
||||
|
||||
25.4.1.3.2 Promise Resolve Functions
|
||||
|
||||
11. If IsCallable(thenAction) is false, then
|
||||
a. Return FulfillPromise(promise, resolution).
|
||||
12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
|
||||
«promise, resolution, thenAction»)
|
||||
13. Return undefined.
|
||||
---*/
|
||||
|
||||
var nonThenable = {
|
||||
then: null
|
||||
};
|
||||
|
||||
Promise.resolve(nonThenable).then(function(value) {
|
||||
assert.sameValue(value, nonThenable);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked 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 poisonedThen = {};
|
||||
var err = new Test262Error();
|
||||
Object.defineProperty(poisonedThen, 'then', {
|
||||
get: function() {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
Promise.resolve(poisonedThen).then(function() {
|
||||
$ERROR(
|
||||
'Promise should be rejected when retrieving `then` property throws an error'
|
||||
);
|
||||
}, function(reason) {
|
||||
assert.sameValue(reason, err);
|
||||
}).then($DONE, $DONE);
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked with a Promise with a unique constructor
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
[...]
|
||||
3. If IsPromise(x) is true,
|
||||
a. Let xConstructor be Get(x, "constructor").
|
||||
b. ReturnIfAbrupt(xConstructor).
|
||||
c. If SameValue(xConstructor, C) is true, return x.
|
||||
4. Let promiseCapability be NewPromiseCapability(C).
|
||||
[...]
|
||||
8. Return promiseCapability.[[Promise]].
|
||||
---*/
|
||||
|
||||
var promise1 = new Promise(function() {});
|
||||
var promise2;
|
||||
|
||||
promise1.constructor = null;
|
||||
|
||||
promise2 = Promise.resolve(promise1);
|
||||
|
||||
assert.sameValue(promise1 === promise2, false);
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked on a constructor value
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
[...]
|
||||
4. Let promiseCapability be NewPromiseCapability(C).
|
||||
[...]
|
||||
8. Return promiseCapability.[[Promise]].
|
||||
features: [class]
|
||||
---*/
|
||||
|
||||
var executor = null;
|
||||
var callCount = 0;
|
||||
|
||||
class SubPromise extends Promise {
|
||||
constructor(a) {
|
||||
super(a);
|
||||
executor = a;
|
||||
callCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var instance = Promise.resolve.call(SubPromise);
|
||||
|
||||
assert.sameValue(instance.constructor, SubPromise);
|
||||
assert.sameValue(instance instanceof SubPromise, true);
|
||||
|
||||
assert.sameValue(callCount, 1);
|
||||
assert.sameValue(typeof executor, 'function');
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked on a non-constructor value
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
[...]
|
||||
4. Let promiseCapability be NewPromiseCapability(C).
|
||||
5. ReturnIfAbrupt(promiseCapability).
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(eval);
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
`Promise.resolve` invoked on a non-object value
|
||||
es6id: 25.4.4.5
|
||||
info: >
|
||||
1. Let C be the this value.
|
||||
2. If Type(C) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(undefined, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(null, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(86, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call('string', []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(true, []);
|
||||
});
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
Promise.resolve.call(Symbol(), []);
|
||||
});
|
Loading…
Reference in New Issue