diff --git a/cli/tests/unit/net_test.ts b/cli/tests/unit/net_test.ts index 6165e77f6aa9e2..b1f4f87ca83fee 100644 --- a/cli/tests/unit/net_test.ts +++ b/cli/tests/unit/net_test.ts @@ -5,7 +5,7 @@ import { assertNotEquals, assertThrows, assertThrowsAsync, - createResolvable, + deferred, unitTest, } from "./test_util.ts"; @@ -306,7 +306,7 @@ unitTest( unitTest( { perms: { net: true } }, async function netTcpListenIteratorBreakClosesResource(): Promise { - const promise = createResolvable(); + const promise = deferred(); async function iterate(listener: Deno.Listener): Promise { let i = 0; @@ -440,7 +440,7 @@ unitTest( async function netCloseWriteSuccess() { const addr = { hostname: "127.0.0.1", port: 3500 }; const listener = Deno.listen(addr); - const closeDeferred = createResolvable(); + const closeDeferred = deferred(); listener.accept().then(async (conn) => { await conn.write(new Uint8Array([1, 2, 3])); await closeDeferred; @@ -474,7 +474,7 @@ unitTest( async function netDoubleCloseWrite() { const addr = { hostname: "127.0.0.1", port: 3500 }; const listener = Deno.listen(addr); - const closeDeferred = createResolvable(); + const closeDeferred = deferred(); listener.accept().then(async (conn) => { await closeDeferred; conn.close(); @@ -497,7 +497,7 @@ unitTest( }, async function netHangsOnClose() { let acceptedConn: Deno.Conn; - const resolvable = createResolvable(); + const resolvable = deferred(); async function iteratorReq(listener: Deno.Listener): Promise { const p = new Uint8Array(10); diff --git a/cli/tests/unit/performance_test.ts b/cli/tests/unit/performance_test.ts index 122938b369f453..2b8bc620df7454 100644 --- a/cli/tests/unit/performance_test.ts +++ b/cli/tests/unit/performance_test.ts @@ -3,14 +3,14 @@ import { assert, assertEquals, assertThrows, - createResolvable, + deferred, unitTest, } from "./test_util.ts"; unitTest({ perms: { hrtime: false } }, async function performanceNow(): Promise< void > { - const resolvable = createResolvable(); + const resolvable = deferred(); const start = performance.now(); setTimeout((): void => { const end = performance.now(); diff --git a/cli/tests/unit/signal_test.ts b/cli/tests/unit/signal_test.ts index 2ea1e865ff3269..4f97a82e449bf0 100644 --- a/cli/tests/unit/signal_test.ts +++ b/cli/tests/unit/signal_test.ts @@ -3,7 +3,7 @@ import { assert, assertEquals, assertThrows, - createResolvable, + deferred, unitTest, } from "./test_util.ts"; @@ -106,7 +106,7 @@ unitTest( unitTest( { ignore: Deno.build.os === "windows", perms: { run: true, net: true } }, async function signalStreamTest(): Promise { - const resolvable = createResolvable(); + const resolvable = deferred(); // This prevents the program from exiting. const t = setInterval(() => {}, 1000); @@ -137,7 +137,7 @@ unitTest( unitTest( { ignore: Deno.build.os === "windows", perms: { run: true } }, async function signalPromiseTest(): Promise { - const resolvable = createResolvable(); + const resolvable = deferred(); // This prevents the program from exiting. const t = setInterval(() => {}, 1000); diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index 6163865de3ca57..39a1949c3c26a6 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -16,6 +16,7 @@ export { fail, unreachable, } from "../../../std/testing/asserts.ts"; +export { deferred } from "../../../std/async/deferred.ts"; export { readLines } from "../../../std/io/bufio.ts"; export { parse as parseArgs } from "../../../std/flags/mod.ts"; @@ -187,24 +188,6 @@ export function unitTest( REGISTERED_UNIT_TESTS.push(unitTestDefinition); } -export interface ResolvableMethods { - resolve: (value: T | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; -} - -export type Resolvable = Promise & ResolvableMethods; - -export function createResolvable(): Resolvable { - let methods: ResolvableMethods; - const promise = new Promise((resolve, reject): void => { - methods = { resolve, reject }; - }); - // TypeScript doesn't know that the Promise callback occurs synchronously - // therefore use of not null assertion (`!`) - return Object.assign(promise, methods!) as Resolvable; -} - const encoder = new TextEncoder(); // Replace functions with null, errors with their stack strings, and JSONify. diff --git a/cli/tests/unit/timers_test.ts b/cli/tests/unit/timers_test.ts index af876b742a8474..e315d018ace916 100644 --- a/cli/tests/unit/timers_test.ts +++ b/cli/tests/unit/timers_test.ts @@ -3,7 +3,7 @@ import { assert, assertEquals, assertNotEquals, - createResolvable, + deferred, unitTest, } from "./test_util.ts"; @@ -12,7 +12,7 @@ function waitForMs(ms: number): Promise { } unitTest(async function timeoutSuccess(): Promise { - const promise = createResolvable(); + const promise = deferred(); let count = 0; setTimeout((): void => { count++; @@ -24,7 +24,7 @@ unitTest(async function timeoutSuccess(): Promise { }); unitTest(async function timeoutArgs(): Promise { - const promise = createResolvable(); + const promise = deferred(); const arg = 1; setTimeout( (a, b, c): void => { @@ -79,7 +79,7 @@ unitTest(async function timeoutCancelMultiple(): Promise { unitTest(async function timeoutCancelInvalidSilentFail(): Promise { // Expect no panic - const promise = createResolvable(); + const promise = deferred(); let count = 0; const id = setTimeout((): void => { count++; @@ -95,7 +95,7 @@ unitTest(async function timeoutCancelInvalidSilentFail(): Promise { }); unitTest(async function intervalSuccess(): Promise { - const promise = createResolvable(); + const promise = deferred(); let count = 0; const id = setInterval((): void => { count++; @@ -155,7 +155,7 @@ unitTest(async function fireCallbackImmediatelyWhenDelayOverMaxValue(): Promise< }); unitTest(async function timeoutCallbackThis(): Promise { - const promise = createResolvable(); + const promise = deferred(); const obj = { foo(): void { assertEquals(this, window); @@ -182,7 +182,7 @@ unitTest(async function timeoutBindThis(): Promise { ]; for (const thisArg of thisCheckPassed) { - const resolvable = createResolvable(); + const resolvable = deferred(); let hasThrown = 0; try { setTimeout.call(thisArg, () => resolvable.resolve(), 1); @@ -286,7 +286,7 @@ unitTest(async function timerMaxCpuBug(): Promise { unitTest(async function timerBasicMicrotaskOrdering(): Promise { let s = ""; let count = 0; - const promise = createResolvable(); + const promise = deferred(); setTimeout(() => { Promise.resolve().then(() => { count++; @@ -309,7 +309,7 @@ unitTest(async function timerBasicMicrotaskOrdering(): Promise { unitTest(async function timerNestedMicrotaskOrdering(): Promise { let s = ""; - const promise = createResolvable(); + const promise = deferred(); s += "0"; setTimeout(() => { s += "4"; @@ -349,7 +349,7 @@ unitTest(function testQueueMicrotask() { unitTest(async function timerIgnoresDateOverride(): Promise { const OriginalDate = Date; - const promise = createResolvable(); + const promise = deferred(); let hasThrown = 0; try { const overrideCalled: () => number = () => { diff --git a/cli/tests/unit/tls_test.ts b/cli/tests/unit/tls_test.ts index 058abf5d709419..9e1c66161a9048 100644 --- a/cli/tests/unit/tls_test.ts +++ b/cli/tests/unit/tls_test.ts @@ -4,7 +4,7 @@ import { assertEquals, assertThrows, assertThrowsAsync, - createResolvable, + deferred, unitTest, } from "./test_util.ts"; import { BufReader, BufWriter } from "../../../std/io/bufio.ts"; @@ -121,7 +121,7 @@ unitTest( unitTest( { perms: { read: true, net: true } }, async function dialAndListenTLS(): Promise { - const resolvable = createResolvable(); + const resolvable = deferred(); const hostname = "localhost"; const port = 3500; diff --git a/cli/tests/websocket_test.ts b/cli/tests/websocket_test.ts index 0a91ac3088424d..51876dc59222ea 100644 --- a/cli/tests/websocket_test.ts +++ b/cli/tests/websocket_test.ts @@ -3,9 +3,9 @@ import { assert, assertEquals, assertThrows, - createResolvable, fail, -} from "./unit/test_util.ts"; +} from "../../std/testing/asserts.ts"; +import { deferred } from "../../std/async/deferred.ts"; Deno.test("invalid scheme", () => { assertThrows(() => new WebSocket("foo://localhost:4242")); @@ -21,7 +21,7 @@ Deno.test("duplicate protocols", () => { }); Deno.test("invalid server", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:2121"); let err = false; ws.onerror = (): void => { @@ -39,7 +39,7 @@ Deno.test("invalid server", async () => { }); Deno.test("connect & close", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => { @@ -52,7 +52,7 @@ Deno.test("connect & close", async () => { }); Deno.test("connect & abort", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.close(); let err = false; @@ -71,7 +71,7 @@ Deno.test("connect & abort", async () => { }); Deno.test("connect & close custom valid code", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => ws.close(1000); @@ -82,7 +82,7 @@ Deno.test("connect & close custom valid code", async () => { }); Deno.test("connect & close custom invalid code", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => { @@ -96,7 +96,7 @@ Deno.test("connect & close custom invalid code", async () => { }); Deno.test("connect & close custom valid reason", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => ws.close(1000, "foo"); @@ -107,7 +107,7 @@ Deno.test("connect & close custom valid reason", async () => { }); Deno.test("connect & close custom invalid reason", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => { @@ -121,7 +121,7 @@ Deno.test("connect & close custom invalid reason", async () => { }); Deno.test("echo string", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.onerror = (): void => fail(); ws.onopen = (): void => ws.send("foo"); @@ -136,8 +136,8 @@ Deno.test("echo string", async () => { }); Deno.test("echo string tls", async () => { - const promise1 = createResolvable(); - const promise2 = createResolvable(); + const promise1 = deferred(); + const promise2 = deferred(); const ws = new WebSocket("wss://localhost:4243"); ws.onerror = (): void => fail(); ws.onopen = (): void => ws.send("foo"); @@ -154,7 +154,7 @@ Deno.test("echo string tls", async () => { }); Deno.test("websocket error", async () => { - const promise1 = createResolvable(); + const promise1 = deferred(); const ws = new WebSocket("wss://localhost:4242"); ws.onopen = () => fail(); ws.onerror = (err): void => { @@ -166,7 +166,7 @@ Deno.test("websocket error", async () => { }); Deno.test("echo blob with binaryType blob", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); const blob = new Blob(["foo"]); ws.onerror = (): void => fail(); @@ -186,7 +186,7 @@ Deno.test("echo blob with binaryType blob", async () => { }); Deno.test("echo blob with binaryType arraybuffer", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.binaryType = "arraybuffer"; const blob = new Blob(["foo"]); @@ -205,7 +205,7 @@ Deno.test("echo blob with binaryType arraybuffer", async () => { }); Deno.test("echo uint8array with binaryType blob", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); const uint = new Uint8Array([102, 111, 111]); ws.onerror = (): void => fail(); @@ -223,7 +223,7 @@ Deno.test("echo uint8array with binaryType blob", async () => { }); Deno.test("echo uint8array with binaryType arraybuffer", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.binaryType = "arraybuffer"; const uint = new Uint8Array([102, 111, 111]); @@ -240,7 +240,7 @@ Deno.test("echo uint8array with binaryType arraybuffer", async () => { }); Deno.test("echo arraybuffer with binaryType blob", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); const buffer = new ArrayBuffer(3); ws.onerror = (): void => fail(); @@ -258,7 +258,7 @@ Deno.test("echo arraybuffer with binaryType blob", async () => { }); Deno.test("echo arraybuffer with binaryType arraybuffer", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); ws.binaryType = "arraybuffer"; const buffer = new ArrayBuffer(3); @@ -275,7 +275,7 @@ Deno.test("echo arraybuffer with binaryType arraybuffer", async () => { }); Deno.test("Event Handlers order", async () => { - const promise = createResolvable(); + const promise = deferred(); const ws = new WebSocket("ws://localhost:4242"); const arr: number[] = []; ws.onerror = (): void => fail(); diff --git a/cli/tests/workers_round_robin_bench.ts b/cli/tests/workers_round_robin_bench.ts index 2edb92b8c54c49..8467480b86d568 100644 --- a/cli/tests/workers_round_robin_bench.ts +++ b/cli/tests/workers_round_robin_bench.ts @@ -5,26 +5,10 @@ const data = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n"; const workerCount = 4; const cmdsPerWorker = 400; -export interface ResolvableMethods { - resolve: (value: T | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; -} - -export type Resolvable = Promise & ResolvableMethods; - -export function createResolvable(): Resolvable { - let methods: ResolvableMethods; - const promise = new Promise((resolve, reject): void => { - methods = { resolve, reject }; - }); - // TypeScript doesn't know that the Promise callback occurs synchronously - // therefore use of not null assertion (`!`) - return Object.assign(promise, methods!) as Resolvable; -} +import { Deferred, deferred } from "../../std/async/deferred.ts"; function handleAsyncMsgFromWorker( - promiseTable: Map>, + promiseTable: Map>, msg: { cmdId: number; data: string }, ): void { const promise = promiseTable.get(msg.cmdId); @@ -35,13 +19,13 @@ function handleAsyncMsgFromWorker( } async function main(): Promise { - const workers: Array<[Map>, Worker]> = []; + const workers: Array<[Map>, Worker]> = []; for (let i = 1; i <= workerCount; ++i) { const worker = new Worker( new URL("subdir/bench_worker.ts", import.meta.url).href, { type: "module" }, ); - const promise = createResolvable(); + const promise = deferred(); worker.onmessage = (e): void => { if (e.data.cmdId === 0) promise.resolve(); }; @@ -58,7 +42,7 @@ async function main(): Promise { for (const cmdId of Array(cmdsPerWorker).keys()) { const promises: Array> = []; for (const [promiseTable, worker] of workers) { - const promise = createResolvable(); + const promise = deferred(); promiseTable.set(cmdId, promise); worker.postMessage({ cmdId: cmdId, action: 1, data }); promises.push(promise); @@ -68,7 +52,7 @@ async function main(): Promise { } } for (const [, worker] of workers) { - const promise = createResolvable(); + const promise = deferred(); worker.onmessage = (e): void => { if (e.data.cmdId === 3) promise.resolve(); }; diff --git a/cli/tests/workers_test.ts b/cli/tests/workers_test.ts index c74680c27f8586..e5b0eaa749152d 100644 --- a/cli/tests/workers_test.ts +++ b/cli/tests/workers_test.ts @@ -8,29 +8,12 @@ // again moved to `cli/js/` as an unit test file. import { assert, assertEquals } from "../../std/testing/asserts.ts"; - -export interface ResolvableMethods { - resolve: (value: T | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; -} - -export type Resolvable = Promise & ResolvableMethods; - -export function createResolvable(): Resolvable { - let methods: ResolvableMethods; - const promise = new Promise((resolve, reject): void => { - methods = { resolve, reject }; - }); - // TypeScript doesn't know that the Promise callback occurs synchronously - // therefore use of not null assertion (`!`) - return Object.assign(promise, methods!) as Resolvable; -} +import { deferred } from "../../std/async/deferred.ts"; Deno.test({ name: "worker terminate", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const jsWorker = new Worker( new URL("subdir/test_worker.js", import.meta.url).href, @@ -66,7 +49,7 @@ Deno.test({ Deno.test({ name: "worker nested", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const nestedWorker = new Worker( new URL("subdir/nested_worker.js", import.meta.url).href, @@ -87,7 +70,7 @@ Deno.test({ Deno.test({ name: "worker throws when executing", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const throwingWorker = new Worker( new URL("subdir/throwing_worker.js", import.meta.url).href, { type: "module" }, @@ -108,7 +91,7 @@ Deno.test({ Deno.test({ name: "worker globals", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const w = new Worker( new URL("subdir/worker_globals.ts", import.meta.url).href, { type: "module" }, @@ -126,7 +109,7 @@ Deno.test({ Deno.test({ name: "worker fetch API", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const fetchingWorker = new Worker( new URL("subdir/fetching_worker.js", import.meta.url).href, @@ -153,7 +136,7 @@ Deno.test({ Deno.test({ name: "worker terminate busy loop", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const busyWorker = new Worker( new URL("subdir/busy_worker.js", import.meta.url).href, @@ -186,7 +169,7 @@ Deno.test({ fn: async function (): Promise { // See issue for details // https://github.com/denoland/deno/issues/4080 - const promise = createResolvable(); + const promise = deferred(); const racyWorker = new Worker( new URL("subdir/racy_worker.js", import.meta.url).href, @@ -213,8 +196,8 @@ Deno.test({ let messageHandlersCalled = 0; let errorHandlersCalled = 0; - const promise1 = createResolvable(); - const promise2 = createResolvable(); + const promise1 = deferred(); + const promise2 = deferred(); const worker = new Worker( new URL("subdir/event_worker.js", import.meta.url).href, @@ -258,7 +241,7 @@ Deno.test({ Deno.test({ name: "worker scope is event listener", fn: async function (): Promise { - const promise1 = createResolvable(); + const promise1 = deferred(); const worker = new Worker( new URL("subdir/event_worker_scope.js", import.meta.url).href, @@ -286,8 +269,8 @@ Deno.test({ Deno.test({ name: "worker with Deno namespace", fn: async function (): Promise { - const promise = createResolvable(); - const promise2 = createResolvable(); + const promise = deferred(); + const promise2 = deferred(); const regularWorker = new Worker( new URL("subdir/non_deno_worker.js", import.meta.url).href, @@ -320,7 +303,7 @@ Deno.test({ Deno.test({ name: "worker with crypto in scope", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const w = new Worker( new URL("subdir/worker_crypto.js", import.meta.url).href, { type: "module" }, @@ -338,7 +321,7 @@ Deno.test({ Deno.test({ name: "Worker event handler order", fn: async function (): Promise { - const promise = createResolvable(); + const promise = deferred(); const w = new Worker( new URL("subdir/test_worker.ts", import.meta.url).href, { type: "module", name: "tsWorker" },