Skip to content

[explicit-resource-management] Add remaining tests specific to AsyncDisposableStack #4478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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, [[DisposableState]]).
3. If asyncDisposableStack.[[DisposableState]] 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, [[DisposableState]]).
3. If asyncDisposableStack.[[DisposableState]] 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, [[DisposableState]]).
3. If asyncDisposableStack.[[DisposableState]] 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,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');
31 changes: 31 additions & 0 deletions test/built-ins/AsyncDisposableStack/prototype/constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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: |
AsyncDisposableStack.prototype.constructor

Normative Optional

The initial value of AsyncDisposableStack.prototype.constructor is the intrinsic object %AsyncDisposableStack%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

This section is to be treated identically to the "Annex B" of ECMA-262, but to be written in-line with the main specification.
includes: [propertyHelper.js]
features: [explicit-resource-management]
---*/

var actual = AsyncDisposableStack.prototype.hasOwnProperty('constructor');

// If implemented, it should conform to the spec text
if (actual) {
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, [[DisposableState]]).
3. If asyncDisposableStack.[[DisposableState]] 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, [[DisposableState]]).
3. If asyncDisposableStack.[[DisposableState]] 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 the argument provided.
info: |
AsyncDisposableStack.prototype.defer ( onDisposeAsync )

...
6. Return undefined.

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

var stack = new AsyncDisposableStack();
assert.sameValue(stack.defer(_ => {}), undefined);
Loading