From 29a35ab71cdc6475851d70af148e79c3eecf5b51 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 9 Dec 2022 10:50:33 -0500 Subject: [PATCH] Add tests to verify runMany behaviour in new possible incorrect configuration Signed-off-by: Sebastian Malton --- src/common/runnable/run-many-for.test.ts | 63 +++++++++++++++++++++++- src/common/runnable/run-many-for.ts | 10 ++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/common/runnable/run-many-for.test.ts b/src/common/runnable/run-many-for.test.ts index 768eb57939..c80e206af9 100644 --- a/src/common/runnable/run-many-for.test.ts +++ b/src/common/runnable/run-many-for.test.ts @@ -223,7 +223,68 @@ describe("runManyFor", () => { ); 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/, + /Runnable "some-runnable-1" is unreachable for injection token "some-injection-token": run afters "some-runnable-2" are a part of different injection tokens./, + ); + }); + + it("given partially incorrect hierarchy, when running runnables, throws", () => { + const rootDi = createContainer("irrelevant"); + + const runMock = asyncFn<(...args: unknown[]) => void>(); + + const someInjectionToken = getInjectionToken({ + id: "some-injection-token", + }); + + const someOtherInjectionToken = getInjectionToken({ + 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), + di.inject(someSecondInjectable), + ], + }), + + injectionToken: someInjectionToken, + }); + + const someSecondInjectable = getInjectable({ + id: "some-runnable-2", + + instantiate: () => ({ + id: "some-runnable-2", + run: () => runMock("some-runnable-2"), + }), + + injectionToken: someInjectionToken, + }); + + const someOtherInjectable = getInjectable({ + id: "some-runnable-3", + + instantiate: () => ({ + id: "some-runnable-3", + run: () => runMock("some-runnable-3"), + }), + + injectionToken: someOtherInjectionToken, + }); + + rootDi.register(someInjectable, someOtherInjectable, someSecondInjectable); + + const runMany = runManyFor(rootDi)( + someInjectionToken, + ); + + return expect(() => runMany()).rejects.toThrow( + /Runnable "some-runnable-3" is not part of the injection token "some-injection-token"/, ); }); diff --git a/src/common/runnable/run-many-for.ts b/src/common/runnable/run-many-for.ts index d5bff091eb..bda6edb9d1 100644 --- a/src/common/runnable/run-many-for.ts +++ b/src/common/runnable/run-many-for.ts @@ -34,7 +34,7 @@ const computedNextEdge = (traversed: string[], graph: Map>, } }; -const verifyRunnablesAreDAG = (runnables: Runnable[]) => { +const verifyRunnablesAreDAG = (injectionToken: InjectionToken, void>, runnables: Runnable[]) => { const rootId = uuid.v4(); const runnableGraph = new Map>(); const seenIds = new Set(); @@ -63,7 +63,9 @@ const verifyRunnablesAreDAG = (runnables: Runnable[]) => { if (!seenIds.has(id)) { const runnable = runnables.find(runnable => runnable.id === id); - assert(runnable, `Unknown runnable id="${id}", logic error`); + if (!runnable) { + throw new Error(`Runnable "${id}" is not part of the injection token "${injectionToken.id}"`); + } const runAfters = [runnable.runAfter] .flat() @@ -71,7 +73,7 @@ const verifyRunnablesAreDAG = (runnables: Runnable[]) => { .map(runnable => runnable.id) .join('", "'); - throw new Error(`Unreachable runnable="${id}". The specified runAfters; all of "${runAfters}"; are not part of this injection token`); + throw new Error(`Runnable "${id}" is unreachable for injection token "${injectionToken.id}": run afters "${runAfters}" are a part of different injection tokens.`); } } }; @@ -96,7 +98,7 @@ export function runManyFor(di: DiContainerForInjection): RunMany { const executeRunnable = executeRunnableWith(param); const allRunnables = di.injectMany(injectionToken); - verifyRunnablesAreDAG(allRunnables); + verifyRunnablesAreDAG(injectionToken, allRunnables); await Promise.all(allRunnables.map(executeRunnable)); };