Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype-@@toStringTag
description: >
`Symbol.toStringTag` property descriptor
info: |
The initial value of the @@toStringTag property is the String value
'AsyncDisposableStack'.

This property has the attributes { [[Writable]]: false, [[Enumerable]]:
false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [explicit-resource-management, Symbol, Symbol.toStringTag]
---*/

verifyProperty(AsyncDisposableStack.prototype, Symbol.toStringTag, {
value: 'AsyncDisposableStack',
writable: false,
enumerable: false,
configurable: true
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Adds a disposable resource to the stack
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
5. Let closure be a new Abstract Closure with no parameters that captures value and onDisposeAsync and performs the following steps when called:
a. Perform ? Call(onDisposeAsync, undefined, « value »).
6. Let F be CreateBuiltinFunction(closure, 0, "", « »).
7. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, F).
...

AddDisposableResource ( disposeCapability, V, hint [, method ] )

1. If method is not present then,
...
2. Else,
a. Assert: V is undefined.
b. Let resource be ? CreateDisposableResource(undefined, hint, method).
3. Append resource to disposeCapability.[[DisposableResourceStack]].
4. Return unused.

flags: [async]
includes: [asyncHelpers.js]
features: [explicit-resource-management]
---*/

asyncTest(async function () {
var stack = new AsyncDisposableStack();
var resource = { disposed: false };
stack.adopt(resource, async r => { r.disposed = true });
await stack.disposeAsync();
assert.sameValue(resource.disposed, true, 'Expected resource to have been disposed');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Allows any 'value'
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
5. Let closure be a new Abstract Closure with no parameters that captures value and onDisposeAsync and performs the following steps when called:
a. Perform ? Call(onDisposeAsync, undefined, « value »).
6. Let F be CreateBuiltinFunction(closure, 0, "", « »).
7. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, F).
...

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
stack.adopt(null, async _ => {});
stack.adopt(undefined, async _ => {});
stack.adopt({}, async _ => {});
stack.adopt({ async [Symbol.asyncDispose]() {} }, async _ => {});
stack.adopt(() => {}, async _ => {});
stack.adopt(true, async _ => {});
stack.adopt(false, async _ => {});
stack.adopt(1, async _ => {});
stack.adopt('object', async _ => {});
stack.adopt(Symbol(), async _ => {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Adds a disposable resource to the stack
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
5. Let closure be a new Abstract Closure with no parameters that captures value and onDisposeAsync and performs the following steps when called:
a. Perform ? Call(onDisposeAsync, undefined, « value »).
6. Let F be CreateBuiltinFunction(closure, 0, "", « »).
7. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, F).
...

AddDisposableResource ( disposeCapability, V, hint [, method ] )

1. If method is not present then,
...
2. Else,
a. Assert: V is undefined.
b. Let resource be ? CreateDisposableResource(undefined, hint, method).
3. Append resource to disposeCapability.[[DisposableResourceStack]].
4. Return unused.

flags: [async]
includes: [asyncHelpers.js]
features: [explicit-resource-management]
---*/

asyncTest(async function () {
var stack = new AsyncDisposableStack();
var disposed = [];
var resource1 = {};
async function dispose1(res) { disposed.push([res, dispose1]); }
var resource2 = {};
function dispose2(res) { disposed.push([res, dispose2]); }
stack.adopt(resource1, dispose1);
stack.adopt(resource2, dispose2);
await stack.disposeAsync();
assert.sameValue(2, disposed.length);
assert.sameValue(disposed[0][0], resource2, 'Expected resource2 to be the first disposed resource');
assert.sameValue(disposed[0][1], dispose2, 'Expected dispose2 to be the first onDispose invoked');
assert.sameValue(disposed[1][0], resource1, 'Expected resource1 to be the second disposed resource');
assert.sameValue(disposed[1][1], dispose1, 'Expected dispose1 to be the second onDispose invoked');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Returns the argument provided.
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

...
8. Return value.

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
var resource = {};
assert.sameValue(stack.adopt(resource, async _ => {}), resource);
assert.sameValue(stack.adopt(null, async _ => {}), null);
assert.sameValue(stack.adopt(undefined, async _ => {}), undefined);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2026 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Throws a ReferenceError if this is disposed.
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
...

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
stack.disposeAsync();

assert.throws(ReferenceError, function() {
stack.adopt(null, async _ => {});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.adopt
description: Throws if onDisposeAsync argument not callable
info: |
AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync )

...
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
...

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
assert.throws(TypeError, function() {
stack.adopt(null, null);
}, 'null');

assert.throws(TypeError, function() {
stack.adopt(null, undefined);
}, 'undefined');

assert.throws(TypeError, function() {
stack.adopt(null, true);
}, 'true');

assert.throws(TypeError, function() {
stack.adopt(null, false);
}, 'false');

assert.throws(TypeError, function() {
stack.adopt(null, 1);
}, 'number');

assert.throws(TypeError, function() {
stack.adopt(null, 'object');
}, 'string');

assert.throws(TypeError, function() {
stack.adopt(null, {});
}, 'object');

var s = Symbol();
assert.throws(TypeError, function() {
stack.adopt(null, s);
}, 'symbol');
20 changes: 20 additions & 0 deletions test/built-ins/AsyncDisposableStack/prototype/constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-properties-of-the-asyncdisposablestack-prototype-object
description: AsyncDisposableStack.prototype.constructor
info: |
The initial value of AsyncDisposableStack.prototype.constructor is the intrinsic object %AsyncDisposableStack%.

17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [explicit-resource-management]
---*/

verifyProperty(AsyncDisposableStack.prototype, 'constructor', {
value: AsyncDisposableStack,
writable: true,
enumerable: false,
configurable: true
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.defer
description: Adds an onDisposeAsync callback to the stack
info: |
AsyncDisposableStack.prototype.defer ( onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
5. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, onDisposeAsync).
...

AddDisposableResource ( disposeCapability, V, hint [, method ] )

1. If method is not present then,
...
2. Else,
a. Assert: V is undefined.
b. Let resource be ? CreateDisposableResource(undefined, hint, method).
3. Append resource to disposeCapability.[[DisposableResourceStack]].
4. Return unused.

flags: [async]
includes: [asyncHelpers.js]
features: [explicit-resource-management]
---*/

asyncTest(async function () {
var stack = new AsyncDisposableStack();
var disposed = false;
stack.defer(async () => { disposed = true });
await stack.disposeAsync();
assert.sameValue(disposed, true, 'Expected callback to have been called');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.defer
description: Adds a disposable resource to the stack
info: |
AsyncDisposableStack.prototype.defer ( onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. If IsCallable(onDisposeAsync) is false, throw a TypeError exception.
5. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, onDisposeAsync).
...

AddDisposableResource ( disposeCapability, V, hint [, method ] )

1. If method is not present then,
...
2. Else,
a. Assert: V is undefined.
b. Let resource be ? CreateDisposableResource(undefined, hint, method).
3. Append resource to disposeCapability.[[DisposableResourceStack]].
4. Return unused.

flags: [async]
includes: [asyncHelpers.js]
features: [explicit-resource-management]
---*/

asyncTest(async function () {
var stack = new AsyncDisposableStack();
var disposed = [];
async function dispose1() { disposed.push(dispose1); }
function dispose2() { disposed.push(dispose2); }
stack.defer(dispose1);
stack.defer(dispose2);
await stack.disposeAsync();
assert.sameValue(2, disposed.length);
assert.sameValue(disposed[0], dispose2, 'Expected dispose2 to be the first onDisposeAsync invoked');
assert.sameValue(disposed[1], dispose1, 'Expected dispose1 to be the second onDisposeAsync invoked');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.defer
description: Returns undefined.
info: |
AsyncDisposableStack.prototype.defer ( onDisposeAsync )

...
6. Return undefined.

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
assert.sameValue(stack.defer(_ => {}), undefined);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2026 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-asyncdisposablestack.prototype.defer
description: Throws a ReferenceError if this is disposed.
info: |
AsyncDisposableStack.prototype.defer ( onDisposeAsync )

1. Let asyncDisposableStack be the this value.
2. Perform ? RequireInternalSlot(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
...

features: [explicit-resource-management]
---*/

var stack = new AsyncDisposableStack();
stack.disposeAsync();

assert.throws(ReferenceError, function() {
stack.defer(async _ => {});
});
Loading