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 DisposableStack();
const obj = {
[Symbol.dispose]() {
disposed.push(1);
throw errorToThrow;
},
};
stack.use(obj);
assertEq(stack.disposed, false);
assertThrowsInstanceOf(() => stack.dispose(), Error);
assertArrayEq(disposed, [1]);
assertEq(stack.disposed, true);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3")];
const stack = new DisposableStack();
for (let i = 0; i < 3; i++) {
stack.use({
[Symbol.dispose]() {
disposed.push(i);
throw errorsToThrow[i];
},
});
}
assertEq(stack.disposed, false);
assertSuppressionChain(() => stack.dispose(), errorsToThrow);
assertEq(stack.disposed, true);
assertArrayEq(disposed, [2, 1, 0]);
stack.dispose();
assertArrayEq(disposed, [2, 1, 0]);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3"), new Error("error4")];
function testStackDisposalWithUsingAndErrors() {
const stack = new DisposableStack();
for (let i = 0; i < 3; i++) {
stack.use({
[Symbol.dispose]() {
disposed.push(i);
throw errorsToThrow[i];
},
});
}
assertEq(stack.disposed, false);
{
using stk = stack;
stk.use({
[Symbol.dispose]() {
disposed.push(3);
throw errorsToThrow[3];
},
});
}
}
assertSuppressionChain(testStackDisposalWithUsingAndErrors, errorsToThrow);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3")];
function testStackDisposalWithUseAdoptDeferAndErrors() {
const stack = new DisposableStack();
stack.use({
[Symbol.dispose]() {
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);
stack.dispose();
}
assertSuppressionChain(testStackDisposalWithUseAdoptDeferAndErrors, errorsToThrow);
assertArrayEq(disposed, [3, 2, 1]);
}
{
const disposed = [];
const errorsToThrow = [new Error("error1"), new Error("error2"), new Error("error3"), new Error("error4")];
function testStackDisposalWithUseAdoptDeferAndErrorsAndOutsideError() {
using stack = new DisposableStack();
stack.use({
[Symbol.dispose]() {
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;
try {
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);
}
}