mirror of https://github.com/tc39/test262.git
[explicit-resource-management] Add DisposableStack constructor, use
and dispose method This CL adds DisposableStack constructor, use() and dispose() methods as developer exposed methods. Also, this CL fixed the use of `using` keyword with `null` and `undefined` and adds tests for them. Bug: 42203506 Change-Id: If50b9e33d9cbb3de2be41dc81e656d9d202b8fa8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5498999 Commit-Queue: Rezvan Mahdavi Hezaveh <rezvan@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/main@{#93807}
This commit is contained in:
parent
55a5346f99
commit
9b4c6577f6
|
@ -0,0 +1,185 @@
|
||||||
|
// Copyright (C) 2024 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
Test developer exposed DisposableStack protype methods use() and dispose().
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [explicit-resource-management]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// use() method on null should not throw --------
|
||||||
|
let valuesWithNull = [];
|
||||||
|
|
||||||
|
(function TestDisposableStackUsewithNull() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
valuesWithNull.push(42);
|
||||||
|
stack.use(null);
|
||||||
|
valuesWithNull.push(43);
|
||||||
|
})();
|
||||||
|
assert.compareArray(valuesWithNull, [42, 43]);
|
||||||
|
|
||||||
|
// use() method on undefined should not throw --------
|
||||||
|
let valuesWithUndefined = [];
|
||||||
|
|
||||||
|
(function TestDisposableStackUseWithUndefined() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
valuesWithUndefined.push(42);
|
||||||
|
stack.use(undefined);
|
||||||
|
valuesWithUndefined.push(43);
|
||||||
|
})();
|
||||||
|
assert.compareArray(valuesWithUndefined, [42, 43]);
|
||||||
|
|
||||||
|
// use() method on a non object --------
|
||||||
|
function TestDisposableStackUseWithNonObject() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
stack.use(42);
|
||||||
|
};
|
||||||
|
assert.throws(
|
||||||
|
TypeError, () => TestDisposableStackUseWithNonObject(),
|
||||||
|
'use() is called on non-object');
|
||||||
|
|
||||||
|
// use() method on normal value --------
|
||||||
|
let valuesNormal = [];
|
||||||
|
|
||||||
|
(function TestDisposableStackUse() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]() {
|
||||||
|
valuesNormal.push(42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
stack.dispose();
|
||||||
|
})();
|
||||||
|
assert.compareArray(valuesNormal, [42]);
|
||||||
|
|
||||||
|
// use() method with null [symbol.dispose] --------
|
||||||
|
function TestDisposableStackUseWithNullDispose() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]: null,
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
};
|
||||||
|
assert.throws(
|
||||||
|
TypeError, () => TestDisposableStackUseWithNullDispose(),
|
||||||
|
'symbol.dispose is null');
|
||||||
|
|
||||||
|
// use() method with undefined [symbol.dispose] --------
|
||||||
|
function TestDisposableStackUseWithUndefinedDispose() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]: undefined,
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
};
|
||||||
|
assert.throws(
|
||||||
|
TypeError, () => TestDisposableStackUseWithUndefinedDispose(),
|
||||||
|
'symbol.dispose is undefined');
|
||||||
|
|
||||||
|
// use() method when [symbol.dispose] is not callable--------
|
||||||
|
function TestDisposableStackUseWithNonCallableDispose() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]: 42,
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
};
|
||||||
|
assert.throws(
|
||||||
|
TypeError, () => TestDisposableStackUseWithNonCallableDispose(),
|
||||||
|
'symbol.dispose is not callable');
|
||||||
|
|
||||||
|
// disposing a disposed stack should not throw --------
|
||||||
|
let valuesWithTwiceDisposal = [];
|
||||||
|
|
||||||
|
(function TestDisposableStackUseDisposingTwice() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]() {
|
||||||
|
valuesWithTwiceDisposal.push(42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
stack.dispose();
|
||||||
|
stack.dispose();
|
||||||
|
})();
|
||||||
|
assert.compareArray(valuesWithTwiceDisposal, [42]);
|
||||||
|
|
||||||
|
// use() method on disposed stack --------
|
||||||
|
function TestDisposableStackUseOnDisposedStack() {
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
stack.dispose();
|
||||||
|
stack.use(disposable);
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
ReferenceError, () => TestDisposableStackUseOnDisposedStack(),
|
||||||
|
'Cannot add values to a disposed stack!');
|
||||||
|
|
||||||
|
// use() method with error inside disposal method --------
|
||||||
|
function TestDisposableStackUseDisposeMethodThrows() {
|
||||||
|
{
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const disposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]() {
|
||||||
|
throw new Test262Error('Symbol.dispose is throwing!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stack.use(disposable);
|
||||||
|
stack.dispose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert.throws(
|
||||||
|
Test262Error, () => TestDisposableStackUseDisposeMethodThrows(),
|
||||||
|
'Symbol.dispose is throwing!');
|
||||||
|
|
||||||
|
// use() method with suppressed error of two disposal method errors--------
|
||||||
|
let firstDisposeError =
|
||||||
|
new Test262Error('The first Symbol.dispose is throwing!');
|
||||||
|
let secondDisposeError =
|
||||||
|
new Test262Error('The second Symbol.dispose is throwing!');
|
||||||
|
|
||||||
|
function TestDisposableStackUseTwoDisposeMethodsThrow() {
|
||||||
|
{
|
||||||
|
let stack = new DisposableStack();
|
||||||
|
const firstDisposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]() {
|
||||||
|
throw firstDisposeError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const secondDisposable = {
|
||||||
|
value: 1,
|
||||||
|
[Symbol.dispose]() {
|
||||||
|
throw secondDisposeError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stack.use(firstDisposable);
|
||||||
|
stack.use(secondDisposable);
|
||||||
|
stack.dispose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
SuppressedError, () => TestDisposableStackUseTwoDisposeMethodsThrow(),
|
||||||
|
'An error was suppressed during disposal');
|
||||||
|
|
||||||
|
function RunTestDisposableStackUseTwoDisposeMethodsThrow() {
|
||||||
|
try {
|
||||||
|
TestDisposableStackUseTwoDisposeMethodsThrow();
|
||||||
|
} catch (error) {
|
||||||
|
assert(
|
||||||
|
error instanceof SuppressedError,
|
||||||
|
'error is an instanceof SuppressedError');
|
||||||
|
assert.sameValue(error.error, firstDisposeError, 'error.error');
|
||||||
|
assert.sameValue(error.suppressed, secondDisposeError, 'error.suppressed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RunTestDisposableStackUseTwoDisposeMethodsThrow();
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (C) 2024 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
description: using with null or undefined should not throw.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [explicit-resource-management]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// Use using with null --------------
|
||||||
|
let withNullvalues = [];
|
||||||
|
|
||||||
|
(function TestUsingWithNull() {
|
||||||
|
let using = null;
|
||||||
|
withNullvalues.push(42);
|
||||||
|
})();
|
||||||
|
assert.compareArray(withNullvalues, [42]);
|
||||||
|
|
||||||
|
// Use using with undefined --------------
|
||||||
|
let withUndefinedvalues = [];
|
||||||
|
|
||||||
|
(function TestUsingWithUndefined() {
|
||||||
|
let using = undefined;
|
||||||
|
withUndefinedvalues.push(42);
|
||||||
|
})();
|
||||||
|
assert.compareArray(withUndefinedvalues, [42]);
|
Loading…
Reference in New Issue