From a38a06f91660b78e591de99e7f595f404b743e8d Mon Sep 17 00:00:00 2001 From: Iku-turso Date: Wed, 15 Mar 2023 11:09:02 +0200 Subject: [PATCH] Make monster pool extendable instead of single hard-coded monster Co-authored-by: Janne Savolainen Signed-off-by: Iku-turso --- ...andom-sample-from-collection.injectable.ts | 10 ++++++++ ...le-initial-monster-encounter.injectable.ts | 2 +- .../src/monster-beatdown.test.ts | 25 +++++++++++++++---- .../src/monster.injectable.ts | 20 +++++++++++++-- 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 packages/kata-for-gabriel/src/get-random-sample-from-collection.injectable.ts diff --git a/packages/kata-for-gabriel/src/get-random-sample-from-collection.injectable.ts b/packages/kata-for-gabriel/src/get-random-sample-from-collection.injectable.ts new file mode 100644 index 0000000000..d4b39c1819 --- /dev/null +++ b/packages/kata-for-gabriel/src/get-random-sample-from-collection.injectable.ts @@ -0,0 +1,10 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import { sample } from "lodash/fp"; + +const getRandomSampleFromCollectionInjectable = getInjectable({ + id: "get-random-sample-from-collection", + instantiate: () => sample, + causesSideEffects: true, +}); + +export default getRandomSampleFromCollectionInjectable; diff --git a/packages/kata-for-gabriel/src/handle-initial-monster-encounter.injectable.ts b/packages/kata-for-gabriel/src/handle-initial-monster-encounter.injectable.ts index 1368a32c44..66f3c6239c 100644 --- a/packages/kata-for-gabriel/src/handle-initial-monster-encounter.injectable.ts +++ b/packages/kata-for-gabriel/src/handle-initial-monster-encounter.injectable.ts @@ -12,7 +12,7 @@ const handleInitialMonsterEncounterInjectable = getInjectable({ const monster = di.inject(monsterInjectable); return async () => { - messageToPlayer(`You encounter a monster with ${monster.hitPoints} hit-points`); + messageToPlayer(`You encounter a monster "${monster.name}" with ${monster.hitPoints} hit-points`); const playerWantsToAttack = await questionToPlayer("Attack the monster?"); if (playerWantsToAttack) { diff --git a/packages/kata-for-gabriel/src/monster-beatdown.test.ts b/packages/kata-for-gabriel/src/monster-beatdown.test.ts index 4869fa72ac..fde9b46238 100644 --- a/packages/kata-for-gabriel/src/monster-beatdown.test.ts +++ b/packages/kata-for-gabriel/src/monster-beatdown.test.ts @@ -1,22 +1,28 @@ import { Dependencies, gameInjectable } from "./monster-beatdown.injectable"; import asyncFn, { AsyncFnMock } from "@async-fn/jest"; import { getPromiseStatus } from "@k8slens/test-utils"; -import { createContainer } from "@ogre-tools/injectable"; +import { createContainer, DiContainer, getInjectable } from "@ogre-tools/injectable"; import messageToPlayerInjectable from "./message-to-player.injectable"; import castDieInjectable from "./cast-die.injectable"; import questionToPlayerInjectable from "./question-to-player.injectable"; import { registerFeature } from "@k8slens/feature-core"; import { gabrielFeature } from "./feature"; +import { monsterInjectionToken } from "./monster.injectable"; +import { find } from "lodash/fp"; +import getRandomSampleFromCollectionInjectable from "./get-random-sample-from-collection.injectable"; -describe("monster-beatdown", () => { +describe("monster-beatdown, given there are monsters in the monster pool", () => { let game: { start: () => Promise }; let messageToPlayerMock: jest.Mock; let questionToPlayerMock: AsyncFnMock; let castDieMock: AsyncFnMock; let gamePromise: Promise; + let di: DiContainer; beforeEach(() => { - const di = createContainer("monster-beatdown"); + di = createContainer("monster-beatdown"); + + di.preventSideEffects(); registerFeature(di, gabrielFeature); @@ -28,6 +34,15 @@ describe("monster-beatdown", () => { questionToPlayerMock = asyncFn(); castDieMock = asyncFn(); + const someMonsterInjectable = getInjectable({ + id: "some-janne-monster", + instantiate: () => ({ name: "Janne", hitPoints: 3 }), + injectionToken: monsterInjectionToken, + }); + + di.register(someMonsterInjectable); + di.override(getRandomSampleFromCollectionInjectable, () => find({ name: "Janne" })); + game = di.inject(gameInjectable); }); @@ -50,9 +65,9 @@ describe("monster-beatdown", () => { gamePromise = game.start(); }); - it("player encounters a monster", () => { + it("player encounters one of the monsters", () => { expect(messageToPlayerMock.mock.calls).toEqual([ - ["You encounter a monster with 3 hit-points"], + ['You encounter a monster "Janne" with 3 hit-points'], ]); }); diff --git a/packages/kata-for-gabriel/src/monster.injectable.ts b/packages/kata-for-gabriel/src/monster.injectable.ts index aa78edf6b2..d43bd3f6de 100644 --- a/packages/kata-for-gabriel/src/monster.injectable.ts +++ b/packages/kata-for-gabriel/src/monster.injectable.ts @@ -1,8 +1,24 @@ -import { getInjectable } from "@ogre-tools/injectable"; +import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; +import getRandomSampleFromCollectionInjectable from "./get-random-sample-from-collection.injectable"; + +export type Monster = { + name: string; + hitPoints: number; +}; + +export const monsterInjectionToken = getInjectionToken({ id: "monster-injection-token" }); const monsterInjectable = getInjectable({ id: "monster", - instantiate: () => ({ hitPoints: 3 }), + + instantiate: (di): Monster => { + const allMonsters = di.injectMany(monsterInjectionToken); + const getRandomSampleFromCollection = di.inject(getRandomSampleFromCollectionInjectable); + + const randomMonster = getRandomSampleFromCollection(allMonsters); + + return randomMonster!; + }, }); export default monsterInjectable;