diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index 904b50aa98..c8e58457fc 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -28,84 +28,86 @@ function asyncTest(testFunc) { } } -assert.throwsAsync = async function (expectedErrorConstructor, func, message) { - var innerThenable; - if (message === undefined) { - message = ""; - } else { - message += " "; - } - if (typeof func === "function") { - try { - innerThenable = func(); - if ( - innerThenable === null || - typeof innerThenable !== "object" || - typeof innerThenable.then !== "function" - ) { - message += - "Expected to obtain an inner promise that would reject with a" + - expectedErrorConstructor.name + - " but result was not a thenable"; - throw new Test262Error(message); - } - } catch (thrown) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; - throw new Test262Error(message); +assert.throwsAsync = function (expectedErrorConstructor, func, message) { + return new Promise(function (resolve) { + var innerThenable; + if (message === undefined) { + message = ""; + } else { + message += " "; } - } else { - message += - "assert.throwsAsync called with an argument that is not a function"; - throw new Test262Error(message); - } - - try { - return innerThenable.then( - function () { + if (typeof func === "function") { + try { + innerThenable = func(); + if ( + innerThenable === null || + typeof innerThenable !== "object" || + typeof innerThenable.then !== "function" + ) { + message += + "Expected to obtain an inner promise that would reject with a" + + expectedErrorConstructor.name + + " but result was not a thenable"; + throw new Test262Error(message); + } + } catch (thrown) { message += "Expected a " + expectedErrorConstructor.name + - " to be thrown asynchronously but no exception was thrown at all"; + " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; throw new Test262Error(message); - }, - function (thrown) { - var expectedName, actualName; - if (typeof thrown !== "object" || thrown === null) { - message += "Thrown value was not an object!"; - throw new Test262Error(message); - } else if (thrown.constructor !== expectedErrorConstructor) { - expectedName = expectedErrorConstructor.name; - actualName = thrown.constructor.name; - if (expectedName === actualName) { - message += - "Expected a " + - expectedName + - " but got a different error constructor with the same name"; - } else { - message += - "Expected a " + expectedName + " but got a " + actualName; - } - throw new Test262Error(message); - } } - ); - } catch (thrown) { - if (typeof thrown !== "object" || thrown === null) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but innerThenable synchronously threw a value that was not an object "; } else { message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but a " + - thrown.constructor.name + - " was thrown synchronously"; + "assert.throwsAsync called with an argument that is not a function"; + throw new Test262Error(message); } - throw new Test262Error(message); - } + + try { + resolve(innerThenable.then( + function () { + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but no exception was thrown at all"; + throw new Test262Error(message); + }, + function (thrown) { + var expectedName, actualName; + if (typeof thrown !== "object" || thrown === null) { + message += "Thrown value was not an object!"; + throw new Test262Error(message); + } else if (thrown.constructor !== expectedErrorConstructor) { + expectedName = expectedErrorConstructor.name; + actualName = thrown.constructor.name; + if (expectedName === actualName) { + message += + "Expected a " + + expectedName + + " but got a different error constructor with the same name"; + } else { + message += + "Expected a " + expectedName + " but got a " + actualName; + } + throw new Test262Error(message); + } + } + )); + } catch (thrown) { + if (typeof thrown !== "object" || thrown === null) { + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but innerThenable synchronously threw a value that was not an object "; + } else { + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but a " + + thrown.constructor.name + + " was thrown synchronously"; + } + throw new Test262Error(message); + } + }); }; diff --git a/test/built-ins/Promise/try/args.js b/test/built-ins/Promise/try/args.js index 225ddd42ce..4a75c3aca4 100644 --- a/test/built-ins/Promise/try/args.js +++ b/test/built-ins/Promise/try/args.js @@ -11,12 +11,12 @@ includes: [asyncHelpers.js, compareArray.js] var sentinel = { sentinel: true }; -asyncTest( - Promise.try(function () { +asyncTest(function () { + return Promise.try(function () { assert.compareArray( Array.prototype.slice.call(arguments), [1, 2, Test262Error, sentinel] ); }, 1, 2, Test262Error, sentinel) -); +}); diff --git a/test/built-ins/Promise/try/ctx-ctor.js b/test/built-ins/Promise/try/ctx-ctor.js index 45a1391d48..06e1069347 100644 --- a/test/built-ins/Promise/try/ctx-ctor.js +++ b/test/built-ins/Promise/try/ctx-ctor.js @@ -20,8 +20,8 @@ class SubPromise extends Promise { var instance = Promise.try.call(SubPromise, function () {}); -assert.sameValue(instance.promise.constructor, SubPromise); -assert.sameValue(instance.promise instanceof SubPromise, true); +assert.sameValue(instance.constructor, SubPromise); +assert.sameValue(instance instanceof SubPromise, true); assert.sameValue(callCount, 1); assert.sameValue(typeof executor, 'function'); diff --git a/test/built-ins/Promise/try/return-value.js b/test/built-ins/Promise/try/return-value.js index 7859051913..6f1ef2a7e8 100644 --- a/test/built-ins/Promise/try/return-value.js +++ b/test/built-ins/Promise/try/return-value.js @@ -11,11 +11,11 @@ includes: [asyncHelpers.js] var sentinel = { sentinel: true }; -asyncTest( - Promise.try(function () { +asyncTest(function() { + return Promise.try(function () { return sentinel; }).then(function (v) { assert.sameValue(v, sentinel); }) -); +}); diff --git a/test/built-ins/Promise/try/throws.js b/test/built-ins/Promise/try/throws.js index ad7f56622d..9dc211490f 100644 --- a/test/built-ins/Promise/try/throws.js +++ b/test/built-ins/Promise/try/throws.js @@ -6,12 +6,15 @@ description: Promise.try returns a Promise that rejects when the function throws esid: sec-promise.try features: [promise-try] flags: [async] +includes: [asyncHelpers.js] ---*/ -assert.throwsAsync( - Test262Error, - function () { - Promise.try(function () { throw new Test262Error(); }) - }, - "error thrown from callback must become a rejection" -); +asyncTest(function () { + return assert.throwsAsync( + Test262Error, + function () { + return Promise.try(function () { throw new Test262Error(); }) + }, + "error thrown from callback must become a rejection" + ); +}); diff --git a/test/staging/explicit-resource-management/disposable-stack-adopt-and-defer.js b/test/staging/explicit-resource-management/disposable-stack-adopt-and-defer.js new file mode 100644 index 0000000000..8835a7bb48 --- /dev/null +++ b/test/staging/explicit-resource-management/disposable-stack-adopt-and-defer.js @@ -0,0 +1,84 @@ +// 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 adopt() and defer(). +includes: [compareArray.js] +features: [explicit-resource-management] +---*/ + +// adopt() method on disposed stack -------- +function TestDisposableStackAdoptOnDisposedStack() { + let stack = new DisposableStack(); + stack.dispose(); + stack.adopt(42, function(v) {return v}); + }; + assert.throws( + ReferenceError, () => TestDisposableStackUseOnDisposedStack(), + 'Cannot add values to a disposed stack!'); + +// adopt() method when onDispose is not callable-------- +function TestDisposableStackAdoptWithNonCallableOnDispose() { + let stack = new DisposableStack(); + stack.adopt(42, 43); +}; +assert.throws( + TypeError, () => TestDisposableStackAdoptWithNonCallableOnDispose(), + 'onDispose is not callable'); + +// adopt() method -------- +let valuesNormal = []; + +(function TestDisposableStackAdopt() { + let stack = new DisposableStack(); + stack.adopt(42, function(v) {valuesNormal.push(v)}); + const disposable = { + value: 1, + [Symbol.dispose]() { + valuesNormal.push(43); + } + }; + stack.use(disposable); + stack.adopt(44, function(v) {valuesNormal.push(v)}); + stack.dispose(); +})(); +assert.compareArray(valuesNormal, [44, 43, 42]); + +// defer() method on disposed stack -------- +function TestDisposableStackDeferOnDisposedStack() { + let stack = new DisposableStack(); + stack.dispose(); + stack.defer(() => console.log(42)); +}; + +assert.throws( + ReferenceError, () => TestDisposableStackDeferOnDisposedStack(), + 'Cannot add values to a disposed stack!'); + +// defer() method when onDispose is not callable-------- +function TestDisposableStackDeferWithNonCallableOnDispose() { + let stack = new DisposableStack(); + stack.defer(42); +}; +assert.throws( + TypeError, () => TestDisposableStackDeferWithNonCallableOnDispose(), + 'onDispose is not callable'); + +// defer() method -------- +let deferValuesNormal = []; + +(function TestDisposableStackAdopt() { + let stack = new DisposableStack(); + stack.defer(() => deferValuesNormal.push(42)); + const disposable = { + value: 1, + [Symbol.dispose]() { + deferValuesNormal.push(43); + } + }; + stack.use(disposable); + stack.defer(() => deferValuesNormal.push(44)); + stack.dispose(); +})(); +assert.compareArray(deferValuesNormal, [44, 43, 42]);