Source code
Revision control
Copy as Markdown
Other Tools
// |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management
load(libdir + "asserts.js");
{
const disposed = [];
const errorToThrow = new Error("error");
const stack = new AsyncDisposableStack();
const obj = {
[Symbol.asyncDispose]() {
disposed.push(1);
throw errorToThrow;
},
};
stack.use(obj);
assertEq(stack.disposed, false);
assertThrowsInstanceOfAsync(async () => {
await stack.disposeAsync();
}, Error);
assertArrayEq(disposed, [1]);
assertEq(stack.disposed, true);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3")];
const stack = new AsyncDisposableStack();
for (let i = 0; i < 3; i++) {
stack.use({
[Symbol.asyncDispose]() {
disposed.push(i);
throw errorsToThrow[i];
},
});
}
assertEq(stack.disposed, false);
assertSuppressionChainAsync(async () => { await stack.disposeAsync() }, errorsToThrow);
assertEq(stack.disposed, true);
assertArrayEq(disposed, [2, 1, 0]);
stack.disposeAsync();
drainJobQueue();
assertArrayEq(disposed, [2, 1, 0]);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3"), new Error("error4")];
async function testStackDisposalWithUsingAndErrors() {
const stack = new AsyncDisposableStack();
for (let i = 0; i < 3; i++) {
stack.use({
[Symbol.asyncDispose]() {
disposed.push(i);
throw errorsToThrow[i];
},
});
}
assertEq(stack.disposed, false);
{
await using stk = stack;
stk.use({
[Symbol.asyncDispose]() {
disposed.push(3);
throw errorsToThrow[3];
},
});
}
}
assertSuppressionChainAsync(testStackDisposalWithUsingAndErrors, errorsToThrow);
assertArrayEq(disposed, [3, 2, 1, 0]);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3")];
async function testStackDisposalWithUseAdoptDeferAndErrors() {
const stack = new AsyncDisposableStack();
stack.use({
[Symbol.asyncDispose]() {
disposed.push(1);
throw errorsToThrow[0];
},
});
stack.adopt(2, (v) => {
disposed.push(v);
throw errorsToThrow[1];
});
stack.defer(() => {
disposed.push(3);
throw errorsToThrow[2];
});
assertEq(stack.disposed, false);
await stack.disposeAsync();
}
assertSuppressionChainAsync(testStackDisposalWithUseAdoptDeferAndErrors, errorsToThrow);
assertArrayEq(disposed, [3, 2, 1]);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3"), new Error("error4")];
async function testStackDisposalWithUseAdoptDeferAndErrorsAndOutsideError() {
await using stack = new AsyncDisposableStack();
stack.use({
[Symbol.asyncDispose]() {
disposed.push(1);
throw errorsToThrow[0];
},
});
stack.adopt(2, (v) => {
disposed.push(v);
throw errorsToThrow[1];
});
stack.defer(() => {
disposed.push(3);
throw errorsToThrow[2];
});
throw errorsToThrow[3];
}
let caught = false;
async function test() {
try {
await testStackDisposalWithUseAdoptDeferAndErrorsAndOutsideError();
} catch (err) {
caught = true;
// the error thrown at function end would be suppressed and while
// disposing the stack there would be another suppressed error.
assertEq(err instanceof SuppressedError, true);
assertEq(err.suppressed === errorsToThrow[3], true);
assertSuppressionChain(() => { throw err.error }, [errorsToThrow[0], errorsToThrow[1], errorsToThrow[2]]);
} finally {
assertEq(caught, true);
}
}
test();
drainJobQueue();
assertArrayEq(disposed, [3, 2, 1]);
}