summaryrefslogtreecommitdiff
path: root/cli/tests/testdata
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2024-02-08 13:09:47 -0700
committerGitHub <noreply@github.com>2024-02-08 13:09:47 -0700
commita417772bd7dc4f8508621ec7b2fb75f9bfeca955 (patch)
treef2f522db2abb07eb5472cf9d81645506b6d91380 /cli/tests/testdata
parentd704007e5fdcf1f27030dc5832b884290f1f35de (diff)
chore: Promote some integration tests to js_unit_tests (#22355)
- Move a workers test to js_unit_tests and make it work - (slightly) repair the websocketstream_test and make it a JS unit test. This test was being ignored and rotted quite a bit, but there's some value in running as much of it as we can. - Merge the two websocket test files
Diffstat (limited to 'cli/tests/testdata')
-rw-r--r--cli/tests/testdata/run/websocket_test.ts308
-rw-r--r--cli/tests/testdata/run/websocketstream_test.ts335
-rw-r--r--cli/tests/testdata/workers/test.ts844
-rw-r--r--cli/tests/testdata/workers/test.ts.out3
4 files changed, 0 insertions, 1490 deletions
diff --git a/cli/tests/testdata/run/websocket_test.ts b/cli/tests/testdata/run/websocket_test.ts
deleted file mode 100644
index b6c5744af..000000000
--- a/cli/tests/testdata/run/websocket_test.ts
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-import {
- assert,
- assertEquals,
- assertThrows,
- fail,
-} from "../../../../test_util/std/assert/mod.ts";
-
-Deno.test("invalid scheme", () => {
- assertThrows(() => new WebSocket("foo://localhost:4242"));
-});
-
-Deno.test("fragment", () => {
- assertThrows(() => new WebSocket("ws://localhost:4242/#"));
- assertThrows(() => new WebSocket("ws://localhost:4242/#foo"));
-});
-
-Deno.test("duplicate protocols", () => {
- assertThrows(() => new WebSocket("ws://localhost:4242", ["foo", "foo"]));
-});
-
-Deno.test("invalid server", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:2121");
- let err = false;
- ws.onerror = () => {
- err = true;
- };
- ws.onclose = () => {
- if (err) {
- resolve();
- } else {
- fail();
- }
- };
- ws.onopen = () => fail();
- await promise;
-});
-
-Deno.test("connect & close", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & abort", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.close();
- let err = false;
- ws.onerror = () => {
- err = true;
- };
- ws.onclose = () => {
- if (err) {
- resolve();
- } else {
- fail();
- }
- };
- ws.onopen = () => fail();
- await promise;
-});
-
-Deno.test("connect & close custom valid code", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.close(1000);
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom invalid code", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- assertThrows(() => ws.close(1001));
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom valid reason", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.close(1000, "foo");
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom invalid reason", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- assertThrows(() => ws.close(1000, "".padEnd(124, "o")));
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo string", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.send("foo");
- ws.onmessage = (e) => {
- assertEquals(e.data, "foo");
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo string tls", async () => {
- const deferred1 = Promise.withResolvers<void>();
- const deferred2 = Promise.withResolvers<void>();
- const ws = new WebSocket("wss://localhost:4243");
- ws.onerror = () => fail();
- ws.onopen = () => ws.send("foo");
- ws.onmessage = (e) => {
- assertEquals(e.data, "foo");
- ws.close();
- deferred1.resolve();
- };
- ws.onclose = () => {
- deferred2.resolve();
- };
- await deferred1.promise;
- await deferred2.promise;
-});
-
-Deno.test("websocket error", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("wss://localhost:4242");
- ws.onopen = () => fail();
- ws.onerror = (err) => {
- assert(err instanceof ErrorEvent);
- assertEquals(
- err.message,
- "NetworkError: failed to connect to WebSocket: received corrupt message of type InvalidContentType",
- );
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo blob with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const blob = new Blob(["foo"]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(blob);
- ws.onmessage = (e) => {
- e.data.text().then((actual: string) => {
- blob.text().then((expected) => {
- assertEquals(actual, expected);
- });
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo blob with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const blob = new Blob(["foo"]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(blob);
- ws.onmessage = (e) => {
- blob.arrayBuffer().then((expected) => {
- assertEquals(e.data, expected);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo uint8array with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const uint = new Uint8Array([102, 111, 111]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(uint);
- ws.onmessage = (e) => {
- e.data.arrayBuffer().then((actual: ArrayBuffer) => {
- assertEquals(actual, uint.buffer);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo uint8array with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const uint = new Uint8Array([102, 111, 111]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(uint);
- ws.onmessage = (e) => {
- assertEquals(e.data, uint.buffer);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo arraybuffer with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const buffer = new ArrayBuffer(3);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(buffer);
- ws.onmessage = (e) => {
- e.data.arrayBuffer().then((actual: ArrayBuffer) => {
- assertEquals(actual, buffer);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo arraybuffer with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const buffer = new ArrayBuffer(3);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(buffer);
- ws.onmessage = (e) => {
- assertEquals(e.data, buffer);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("Event Handlers order", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const arr: number[] = [];
- ws.onerror = () => fail();
- ws.addEventListener("message", () => arr.push(1));
- ws.onmessage = () => fail();
- ws.addEventListener("message", () => {
- arr.push(3);
- ws.close();
- assertEquals(arr, [1, 2, 3]);
- });
- ws.onmessage = () => arr.push(2);
- ws.onopen = () => ws.send("Echo");
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("Close without frame", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4244");
- ws.onerror = () => fail();
- ws.onclose = (e) => {
- assertEquals(e.code, 1005);
- resolve();
- };
- await promise;
-});
diff --git a/cli/tests/testdata/run/websocketstream_test.ts b/cli/tests/testdata/run/websocketstream_test.ts
deleted file mode 100644
index b9157c25e..000000000
--- a/cli/tests/testdata/run/websocketstream_test.ts
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-
-import {
- assert,
- assertEquals,
- assertNotEquals,
- assertRejects,
- assertThrows,
- unreachable,
-} from "../../../../test_util/std/assert/mod.ts";
-
-Deno.test("fragment", () => {
- assertThrows(() => new WebSocketStream("ws://localhost:4242/#"));
- assertThrows(() => new WebSocketStream("ws://localhost:4242/#foo"));
-});
-
-Deno.test("duplicate protocols", () => {
- assertThrows(() =>
- new WebSocketStream("ws://localhost:4242", {
- protocols: ["foo", "foo"],
- })
- );
-});
-
-Deno.test("connect & close custom valid code", async () => {
- const ws = new WebSocketStream("ws://localhost:4242");
- await ws.opened;
- ws.close({ code: 1000 });
- await ws.closed;
-});
-
-Deno.test("connect & close custom invalid reason", async () => {
- const ws = new WebSocketStream("ws://localhost:4242");
- await ws.opened;
- assertThrows(() => ws.close({ code: 1000, reason: "".padEnd(124, "o") }));
- ws.close();
- await ws.closed;
-});
-
-Deno.test("echo string", async () => {
- const ws = new WebSocketStream("ws://localhost:4242");
- const { readable, writable } = await ws.opened;
- await writable.getWriter().write("foo");
- const res = await readable.getReader().read();
- assertEquals(res.value, "foo");
- ws.close();
- await ws.closed;
-});
-
-Deno.test("echo string tls", async () => {
- const ws = new WebSocketStream("wss://localhost:4243");
- const { readable, writable } = await ws.opened;
- await writable.getWriter().write("foo");
- const res = await readable.getReader().read();
- assertEquals(res.value, "foo");
- ws.close();
- await ws.closed;
-});
-
-Deno.test("websocket error", async () => {
- const ws = new WebSocketStream("wss://localhost:4242");
- await Promise.all([
- assertRejects(
- () => ws.opened,
- Deno.errors.UnexpectedEof,
- "tls handshake eof",
- ),
- assertRejects(
- () => ws.closed,
- Deno.errors.UnexpectedEof,
- "tls handshake eof",
- ),
- ]);
-});
-
-Deno.test("echo uint8array", async () => {
- const ws = new WebSocketStream("ws://localhost:4242");
- const { readable, writable } = await ws.opened;
- const uint = new Uint8Array([102, 111, 111]);
- await writable.getWriter().write(uint);
- const res = await readable.getReader().read();
- assertEquals(res.value, uint);
- ws.close();
- await ws.closed;
-});
-
-Deno.test("aborting immediately throws an AbortError", async () => {
- const controller = new AbortController();
- const wss = new WebSocketStream("ws://localhost:4242", {
- signal: controller.signal,
- });
- controller.abort();
- await assertRejects(
- () => wss.opened,
- (error: Error) => {
- assert(error instanceof DOMException);
- assertEquals(error.name, "AbortError");
- },
- );
- await assertRejects(
- () => wss.closed,
- (error: Error) => {
- assert(error instanceof DOMException);
- assertEquals(error.name, "AbortError");
- },
- );
-});
-
-Deno.test("aborting immediately with a reason throws that reason", async () => {
- const controller = new AbortController();
- const wss = new WebSocketStream("ws://localhost:4242", {
- signal: controller.signal,
- });
- const abortReason = new Error();
- controller.abort(abortReason);
- await assertRejects(
- () => wss.opened,
- (error: Error) => assertEquals(error, abortReason),
- );
- await assertRejects(
- () => wss.closed,
- (error: Error) => assertEquals(error, abortReason),
- );
-});
-
-Deno.test("aborting immediately with a primitive as reason throws that primitive", async () => {
- const controller = new AbortController();
- const wss = new WebSocketStream("ws://localhost:4242", {
- signal: controller.signal,
- });
- controller.abort("Some string");
- await wss.opened.then(
- () => unreachable(),
- (e) => assertEquals(e, "Some string"),
- );
- await wss.closed.then(
- () => unreachable(),
- (e) => assertEquals(e, "Some string"),
- );
-});
-
-Deno.test("headers", async () => {
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- assertEquals(request.headers.get("x-some-header"), "foo");
- const { response, socket } = Deno.upgradeWebSocket(request);
- socket.onopen = () => socket.close();
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => socket.close();
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512", {
- headers: [["x-some-header", "foo"]],
- });
- await ws.opened;
- await promise;
- await ws.closed;
- listener.close();
-});
-
-Deno.test("forbidden headers", async () => {
- const forbiddenHeaders = [
- "sec-websocket-accept",
- "sec-websocket-extensions",
- "sec-websocket-key",
- "sec-websocket-protocol",
- "sec-websocket-version",
- "upgrade",
- "connection",
- ];
-
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- for (const [key] of request.headers) {
- assertNotEquals(key, "foo");
- }
- const { response, socket } = Deno.upgradeWebSocket(request);
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => socket.close();
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512", {
- headers: forbiddenHeaders.map((header) => [header, "foo"]),
- });
- await ws.opened;
- await promise;
- await ws.closed;
- listener.close();
-});
-
-Deno.test("sync close with empty stream", async () => {
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- const { response, socket } = Deno.upgradeWebSocket(request);
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => {
- socket.send("first message");
- socket.send("second message");
- };
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512");
- const { readable } = await ws.opened;
- const reader = readable.getReader();
- const firstMessage = await reader.read();
- assertEquals(firstMessage.value, "first message");
- const secondMessage = await reader.read();
- assertEquals(secondMessage.value, "second message");
- ws.close({ code: 1000 });
- await ws.closed;
- await promise;
- listener.close();
-});
-
-Deno.test("sync close with unread messages in stream", async () => {
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- const { response, socket } = Deno.upgradeWebSocket(request);
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => {
- socket.send("first message");
- socket.send("second message");
- socket.send("third message");
- socket.send("fourth message");
- };
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512");
- const { readable } = await ws.opened;
- const reader = readable.getReader();
- const firstMessage = await reader.read();
- assertEquals(firstMessage.value, "first message");
- const secondMessage = await reader.read();
- assertEquals(secondMessage.value, "second message");
- ws.close({ code: 1000 });
- await ws.closed;
- await promise;
- listener.close();
-});
-
-Deno.test("async close with empty stream", async () => {
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- const { response, socket } = Deno.upgradeWebSocket(request);
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => {
- socket.send("first message");
- socket.send("second message");
- };
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512");
- const { readable } = await ws.opened;
- const reader = readable.getReader();
- const firstMessage = await reader.read();
- assertEquals(firstMessage.value, "first message");
- const secondMessage = await reader.read();
- assertEquals(secondMessage.value, "second message");
- setTimeout(() => {
- ws.close({ code: 1000 });
- }, 0);
- await ws.closed;
- await promise;
- listener.close();
-});
-
-Deno.test("async close with unread messages in stream", async () => {
- const listener = Deno.listen({ port: 4512 });
- const promise = (async () => {
- const conn = await listener.accept();
- const httpConn = Deno.serveHttp(conn);
- const { request, respondWith } = (await httpConn.nextRequest())!;
- const { response, socket } = Deno.upgradeWebSocket(request);
- const p = new Promise<void>((resolve) => {
- socket.onopen = () => {
- socket.send("first message");
- socket.send("second message");
- socket.send("third message");
- socket.send("fourth message");
- };
- socket.onclose = () => resolve();
- });
- await respondWith(response);
- await p;
- })();
-
- const ws = new WebSocketStream("ws://localhost:4512");
- const { readable } = await ws.opened;
- const reader = readable.getReader();
- const firstMessage = await reader.read();
- assertEquals(firstMessage.value, "first message");
- const secondMessage = await reader.read();
- assertEquals(secondMessage.value, "second message");
- setTimeout(() => {
- ws.close({ code: 1000 });
- }, 0);
- await ws.closed;
- await promise;
- listener.close();
-});
diff --git a/cli/tests/testdata/workers/test.ts b/cli/tests/testdata/workers/test.ts
deleted file mode 100644
index 2fecc63e0..000000000
--- a/cli/tests/testdata/workers/test.ts
+++ /dev/null
@@ -1,844 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-
-// Requires to be run with `--allow-net` flag
-
-import {
- assert,
- assertEquals,
- assertMatch,
- assertThrows,
-} from "../../../../test_util/std/assert/mod.ts";
-
-Deno.test({
- name: "worker terminate",
- fn: async function () {
- const jsWorker = new Worker(
- import.meta.resolve("./test_worker.js"),
- { type: "module" },
- );
- const tsWorker = new Worker(
- import.meta.resolve("./test_worker.ts"),
- { type: "module", name: "tsWorker" },
- );
-
- const deferred1 = Promise.withResolvers<string>();
- jsWorker.onmessage = (e) => {
- deferred1.resolve(e.data);
- };
-
- const deferred2 = Promise.withResolvers<string>();
- tsWorker.onmessage = (e) => {
- deferred2.resolve(e.data);
- };
-
- jsWorker.postMessage("Hello World");
- assertEquals(await deferred1.promise, "Hello World");
- tsWorker.postMessage("Hello World");
- assertEquals(await deferred2.promise, "Hello World");
- tsWorker.terminate();
- jsWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker from data url",
- async fn() {
- const tsWorker = new Worker(
- "data:application/typescript;base64,aWYgKHNlbGYubmFtZSAhPT0gInRzV29ya2VyIikgewogIHRocm93IEVycm9yKGBJbnZhbGlkIHdvcmtlciBuYW1lOiAke3NlbGYubmFtZX0sIGV4cGVjdGVkIHRzV29ya2VyYCk7Cn0KCm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKTogdm9pZCB7CiAgcG9zdE1lc3NhZ2UoZS5kYXRhKTsKICBjbG9zZSgpOwp9Owo=",
- { type: "module", name: "tsWorker" },
- );
-
- const { promise, resolve } = Promise.withResolvers<string>();
- tsWorker.onmessage = (e) => {
- resolve(e.data);
- };
-
- tsWorker.postMessage("Hello World");
- assertEquals(await promise, "Hello World");
- tsWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker nested",
- fn: async function () {
- const nestedWorker = new Worker(
- import.meta.resolve("./nested_worker.js"),
- { type: "module", name: "nested" },
- );
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- nestedWorker.onmessage = (e) => {
- resolve(e.data);
- };
-
- nestedWorker.postMessage("Hello World");
- assertEquals(await promise, { type: "msg", text: "Hello World" });
- nestedWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker throws when executing",
- fn: async function () {
- const throwingWorker = new Worker(
- import.meta.resolve("./throwing_worker.js"),
- { type: "module" },
- );
-
- const { promise, resolve } = Promise.withResolvers<string>();
- // deno-lint-ignore no-explicit-any
- throwingWorker.onerror = (e: any) => {
- e.preventDefault();
- resolve(e.message);
- };
-
- assertMatch(
- await promise as string,
- /Uncaught \(in promise\) Error: Thrown error/,
- );
- throwingWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker globals",
- fn: async function () {
- const workerOptions: WorkerOptions = { type: "module" };
- const w = new Worker(
- import.meta.resolve("./worker_globals.ts"),
- workerOptions,
- );
-
- const { promise, resolve } = Promise.withResolvers<string>();
- w.onmessage = (e) => {
- resolve(e.data);
- };
-
- w.postMessage("Hello, world!");
- assertEquals(await promise, "true, true, true, true");
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker navigator",
- fn: async function () {
- const workerOptions: WorkerOptions = { type: "module" };
- const w = new Worker(
- import.meta.resolve("./worker_navigator.ts"),
- workerOptions,
- );
-
- const { promise, resolve } = Promise.withResolvers<string>();
- w.onmessage = (e) => {
- resolve(e.data);
- };
-
- w.postMessage("Hello, world!");
- assertEquals(await promise, "string, object, string, number");
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker fetch API",
- fn: async function () {
- const fetchingWorker = new Worker(
- import.meta.resolve("./fetching_worker.js"),
- { type: "module" },
- );
-
- const { promise, resolve, reject } = Promise.withResolvers<string>();
- // deno-lint-ignore no-explicit-any
- fetchingWorker.onerror = (e: any) => {
- e.preventDefault();
- reject(e.message);
- };
- // Defer promise.resolve() to allow worker to shut down
- fetchingWorker.onmessage = (e) => {
- resolve(e.data);
- };
-
- assertEquals(await promise, "Done!");
- fetchingWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker terminate busy loop",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<number>();
-
- const busyWorker = new Worker(
- import.meta.resolve("./busy_worker.js"),
- { type: "module" },
- );
-
- let testResult = 0;
-
- busyWorker.onmessage = (e) => {
- testResult = e.data;
- if (testResult >= 10000) {
- busyWorker.terminate();
- busyWorker.onmessage = (_e) => {
- throw new Error("unreachable");
- };
- setTimeout(() => {
- resolve(testResult);
- }, 100);
- }
- };
-
- busyWorker.postMessage("ping");
- assertEquals(await promise, 10000);
- },
-});
-
-Deno.test({
- name: "worker race condition",
- fn: async function () {
- // See issue for details
- // https://github.com/denoland/deno/issues/4080
- const { promise, resolve } = Promise.withResolvers<void>();
-
- const racyWorker = new Worker(
- import.meta.resolve("./racy_worker.js"),
- { type: "module" },
- );
-
- racyWorker.onmessage = (_e) => {
- setTimeout(() => {
- resolve();
- }, 100);
- };
-
- racyWorker.postMessage("START");
- await promise;
- },
-});
-
-Deno.test({
- name: "worker is event listener",
- fn: async function () {
- let messageHandlersCalled = 0;
- let errorHandlersCalled = 0;
-
- const deferred1 = Promise.withResolvers<void>();
- const deferred2 = Promise.withResolvers<void>();
-
- const worker = new Worker(
- import.meta.resolve("./event_worker.js"),
- { type: "module" },
- );
-
- worker.onmessage = (_e: Event) => {
- messageHandlersCalled++;
- };
- worker.addEventListener("message", (_e: Event) => {
- messageHandlersCalled++;
- });
- worker.addEventListener("message", (_e: Event) => {
- messageHandlersCalled++;
- deferred1.resolve();
- });
-
- worker.onerror = (e) => {
- errorHandlersCalled++;
- e.preventDefault();
- };
- worker.addEventListener("error", (_e: Event) => {
- errorHandlersCalled++;
- });
- worker.addEventListener("error", (_e: Event) => {
- errorHandlersCalled++;
- deferred2.resolve();
- });
-
- worker.postMessage("ping");
- await deferred1.promise;
- assertEquals(messageHandlersCalled, 3);
-
- worker.postMessage("boom");
- await deferred2.promise;
- assertEquals(errorHandlersCalled, 3);
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker scope is event listener",
- fn: async function () {
- const worker = new Worker(
- import.meta.resolve("./event_worker_scope.js"),
- { type: "module" },
- );
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = (e: MessageEvent) => {
- resolve(e.data);
- };
- worker.onerror = (_e) => {
- throw new Error("unreachable");
- };
-
- worker.postMessage("boom");
- worker.postMessage("ping");
- assertEquals(await promise, {
- messageHandlersCalled: 4,
- errorHandlersCalled: 4,
- });
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker with Deno namespace",
- fn: async function () {
- const denoWorker = new Worker(
- import.meta.resolve("./deno_worker.ts"),
- { type: "module", deno: { permissions: "inherit" } },
- );
-
- const { promise, resolve } = Promise.withResolvers<string>();
- denoWorker.onmessage = (e) => {
- denoWorker.terminate();
- resolve(e.data);
- };
-
- denoWorker.postMessage("Hello World");
- assertEquals(await promise, "Hello World");
- },
-});
-
-Deno.test({
- name: "worker with crypto in scope",
- fn: async function () {
- const w = new Worker(
- import.meta.resolve("./worker_crypto.js"),
- { type: "module" },
- );
-
- const { promise, resolve } = Promise.withResolvers<boolean>();
- w.onmessage = (e) => {
- resolve(e.data);
- };
-
- w.postMessage(null);
- assertEquals(await promise, true);
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker event handler order",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<void>();
- const w = new Worker(
- import.meta.resolve("./test_worker.ts"),
- { type: "module", name: "tsWorker" },
- );
- const arr: number[] = [];
- w.addEventListener("message", () => arr.push(1));
- w.onmessage = (_e) => {
- arr.push(2);
- };
- w.addEventListener("message", () => arr.push(3));
- w.addEventListener("message", () => {
- resolve();
- });
- w.postMessage("Hello World");
- await promise;
- assertEquals(arr, [1, 2, 3]);
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker immediate close",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<void>();
- const w = new Worker(
- import.meta.resolve("./immediately_close_worker.js"),
- { type: "module" },
- );
- setTimeout(() => {
- resolve();
- }, 1000);
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker post undefined",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<void>();
- const worker = new Worker(
- import.meta.resolve("./post_undefined.ts"),
- { type: "module" },
- );
-
- const handleWorkerMessage = (e: MessageEvent) => {
- console.log("main <- worker:", e.data);
- worker.terminate();
- resolve();
- };
-
- worker.addEventListener("messageerror", () => console.log("message error"));
- worker.addEventListener("error", () => console.log("error"));
- worker.addEventListener("message", handleWorkerMessage);
-
- console.log("\npost from parent");
- worker.postMessage(undefined);
- await promise;
- },
-});
-
-Deno.test("Worker inherits permissions", async function () {
- const worker = new Worker(
- import.meta.resolve("./read_check_worker.js"),
- { type: "module", deno: { permissions: "inherit" } },
- );
-
- const { promise, resolve } = Promise.withResolvers<boolean>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage(null);
- assertEquals(await promise, true);
- worker.terminate();
-});
-
-Deno.test("Worker limit children permissions", async function () {
- const worker = new Worker(
- import.meta.resolve("./read_check_worker.js"),
- { type: "module", deno: { permissions: { read: false } } },
- );
-
- const { promise, resolve } = Promise.withResolvers<boolean>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage(null);
- assertEquals(await promise, false);
- worker.terminate();
-});
-
-Deno.test("Worker limit children permissions granularly", async function () {
- const worker = new Worker(
- import.meta.resolve("./read_check_granular_worker.js"),
- {
- type: "module",
- deno: {
- permissions: {
- env: ["foo"],
- hrtime: true,
- net: ["foo", "bar:8000"],
- ffi: [new URL("foo", import.meta.url), "bar"],
- read: [new URL("foo", import.meta.url), "bar"],
- run: [new URL("foo", import.meta.url), "bar", "./baz"],
- write: [new URL("foo", import.meta.url), "bar"],
- },
- },
- },
- );
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = ({ data }) => resolve(data);
- assertEquals(await promise, {
- envGlobal: "prompt",
- envFoo: "granted",
- envAbsent: "prompt",
- hrtime: "granted",
- netGlobal: "prompt",
- netFoo: "granted",
- netFoo8000: "granted",
- netBar: "prompt",
- netBar8000: "granted",
- ffiGlobal: "prompt",
- ffiFoo: "granted",
- ffiBar: "granted",
- ffiAbsent: "prompt",
- readGlobal: "prompt",
- readFoo: "granted",
- readBar: "granted",
- readAbsent: "prompt",
- runGlobal: "prompt",
- runFoo: "granted",
- runBar: "granted",
- runBaz: "granted",
- runAbsent: "prompt",
- writeGlobal: "prompt",
- writeFoo: "granted",
- writeBar: "granted",
- writeAbsent: "prompt",
- });
- worker.terminate();
-});
-
-Deno.test("Nested worker limit children permissions", async function () {
- /** This worker has permissions but doesn't grant them to its children */
- const worker = new Worker(
- import.meta.resolve("./parent_read_check_worker.js"),
- { type: "module", deno: { permissions: "inherit" } },
- );
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = ({ data }) => resolve(data);
- assertEquals(await promise, {
- envGlobal: "prompt",
- envFoo: "prompt",
- envAbsent: "prompt",
- hrtime: "prompt",
- netGlobal: "prompt",
- netFoo: "prompt",
- netFoo8000: "prompt",
- netBar: "prompt",
- netBar8000: "prompt",
- ffiGlobal: "prompt",
- ffiFoo: "prompt",
- ffiBar: "prompt",
- ffiAbsent: "prompt",
- readGlobal: "prompt",
- readFoo: "prompt",
- readBar: "prompt",
- readAbsent: "prompt",
- runGlobal: "prompt",
- runFoo: "prompt",
- runBar: "prompt",
- runBaz: "prompt",
- runAbsent: "prompt",
- writeGlobal: "prompt",
- writeFoo: "prompt",
- writeBar: "prompt",
- writeAbsent: "prompt",
- });
- worker.terminate();
-});
-
-// This test relies on env permissions not being granted on main thread
-Deno.test({
- name:
- "Worker initialization throws on worker permissions greater than parent thread permissions",
- permissions: { env: false },
- fn: function () {
- assertThrows(
- () => {
- const worker = new Worker(
- import.meta.resolve("./deno_worker.ts"),
- { type: "module", deno: { permissions: { env: true } } },
- );
- worker.terminate();
- },
- Deno.errors.PermissionDenied,
- "Can't escalate parent thread permissions",
- );
- },
-});
-
-Deno.test("Worker with disabled permissions", async function () {
- const worker = new Worker(
- import.meta.resolve("./no_permissions_worker.js"),
- { type: "module", deno: { permissions: "none" } },
- );
-
- const { promise, resolve } = Promise.withResolvers<boolean>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage(null);
- assertEquals(await promise, true);
- worker.terminate();
-});
-
-Deno.test("Worker permissions are not inherited with empty permission object", async function () {
- const worker = new Worker(
- import.meta.resolve("./permission_echo.js"),
- { type: "module", deno: { permissions: {} } },
- );
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage(null);
- assertEquals(await promise, {
- env: "prompt",
- hrtime: "prompt",
- net: "prompt",
- ffi: "prompt",
- read: "prompt",
- run: "prompt",
- write: "prompt",
- });
- worker.terminate();
-});
-
-Deno.test("Worker permissions are not inherited with single specified permission", async function () {
- const worker = new Worker(
- import.meta.resolve("./permission_echo.js"),
- { type: "module", deno: { permissions: { net: true } } },
- );
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage(null);
- assertEquals(await promise, {
- env: "prompt",
- hrtime: "prompt",
- net: "granted",
- ffi: "prompt",
- read: "prompt",
- run: "prompt",
- write: "prompt",
- });
- worker.terminate();
-});
-
-Deno.test("Worker with invalid permission arg", function () {
- assertThrows(
- () =>
- new Worker(`data:,close();`, {
- type: "module",
- // @ts-expect-error invalid env value
- deno: { permissions: { env: "foo" } },
- }),
- TypeError,
- '(deno.permissions.env) invalid value: string "foo", expected "inherit" or boolean or string[]',
- );
-});
-
-Deno.test({
- name: "worker location",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<string>();
- const workerModuleHref = import.meta.resolve("./worker_location.ts");
- const w = new Worker(workerModuleHref, { type: "module" });
- w.onmessage = (e) => {
- resolve(e.data);
- };
- w.postMessage("Hello, world!");
- assertEquals(await promise, `${workerModuleHref}, true`);
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker with relative specifier",
- fn: async function () {
- assertEquals(location.href, "http://127.0.0.1:4545/");
- const w = new Worker(
- "./workers/test_worker.ts",
- { type: "module", name: "tsWorker" },
- );
- const { promise, resolve } = Promise.withResolvers<string>();
- w.onmessage = (e) => {
- resolve(e.data);
- };
- w.postMessage("Hello, world!");
- assertEquals(await promise, "Hello, world!");
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker with top-level-await",
- fn: async function () {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const worker = new Worker(
- import.meta.resolve("./worker_with_top_level_await.ts"),
- { type: "module" },
- );
- worker.onmessage = (e) => {
- if (e.data == "ready") {
- worker.postMessage("trigger worker handler");
- } else if (e.data == "triggered worker handler") {
- resolve();
- } else {
- reject(new Error("Handler didn't run during top-level delay."));
- }
- };
- await promise;
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "Worker with native HTTP",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<void>();
- const worker = new Worker(
- import.meta.resolve("./http_worker.js"),
- { type: "module", deno: { permissions: "inherit" } },
- );
- worker.onmessage = () => {
- resolve();
- };
- await promise;
-
- assert(worker);
- const response = await fetch("http://localhost:4506");
- assert(await response.arrayBuffer());
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "structured cloning postMessage",
- fn: async function () {
- const worker = new Worker(
- import.meta.resolve("./worker_structured_cloning.ts"),
- { type: "module" },
- );
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- worker.onmessage = (e) => {
- resolve(e.data);
- };
-
- worker.postMessage("START");
- const data = await promise;
- // self field should reference itself (circular ref)
- assert(data === data.self);
- // fields a and b refer to the same array
- assertEquals(data.a, ["a", true, 432]);
- assertEquals(data.b, ["a", true, 432]);
- data.b[0] = "b";
- data.a[2] += 5;
- assertEquals(data.a, ["b", true, 437]);
- assertEquals(data.b, ["b", true, 437]);
- // c is a set
- const len = data.c.size;
- data.c.add(1); // This value is already in the set.
- data.c.add(2);
- assertEquals(len + 1, data.c.size);
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker with relative specifier",
- fn: async function () {
- assertEquals(location.href, "http://127.0.0.1:4545/");
- const w = new Worker(
- "./workers/test_worker.ts",
- { type: "module", name: "tsWorker" },
- );
- const { promise, resolve } = Promise.withResolvers<string>();
- w.onmessage = (e) => {
- resolve(e.data);
- };
- w.postMessage("Hello, world!");
- assertEquals(await promise, "Hello, world!");
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker SharedArrayBuffer",
- fn: async function () {
- const { promise, resolve } = Promise.withResolvers<void>();
- const workerOptions: WorkerOptions = { type: "module" };
- const w = new Worker(
- import.meta.resolve("./shared_array_buffer.ts"),
- workerOptions,
- );
- const sab1 = new SharedArrayBuffer(1);
- const sab2 = new SharedArrayBuffer(1);
- const bytes1 = new Uint8Array(sab1);
- const bytes2 = new Uint8Array(sab2);
- assertEquals(bytes1[0], 0);
- assertEquals(bytes2[0], 0);
- w.onmessage = () => {
- w.postMessage([sab1, sab2]);
- w.onmessage = () => {
- resolve();
- };
- };
- await promise;
- assertEquals(bytes1[0], 1);
- assertEquals(bytes2[0], 2);
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Send MessagePorts from / to workers",
- fn: async function () {
- const worker = new Worker(
- import.meta.resolve("./message_port.ts"),
- { type: "module" },
- );
- const channel = new MessageChannel();
-
- // deno-lint-ignore no-explicit-any
- const deferred1 = Promise.withResolvers<any>();
- const deferred2 = Promise.withResolvers<boolean>();
- const deferred3 = Promise.withResolvers<boolean>();
- const result = Promise.withResolvers<void>();
- worker.onmessage = (e) => {
- deferred1.resolve([e.data, e.ports.length]);
- const port1 = e.ports[0];
- port1.onmessage = (e) => {
- deferred2.resolve(e.data);
- port1.close();
- worker.postMessage("3", [channel.port1]);
- };
- port1.postMessage("2");
- };
- channel.port2.onmessage = (e) => {
- deferred3.resolve(e.data);
- channel.port2.close();
- result.resolve();
- };
-
- assertEquals(await deferred1.promise, ["1", 1]);
- assertEquals(await deferred2.promise, true);
- assertEquals(await deferred3.promise, true);
- await result.promise;
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker Deno.memoryUsage",
- fn: async function () {
- const w = new Worker(
- /**
- * Source code
- * self.onmessage = function() {self.postMessage(Deno.memoryUsage())}
- */
- "data:application/typescript;base64,c2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtzZWxmLnBvc3RNZXNzYWdlKERlbm8ubWVtb3J5VXNhZ2UoKSl9",
- { type: "module", name: "tsWorker" },
- );
-
- w.postMessage(null);
-
- // deno-lint-ignore no-explicit-any
- const { promise, resolve } = Promise.withResolvers<any>();
- w.onmessage = function (evt) {
- resolve(evt.data);
- };
-
- assertEquals(
- Object.keys(
- await promise as unknown as Record<string, number>,
- ),
- ["rss", "heapTotal", "heapUsed", "external"],
- );
- w.terminate();
- },
-});
diff --git a/cli/tests/testdata/workers/test.ts.out b/cli/tests/testdata/workers/test.ts.out
deleted file mode 100644
index 62c132b60..000000000
--- a/cli/tests/testdata/workers/test.ts.out
+++ /dev/null
@@ -1,3 +0,0 @@
-[WILDCARD]
-ok | [WILDCARD] passed | 0 failed ([WILDCARD])
-