summaryrefslogtreecommitdiff
path: root/cli/tests/workers_test.ts
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-03-03 18:22:53 +0100
committerGitHub <noreply@github.com>2020-03-03 18:22:53 +0100
commitee452ad883c1c711839655a307b39e8eea5bf410 (patch)
tree2812a5201beb2b52c92d6e3c958f2288b0253b68 /cli/tests/workers_test.ts
parent4dc004f0a24fdc81026ec03326b9943a95f1a31d (diff)
add assertOps sanitizer in cli/js/ unit tests (#4209)
* add "assertOps" test assertion which makes sure test case is not "leaking" ops - ie. after test finishes there are no pending async ops * apply "assertOps" to all tests in "cli/js/" * fix numerous tests leaking ops * document problem with edge case in "clearInterval" and "clearTimeout" implementation where they may leak async ops * move "cli/js/worker_test.ts" to "cli/tests/worker_test.ts" and run as integration test; workers leak ops because of missing "terminate" implementation
Diffstat (limited to 'cli/tests/workers_test.ts')
-rw-r--r--cli/tests/workers_test.ts115
1 files changed, 115 insertions, 0 deletions
diff --git a/cli/tests/workers_test.ts b/cli/tests/workers_test.ts
new file mode 100644
index 000000000..44e7a1776
--- /dev/null
+++ b/cli/tests/workers_test.ts
@@ -0,0 +1,115 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+// Requires to be run with `--allow-net` flag
+
+// FIXME(bartlomieju): this file is an integration test only because
+// workers are leaking ops at the moment - `worker.terminate()` is not
+// yet implemented. Once it gets implemented this file should be
+// again moved to `cli/js/` as an unit test file.
+
+import { assert, assertEquals } from "../../std/testing/asserts.ts";
+
+export interface ResolvableMethods<T> {
+ resolve: (value?: T | PromiseLike<T>) => void;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ reject: (reason?: any) => void;
+}
+
+export type Resolvable<T> = Promise<T> & ResolvableMethods<T>;
+
+export function createResolvable<T>(): Resolvable<T> {
+ let methods: ResolvableMethods<T>;
+ const promise = new Promise<T>((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<T>;
+}
+
+Deno.test(async function workersBasic(): Promise<void> {
+ const promise = createResolvable();
+ const jsWorker = new Worker("../tests/subdir/test_worker.js", {
+ type: "module",
+ name: "jsWorker"
+ });
+ const tsWorker = new Worker("../tests/subdir/test_worker.ts", {
+ type: "module",
+ name: "tsWorker"
+ });
+
+ tsWorker.onmessage = (e): void => {
+ assertEquals(e.data, "Hello World");
+ promise.resolve();
+ };
+
+ jsWorker.onmessage = (e): void => {
+ assertEquals(e.data, "Hello World");
+ tsWorker.postMessage("Hello World");
+ };
+
+ jsWorker.onerror = (e: Event): void => {
+ e.preventDefault();
+ jsWorker.postMessage("Hello World");
+ };
+
+ jsWorker.postMessage("Hello World");
+ await promise;
+});
+
+Deno.test(async function nestedWorker(): Promise<void> {
+ const promise = createResolvable();
+
+ const nestedWorker = new Worker("../tests/subdir/nested_worker.js", {
+ type: "module",
+ name: "nested"
+ });
+
+ nestedWorker.onmessage = (e): void => {
+ assert(e.data.type !== "error");
+ promise.resolve();
+ };
+
+ nestedWorker.postMessage("Hello World");
+ await promise;
+});
+
+Deno.test(async function workerThrowsWhenExecuting(): Promise<void> {
+ const promise = createResolvable();
+ const throwingWorker = new Worker("../tests/subdir/throwing_worker.js", {
+ type: "module"
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ throwingWorker.onerror = (e: any): void => {
+ e.preventDefault();
+ assert(/Uncaught Error: Thrown error/.test(e.message));
+ promise.resolve();
+ };
+
+ await promise;
+});
+
+Deno.test(async function workerCanUseFetch(): Promise<void> {
+ const promise = createResolvable();
+
+ const fetchingWorker = new Worker("../tests/subdir/fetching_worker.js", {
+ type: "module"
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ fetchingWorker.onerror = (e: any): void => {
+ e.preventDefault();
+ promise.reject(e.message);
+ };
+
+ // Defer promise.resolve() to allow worker to shut down
+ fetchingWorker.onmessage = (e): void => {
+ assert(e.data === "Done!");
+ promise.resolve();
+ };
+
+ await promise;
+});
+
+await Deno.runTests();