Fix test regression in asyncHelpers.js (#4197)

This commit is contained in:
José Julián Espina 2024-08-19 16:33:17 +00:00 committed by GitHub
parent 941813e1f0
commit dde3050bdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 23 deletions

View File

@ -3,7 +3,7 @@
/*---
description: |
A collection of assertion and wrapper functions for testing asynchronous built-ins.
defines: [asyncTest]
defines: [asyncTest, assert.throwsAsync]
---*/
/**
@ -50,18 +50,21 @@ function asyncTest(testFunc) {
*/
assert.throwsAsync = function (expectedErrorConstructor, func, message) {
return new Promise(function (resolve) {
var expectedName = expectedErrorConstructor.name;
var expectation = "Expected a " + expectedName + " to be thrown asynchronously";
var fail = function (detail) {
if (message === undefined) {
throw new Test262Error(detail);
}
throw new Test262Error(message + " " + detail);
};
var res;
if (typeof expectedErrorConstructor !== "function") {
fail("assert.throwsAsync called with an argument that is not an error constructor");
}
if (typeof func !== "function") {
fail("assert.throwsAsync called with an argument that is not a function");
}
var expectedName = expectedErrorConstructor.name;
var expectation = "Expected a " + expectedName + " to be thrown asynchronously";
var res;
try {
res = func();
} catch (thrown) {
@ -70,28 +73,33 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) {
if (res === null || typeof res !== "object" || typeof res.then !== "function") {
fail(expectation + " but result was not a thenable");
}
var onResFulfilled, onResRejected;
var resSettlementP = new Promise(function (onFulfilled, onRejected) {
onResFulfilled = onFulfilled;
onResRejected = onRejected;
});
try {
resolve(Promise.resolve(res).then(
function () {
fail(expectation + " but no exception was thrown at all");
},
function (thrown) {
var actualName;
if (thrown === null || typeof thrown !== "object") {
fail(expectation + " but thrown value was not an object");
} else if (thrown.constructor !== expectedErrorConstructor) {
actualName = thrown.constructor.name;
if (expectedName === actualName) {
fail(expectation +
" but got a different error constructor with the same name");
}
fail(expectation + " but got a " + actualName);
}
}
));
res.then(onResFulfilled, onResRejected)
} catch (thrown) {
fail(expectation + " but .then threw synchronously");
}
resolve(resSettlementP.then(
function () {
fail(expectation + " but no exception was thrown at all");
},
function (thrown) {
var actualName;
if (thrown === null || typeof thrown !== "object") {
fail(expectation + " but thrown value was not an object");
} else if (thrown.constructor !== expectedErrorConstructor) {
actualName = thrown.constructor.name;
if (expectedName === actualName) {
fail(expectation +
" but got a different error constructor with the same name");
}
fail(expectation + " but got a " + actualName);
}
}
));
});
};

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 Julián Espina. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
assert.throwsAsync returns a promise that never settles if func returns a thenable that never settles.
flags: [async]
includes: [asyncHelpers.js]
---*/
var realDone = $DONE;
var doneCalls = 0
globalThis.$DONE = function () {
doneCalls++;
}
function delay() {
var later = Promise.resolve();
for (var i = 0; i < 100; i++) {
later = later.then();
}
return later;
}
(async function () {
// Spy on the promise returned by an invocation of assert.throwsAsync
// with a function that returns a thenable which never settles.
var neverSettlingThenable = { then: function () { } };
const p = assert.throwsAsync(TypeError, function () { return neverSettlingThenable });
assert(p instanceof Promise, "assert.throwsAsync should return a promise");
p.then($DONE, $DONE);
})()
// Give it a long time to try.
.then(delay, delay)
.then(function () {
assert.sameValue(doneCalls, 0, "$DONE should not have been called")
})
.then(realDone, realDone);