1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Make runnable give friendly error about incorrect hierarchy for easier debugging

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2022-05-18 09:12:46 +03:00
parent aa32655cbe
commit 8aaf288ba6
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
5 changed files with 120 additions and 2 deletions

View File

@ -5,6 +5,8 @@
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import {
createContainer,
getInjectable,
@ -175,6 +177,51 @@ describe("runManyFor", () => {
});
});
it("given invalid hierarchy, when running runnables, throws", () => {
const rootDi = createContainer();
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) => ({
run: () => runMock("some-runnable-1"),
runAfter: di.inject(someOtherInjectable),
}),
injectionToken: someInjectionToken,
});
const someOtherInjectable = getInjectable({
id: "some-runnable-2",
instantiate: () => ({
run: () => runMock("some-runnable-2"),
}),
injectionToken: someOtherInjectionToken,
});
rootDi.register(someInjectable, someOtherInjectable);
const runMany = runManyFor(rootDi)(
someInjectionToken,
);
return expect(() => runMany()).rejects.toThrow(
"Tried to run runnable after other runnable which does not same injection token.",
);
});
describe("when running many with parameter", () => {
let runMock: AsyncFnMock<(...args: unknown[]) => Promise<void>>;

View File

@ -7,7 +7,8 @@ import type {
DiContainerForInjection,
InjectionToken,
} from "@ogre-tools/injectable";
import { filter, map } from "lodash/fp";
import { filter, forEach, map, tap } from "lodash/fp";
import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for";
export interface Runnable<TParameter = void> {
run: Run<TParameter>;
@ -24,12 +25,16 @@ export function runManyFor(di: DiContainerForInjection): RunMany {
return (injectionToken) => async (parameter) => {
const allRunnables = di.injectMany(injectionToken);
const throwWithIncorrectHierarchy = throwWithIncorrectHierarchyFor(allRunnables);
const recursedRun = async (
runAfterRunnable: Runnable<any> | undefined = undefined,
) =>
await pipeline(
allRunnables,
tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)),
filter((runnable) => runnable.runAfter === runAfterRunnable),
map(async (runnable) => {

View File

@ -104,6 +104,51 @@ describe("runManySyncFor", () => {
});
});
it("given invalid hierarchy, when running runnables, throws", () => {
const rootDi = createContainer();
const runMock = jest.fn();
const someInjectionToken = getInjectionToken<RunnableSync>({
id: "some-injection-token",
});
const someOtherInjectionToken = getInjectionToken<RunnableSync>({
id: "some-other-injection-token",
});
const someInjectable = getInjectable({
id: "some-runnable-1",
instantiate: (di) => ({
run: () => runMock("some-runnable-1"),
runAfter: di.inject(someOtherInjectable),
}),
injectionToken: someInjectionToken,
});
const someOtherInjectable = getInjectable({
id: "some-runnable-2",
instantiate: () => ({
run: () => runMock("some-runnable-2"),
}),
injectionToken: someOtherInjectionToken,
});
rootDi.register(someInjectable, someOtherInjectable);
const runMany = runManySyncFor(rootDi)(
someInjectionToken,
);
return expect(() => runMany()).rejects.toThrow(
"Tried to run runnable after other runnable which does not same injection token.",
);
});
describe("when running many with parameter", () => {
let runMock: jest.Mock<(arg: string, arg2: string) => void>;

View File

@ -7,8 +7,9 @@ import type {
DiContainerForInjection,
InjectionToken,
} from "@ogre-tools/injectable";
import { filter, map } from "lodash/fp";
import { filter, forEach, map, tap } from "lodash/fp";
import type { Runnable } from "./run-many-for";
import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for";
export interface RunnableSync<TParameter = void> {
run: RunSync<TParameter>;
@ -25,12 +26,16 @@ export function runManySyncFor(di: DiContainerForInjection): RunManySync {
return (injectionToken) => async (parameter) => {
const allRunnables = di.injectMany(injectionToken);
const throwWithIncorrectHierarchy = throwWithIncorrectHierarchyFor(allRunnables);
const recursedRun = (
runAfterRunnable: RunnableSync<any> | undefined = undefined,
) =>
pipeline(
allRunnables,
tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)),
filter((runnable) => runnable.runAfter === runAfterRunnable),
map((runnable) => {

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Runnable } from "./run-many-for";
import type { RunnableSync } from "./run-many-sync-for";
export const throwWithIncorrectHierarchyFor =
(allRunnables: Runnable<any>[] | RunnableSync<any>[]) =>
(runnable: Runnable<any> | RunnableSync<any>) => {
if (runnable.runAfter && !allRunnables.includes(runnable.runAfter)) {
throw new Error(
"Tried to run runnable after other runnable which does not same injection token.",
);
}
};