Skip to content

Commit

Permalink
Fix test regression in asyncHelpers.js
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Aug 18, 2024
1 parent 941813e commit 6b666e4
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 23 deletions.
54 changes: 31 additions & 23 deletions harness/asyncHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*---
description: |
A collection of assertion and wrapper functions for testing asynchronous built-ins.
defines: [asyncTest]
defines: [asyncTest, assert.throwsAsync]
---*/

/**
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}
));
});
};
37 changes: 37 additions & 0 deletions test/harness/asyncHelpers-throwsAsync-func-never-settles.js
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit 6b666e4

Please sign in to comment.