1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-01 09:24:20 -04:00
denoland-deno/cli/js/workers_test.ts
Bartek Iwańczuk 79b3bc05d6
workers: basic event loop (#3828)
* establish basic event loop for workers
* make "self.close()" inside worker
* remove "runWorkerMessageLoop() - instead manually call global function 
  in Rust when message arrives. This is done in preparation for structured clone
* refactor "WorkerChannel" and use distinct structs for internal 
  and external channels;  "WorkerChannelsInternal" and "WorkerHandle"
* move "State.worker_channels_internal" to "Worker.internal_channels"
* add "WorkerEvent" enum for child->host communication; 
  currently "Message(Buf)" and  "Error(ErrBox)" variants are supported
* add tests for nested workers
* add tests for worker throwing error on startup
2020-02-11 10:04:59 +01:00

84 lines
2.3 KiB
TypeScript

// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEquals } from "./test_util.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>;
}
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;
});
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;
});
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();
assertEquals(e.message, "Uncaught Error: Thrown error");
promise.resolve();
};
await promise;
});