mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add unit tests and fix handling empty runAfter array
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
7b8e97ba08
commit
fcddf442a0
@ -8,6 +8,8 @@ import { createContainer, getInjectable, getInjectionToken } from "@ogre-tools/i
|
|||||||
import type { Runnable } from "./run-many-for";
|
import type { Runnable } from "./run-many-for";
|
||||||
import { runManyFor } from "./run-many-for";
|
import { runManyFor } from "./run-many-for";
|
||||||
import { getPromiseStatus } from "../test-utils/get-promise-status";
|
import { getPromiseStatus } from "../test-utils/get-promise-status";
|
||||||
|
import { runInAction } from "mobx";
|
||||||
|
import { flushPromises } from "../test-utils/flush-promises";
|
||||||
|
|
||||||
describe("runManyFor", () => {
|
describe("runManyFor", () => {
|
||||||
describe("given no hierarchy, when running many", () => {
|
describe("given no hierarchy, when running many", () => {
|
||||||
@ -340,4 +342,315 @@ describe("runManyFor", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("given multiple runAfters", () => {
|
||||||
|
let runMock: AsyncFnMock<(...args: unknown[]) => void>;
|
||||||
|
let finishingPromise: Promise<void>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const rootDi = createContainer("irrelevant");
|
||||||
|
|
||||||
|
runMock = asyncFn<(...args: unknown[]) => void>();
|
||||||
|
|
||||||
|
const someInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "some-injection-token",
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableOneInjectable = getInjectable({
|
||||||
|
id: "runnable-1",
|
||||||
|
instantiate: () => ({
|
||||||
|
id: "runnable-1",
|
||||||
|
run: () => runMock("runnable-1"),
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableTwoInjectable = getInjectable({
|
||||||
|
id: "runnable-2",
|
||||||
|
instantiate: () => ({
|
||||||
|
id: "runnable-2",
|
||||||
|
run: () => runMock("runnable-2"),
|
||||||
|
runAfter: [], // shouldn't block being called
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableThreeInjectable = getInjectable({
|
||||||
|
id: "runnable-3",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
id: "runnable-3",
|
||||||
|
run: () => runMock("runnable-3"),
|
||||||
|
runAfter: di.inject(runnableOneInjectable),
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableFourInjectable = getInjectable({
|
||||||
|
id: "runnable-4",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
id: "runnable-4",
|
||||||
|
run: () => runMock("runnable-4"),
|
||||||
|
runAfter: [di.inject(runnableThreeInjectable)], // should be the same as an single item
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableFiveInjectable = getInjectable({
|
||||||
|
id: "runnable-5",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
id: "runnable-5",
|
||||||
|
run: () => runMock("runnable-5"),
|
||||||
|
runAfter: di.inject(runnableThreeInjectable),
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableSixInjectable = getInjectable({
|
||||||
|
id: "runnable-6",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
id: "runnable-6",
|
||||||
|
run: () => runMock("runnable-6"),
|
||||||
|
runAfter: [
|
||||||
|
di.inject(runnableFourInjectable),
|
||||||
|
di.inject(runnableFiveInjectable),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const runnableSevenInjectable = getInjectable({
|
||||||
|
id: "runnable-7",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
id: "runnable-7",
|
||||||
|
run: () => runMock("runnable-7"),
|
||||||
|
runAfter: [
|
||||||
|
di.inject(runnableFiveInjectable),
|
||||||
|
di.inject(runnableSixInjectable),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
injectionToken: someInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
rootDi.register(
|
||||||
|
runnableOneInjectable,
|
||||||
|
runnableTwoInjectable,
|
||||||
|
runnableThreeInjectable,
|
||||||
|
runnableFourInjectable,
|
||||||
|
runnableFiveInjectable,
|
||||||
|
runnableSixInjectable,
|
||||||
|
runnableSevenInjectable,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const runMany = runManyFor(rootDi);
|
||||||
|
const runSome = runMany(someInjectionToken);
|
||||||
|
|
||||||
|
finishingPromise = runSome();
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-1'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-2'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-2");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-1' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-1"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-3'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-3");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-3' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-3"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-4'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-4");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-5'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-5");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-4' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-4"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-5' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-5"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-6'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-6");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(6);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-6' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-6"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-7'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-7");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-7' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-7"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should resolve the runMany promise call", async () => {
|
||||||
|
await finishingPromise;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-5' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-5"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-4' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-4"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-6'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-6");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(6);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-6' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-6"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should run 'runnable-7'", () => {
|
||||||
|
expect(runMock).toBeCalledWith("runnable-7");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-7' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-7"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should resolve the runMany promise call", async () => {
|
||||||
|
await finishingPromise;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when 'runnable-2' resolves", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await runMock.resolveSpecific(["runnable-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't call any more runnables", () => {
|
||||||
|
expect(runMock).toBeCalledTimes(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { getOrInsertSetFor, isDefined } from "../utils";
|
|||||||
import { observable, when } from "mobx";
|
import { observable, when } from "mobx";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
import type { Asyncify } from "type-fest";
|
||||||
|
|
||||||
export interface Runnable<TParameter = void> {
|
export interface Runnable<TParameter = void> {
|
||||||
id: string;
|
id: string;
|
||||||
@ -17,7 +18,7 @@ export interface Runnable<TParameter = void> {
|
|||||||
|
|
||||||
type Run<Param> = (parameter: Param) => Promise<void> | void;
|
type Run<Param> = (parameter: Param) => Promise<void> | void;
|
||||||
|
|
||||||
export type RunMany = <Param>(injectionToken: InjectionToken<Runnable<Param>, void>) => Run<Param>;
|
export type RunMany = <Param>(injectionToken: InjectionToken<Runnable<Param>, void>) => Asyncify<Run<Param>>;
|
||||||
|
|
||||||
const computedNextEdge = (traversed: string[], graph: Map<string, Set<string>>, currentId: string, seenIds: Set<string>) => {
|
const computedNextEdge = (traversed: string[], graph: Map<string, Set<string>>, currentId: string, seenIds: Set<string>) => {
|
||||||
seenIds.add(currentId);
|
seenIds.add(currentId);
|
||||||
@ -44,7 +45,7 @@ const verifyRunnablesAreDAG = <Param>(injectionToken: InjectionToken<Runnable<Pa
|
|||||||
for (const runnable of runnables) {
|
for (const runnable of runnables) {
|
||||||
addRunnableId(runnable.id);
|
addRunnableId(runnable.id);
|
||||||
|
|
||||||
if (!runnable.runAfter) {
|
if (!runnable.runAfter || (Array.isArray(runnable.runAfter) && runnable.runAfter.length === 0)) {
|
||||||
addRunnableId(rootId).add(runnable.id);
|
addRunnableId(rootId).add(runnable.id);
|
||||||
} else if (Array.isArray(runnable.runAfter)) {
|
} else if (Array.isArray(runnable.runAfter)) {
|
||||||
for (const parentRunnable of runnable.runAfter) {
|
for (const parentRunnable of runnable.runAfter) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user