Files
radicle-explorer/tests/unit/mutexExecutor.test.ts
T
Sebastian Martinez 0c7ea70c1b Update eslint config to flat config
Since the legacy config is being deprecated at the end of 2024, we
should start moving to the eslint flat config.

I avoided the tseslint config helper function so we avoid wrapping
magic.

This seems to have triggered more checking since any checks in svelte
files have appeared and the $$Generic type that is being deprecated had
to be rewritten.

Also fixes some any types that weren't caught previously
2024-05-27 17:35:16 +02:00

122 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as sinon from "sinon";
import { describe, expect, test } from "vitest";
import * as mutexExecutor from "@app/lib/mutexExecutor";
import { sleep } from "@app/lib/sleep";
describe("executor", () => {
test("cancels running task", async () => {
const e = mutexExecutor.create();
const first = e.run(async () => {
await sleep(10);
return "first";
});
const second = e.run(async () => {
return "second";
});
expect(await first).toBe(undefined);
expect(await second).toBe("second");
const third = e.run(async () => {
await sleep(10);
return "third";
});
const fourth = e.run(async () => {
return "fourth";
});
expect(await third).toBe(undefined);
expect(await fourth).toBe("fourth");
});
test("cancels multiple tasks", async () => {
const e = mutexExecutor.create();
const canceled1 = e.run(async () => {
await sleep(10);
return true;
});
const canceled2 = e.run(async () => {
await sleep(10);
return true;
});
const canceled3 = e.run(async () => {
await sleep(10);
return true;
});
const last = e.run(async () => {
return true;
});
expect(await canceled1).toBe(undefined);
expect(await canceled2).toBe(undefined);
expect(await canceled3).toBe(undefined);
expect(await last).toBe(true);
});
test("triggers abort signal event", async () => {
const e = mutexExecutor.create();
const abortListener = sinon.spy();
void e.run(async abort => {
abort.addEventListener("abort", abortListener);
await sleep(10);
return "first";
});
expect(abortListener.called).toBe(false);
// eslint-disable-next-line @typescript-eslint/no-empty-function
void e.run(async () => {});
expect(abortListener.called).toBe(true);
});
test("don’t throw error on aborted task", async () => {
const e = mutexExecutor.create();
const first = e.run(async () => {
await sleep(10);
throw new Error();
});
const second = e.run(async () => {
return "second";
});
expect(await first).toBe(undefined);
expect(await second).toBe("second");
});
});
describe("worker", () => {
test("sequential work", async () => {
const w = mutexExecutor.createWorker(async (value: number) => {
await sleep(10);
return value;
});
const outputs: number[] = [];
w.output.onValue((value: never) => outputs.push(value));
await w.submit(1);
await w.submit(2);
await w.submit(3);
expect(outputs).toEqual([1, 2, 3]);
});
test("overlapping work cancels", async () => {
const w = mutexExecutor.createWorker(async (value: number) => {
await sleep(10);
return value;
});
const nextOutput = w.output.firstToPromise();
void w.submit(1);
void w.submit(2);
void w.submit(3);
expect(await nextOutput).toEqual(3);
});
});