1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/common/runnable/run-many-for.test.ts
Sebastian Malton bbf6ec38bf Fix runManyFor tests
Signed-off-by: Sebastian Malton <sebastian@malton.name>
2022-12-06 09:18:59 -05:00

283 lines
8.0 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import { createContainer, getInjectable, getInjectionToken } from "@ogre-tools/injectable";
import type { Runnable } from "./run-many-for";
import { runManyFor } from "./run-many-for";
import { getPromiseStatus } from "../test-utils/get-promise-status";
describe("runManyFor", () => {
describe("given no hierarchy, when running many", () => {
let runMock: AsyncFnMock<(...args: unknown[]) => Promise<void>>;
let actualPromise: Promise<void>;
beforeEach(() => {
const rootDi = createContainer("irrelevant");
runMock = asyncFn();
const someInjectionTokenForRunnables = getInjectionToken<Runnable>({
id: "some-injection-token",
});
const someInjectable = getInjectable({
id: "some-injectable",
instantiate: () => ({
id: "some-injectable",
run: () => runMock("some-call"),
}),
injectionToken: someInjectionTokenForRunnables,
});
const someOtherInjectable = getInjectable({
id: "some-other-injectable",
instantiate: () => ({
id: "some-other-injectable",
run: () => runMock("some-other-call"),
}),
injectionToken: someInjectionTokenForRunnables,
});
rootDi.register(someInjectable, someOtherInjectable);
const runMany = runManyFor(rootDi)(someInjectionTokenForRunnables);
actualPromise = runMany() as Promise<void>;
});
it("runs all runnables at the same time", () => {
expect(runMock.mock.calls).toEqual([
["some-call"],
["some-other-call"],
]);
});
it("does not resolve yet", async () => {
const promiseStatus = await getPromiseStatus(actualPromise);
expect(promiseStatus.fulfilled).toBe(false);
});
it("when all runnables resolve, resolves", async () => {
await Promise.all([runMock.resolve(), runMock.resolve()]);
expect(await actualPromise).toBe(undefined);
});
});
describe("given hierarchy that is three levels deep, when running many", () => {
let runMock: AsyncFnMock<(...args: unknown[]) => Promise<void>>;
let actualPromise: Promise<void>;
beforeEach(() => {
const di = createContainer("irrelevant");
runMock = asyncFn();
const someInjectionTokenForRunnables = getInjectionToken<Runnable>({
id: "some-injection-token",
});
const someInjectable1 = getInjectable({
id: "some-injectable-1",
instantiate: (di) => ({
id: "some-injectable-1",
run: () => runMock("third-level-run"),
runAfter: di.inject(someInjectable2),
}),
injectionToken: someInjectionTokenForRunnables,
});
const someInjectable2 = getInjectable({
id: "some-injectable-2",
instantiate: (di) => ({
id: "some-injectable-2",
run: () => runMock("second-level-run"),
runAfter: di.inject(someInjectable3),
}),
injectionToken: someInjectionTokenForRunnables,
});
const someInjectable3 = getInjectable({
id: "some-injectable-3",
instantiate: () => ({
id: "some-injectable-3",
run: () => runMock("first-level-run"),
}),
injectionToken: someInjectionTokenForRunnables,
});
di.register(someInjectable1, someInjectable2, someInjectable3);
const runMany = runManyFor(di)(someInjectionTokenForRunnables);
actualPromise = runMany() as Promise<void>;
});
it("runs first level runnables", () => {
expect(runMock.mock.calls).toEqual([["first-level-run"]]);
});
it("does not resolve yet", async () => {
const promiseStatus = await getPromiseStatus(actualPromise);
expect(promiseStatus.fulfilled).toBe(false);
});
describe("when first level runnables resolve", () => {
beforeEach(async () => {
runMock.mockClear();
await runMock.resolveSpecific(["first-level-run"]);
});
it("runs second level runnables", async () => {
expect(runMock.mock.calls).toEqual([["second-level-run"]]);
});
it("does not resolve yet", async () => {
const promiseStatus = await getPromiseStatus(actualPromise);
expect(promiseStatus.fulfilled).toBe(false);
});
describe("when second level runnables resolve", () => {
beforeEach(async () => {
runMock.mockClear();
await runMock.resolveSpecific(["second-level-run"]);
});
it("runs final third level runnables", async () => {
expect(runMock.mock.calls).toEqual([["third-level-run"]]);
});
it("does not resolve yet", async () => {
const promiseStatus = await getPromiseStatus(actualPromise);
expect(promiseStatus.fulfilled).toBe(false);
});
describe("when final third level runnables resolve", () => {
beforeEach(async () => {
await runMock.resolveSpecific(["third-level-run"]);
});
it("resolves", async () => {
const promiseStatus = await getPromiseStatus(actualPromise);
expect(promiseStatus.fulfilled).toBe(true);
});
});
});
});
});
it("given invalid hierarchy, when running runnables, throws", () => {
const rootDi = createContainer("irrelevant");
const runMock = asyncFn<(...args: unknown[]) => void>();
const someInjectionToken = getInjectionToken<Runnable>({
id: "some-injection-token",
});
const someOtherInjectionToken = getInjectionToken<Runnable>({
id: "some-other-injection-token",
});
const someInjectable = getInjectable({
id: "some-runnable-1",
instantiate: (di) => ({
id: "some-runnable-1",
run: () => runMock("some-runnable-1"),
runAfter: di.inject(someOtherInjectable),
}),
injectionToken: someInjectionToken,
});
const someOtherInjectable = getInjectable({
id: "some-runnable-2",
instantiate: () => ({
id: "some-runnable-2",
run: () => runMock("some-runnable-2"),
}),
injectionToken: someOtherInjectionToken,
});
rootDi.register(someInjectable, someOtherInjectable);
const runMany = runManyFor(rootDi)(
someInjectionToken,
);
return expect(() => runMany()).rejects.toThrow(
/Unreachable runnable="some-runnable-1". The specified runAfters; all of "some-runnable-2"; are not part of this injection token/,
);
});
describe("when running many with parameter", () => {
let runMock: AsyncFnMock<(...args: unknown[]) => Promise<void>>;
beforeEach(() => {
const rootDi = createContainer("irrelevant");
runMock = asyncFn();
const someInjectionTokenForRunnablesWithParameter = getInjectionToken<
Runnable<string>
>({
id: "some-injection-token",
});
const someInjectable = getInjectable({
id: "some-runnable-1",
instantiate: () => ({
id: "some-runnable-1",
run: (parameter) => runMock("run-of-some-runnable-1", parameter),
}),
injectionToken: someInjectionTokenForRunnablesWithParameter,
});
const someOtherInjectable = getInjectable({
id: "some-runnable-2",
instantiate: () => ({
id: "some-runnable-2",
run: (parameter) => runMock("run-of-some-runnable-2", parameter),
}),
injectionToken: someInjectionTokenForRunnablesWithParameter,
});
rootDi.register(someInjectable, someOtherInjectable);
const runMany = runManyFor(rootDi)(
someInjectionTokenForRunnablesWithParameter,
);
runMany("some-parameter");
});
it("runs all runnables using the parameter", () => {
expect(runMock.mock.calls).toEqual([
["run-of-some-runnable-1", "some-parameter"],
["run-of-some-runnable-2", "some-parameter"],
]);
});
});
});