mirror of
https://github.com/tc39/test262.git
synced 2025-07-21 21:14:45 +02:00
Add coverage for IteratorClose in Promise combinators
SM doesn't pass these tests, whereas JSC and V8 passes them.
This commit is contained in:
parent
5920cb8e1b
commit
c6ad284d99
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.all
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns abruptly because GetMethod throws.
|
||||
info: |
|
||||
27.2.4.1 Promise.all ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
...
|
||||
5. If completion is a throw completion, return ? completion.
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
3. If IsCallable(func) is false, throw a TypeError exception.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [0, 0n, true, "string", {}, Symbol()]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.all.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.all
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns normally because GetMethod returns undefined.
|
||||
info: |
|
||||
27.2.4.1 Promise.all ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
4. If innerResult is a normal completion, then
|
||||
a. Let return be innerResult.[[Value]].
|
||||
b. If return is undefined, return ? completion.
|
||||
...
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [null, undefined]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.all.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.allsettled
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns abruptly because GetMethod throws.
|
||||
info: |
|
||||
27.2.4.2 Promise.allSettled ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
...
|
||||
5. If completion is a throw completion, return ? completion.
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
3. If IsCallable(func) is false, throw a TypeError exception.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [0, 0n, true, "string", {}, Symbol()]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.allSettled.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.allsettled
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns normally because GetMethod returns undefined.
|
||||
info: |
|
||||
27.2.4.2 Promise.allSettled ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
4. If innerResult is a normal completion, then
|
||||
a. Let return be innerResult.[[Value]].
|
||||
b. If return is undefined, return ? completion.
|
||||
...
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [null, undefined]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.allSettled.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.any
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns abruptly because GetMethod throws.
|
||||
info: |
|
||||
27.2.4.3 Promise.any ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
...
|
||||
5. If completion is a throw completion, return ? completion.
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
3. If IsCallable(func) is false, throw a TypeError exception.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [0, 0n, true, "string", {}, Symbol()]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.any.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.any
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns normally because GetMethod returns undefined.
|
||||
info: |
|
||||
27.2.4.3 Promise.any ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
4. If innerResult is a normal completion, then
|
||||
a. Let return be innerResult.[[Value]].
|
||||
b. If return is undefined, return ? completion.
|
||||
...
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [null, undefined]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.any.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.race
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns abruptly because GetMethod throws.
|
||||
info: |
|
||||
27.2.4.5 Promise.race ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
...
|
||||
5. If completion is a throw completion, return ? completion.
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
3. If IsCallable(func) is false, throw a TypeError exception.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [0, 0n, true, "string", {}, Symbol()]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.race.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-promise.race
|
||||
description: >
|
||||
Input throw-completion forwarded when IteratorClose returns normally because GetMethod returns undefined.
|
||||
info: |
|
||||
27.2.4.5 Promise.race ( iterable )
|
||||
...
|
||||
7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
|
||||
8. If result is an abrupt completion, then
|
||||
a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
|
||||
b. IfAbruptRejectPromise(result, promiseCapability).
|
||||
...
|
||||
|
||||
7.4.11 IteratorClose ( iteratorRecord, completion )
|
||||
...
|
||||
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
||||
4. If innerResult is a normal completion, then
|
||||
a. Let return be innerResult.[[Value]].
|
||||
b. If return is undefined, return ? completion.
|
||||
...
|
||||
...
|
||||
|
||||
7.3.10 GetMethod ( V, P )
|
||||
1. Let func be ? GetV(V, P).
|
||||
2. If func is either undefined or null, return undefined.
|
||||
...
|
||||
---*/
|
||||
|
||||
function resolve() {
|
||||
throw new Test262Error("Unexpected call to resolve");
|
||||
}
|
||||
|
||||
var rejectCallCount = 0;
|
||||
|
||||
function reject(e) {
|
||||
rejectCallCount += 1;
|
||||
assert.sameValue(e, "bad promise resolve");
|
||||
}
|
||||
|
||||
class BadPromise {
|
||||
constructor(executor) {
|
||||
executor(resolve, reject);
|
||||
}
|
||||
|
||||
static resolve() {
|
||||
throw "bad promise resolve";
|
||||
}
|
||||
}
|
||||
|
||||
for (var returnMethod of [null, undefined]) {
|
||||
var iterator = {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
return {done: false};
|
||||
},
|
||||
return: returnMethod,
|
||||
};
|
||||
|
||||
// Reset counter.
|
||||
rejectCallCount = 0;
|
||||
|
||||
Promise.race.call(BadPromise, iterator);
|
||||
|
||||
// Ensure `reject` was called exactly once.
|
||||
assert.sameValue(rejectCallCount, 1);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user