Added new functionality to support conjured items

- add new ConjuredItemsBehavior
- add conjured items behavior detection to resolver
- update snapshots because they didn’t account for conjured items
This commit is contained in:
Arno Chauveau 2025-07-24 16:08:14 +02:00
parent 3fcea88b62
commit 15d47f8740
6 changed files with 88 additions and 6 deletions

View File

@ -35,6 +35,4 @@ describe("Gilded Rose", () => {
expect(updateMock).toHaveBeenCalledWith(item1);
expect(updateMock).toHaveBeenCalledWith(item2);
});
// to implement: "Conjured" items degrade in Quality twice as fast as normal items
});

View File

@ -4,6 +4,7 @@ import { AgedBrieBehavior } from "./implementations/aged-brie/aged-brie-behavior
import { DefaultBehavior } from "./implementations/default/default-behavior";
import { BackstagePassBehavior } from "./implementations/backstage-pass/backstage-pass-behavior";
import { LegendaryItemBehavior } from "./implementations/legendary-item/legendary-item-behavior";
import { ConjuredItemBehavior } from "./implementations/conjured-item/conjured-item-behavior";
describe("Behavior resolver", () => {
it("should correctly resolve Aged Brie", () => {
@ -25,6 +26,11 @@ describe("Behavior resolver", () => {
getUpdateBehaviorFor(new Item("Sulfuras, Hand of Ragnaros", 0, 0))
).toBeInstanceOf(LegendaryItemBehavior);
});
it("should correctly resolve Conjured Items", () => {
expect(
getUpdateBehaviorFor(new Item("Conjured Mana Cake", 0, 0))
).toBeInstanceOf(ConjuredItemBehavior);
});
it("should correctly resolve the rest to Legacy behavior", () => {
expect(

View File

@ -4,6 +4,7 @@ import { DefaultBehavior } from "./implementations/default/default-behavior";
import { AgedBrieBehavior } from "./implementations/aged-brie/aged-brie-behavior";
import { BackstagePassBehavior } from "./implementations/backstage-pass/backstage-pass-behavior";
import { LegendaryItemBehavior } from "./implementations/legendary-item/legendary-item-behavior";
import { ConjuredItemBehavior } from "./implementations/conjured-item/conjured-item-behavior";
export function getUpdateBehaviorFor(item: Item): IUpdateBehavior {
switch (item.name) {
@ -13,6 +14,8 @@ export function getUpdateBehaviorFor(item: Item): IUpdateBehavior {
return new BackstagePassBehavior(item);
case "Sulfuras, Hand of Ragnaros":
return new LegendaryItemBehavior(item);
case "Conjured Mana Cake":
return new ConjuredItemBehavior(item);
default:
return new DefaultBehavior(item);
}

View File

@ -0,0 +1,59 @@
import { Item } from "@app/item";
import { ConjuredItemBehavior } from "./conjured-item-behavior";
describe("Conjured Item Behavior", () => {
it("should degrade quality with 2 and sellIn with 1 when sellIn is over 0", () => {
const behavior = new ConjuredItemBehavior(
new Item("Conjured Mana Cake", 1, 4)
);
const result = behavior.update();
expect(result).toMatchObject({
name: "Conjured Mana Cake",
sellIn: 0,
quality: 2,
});
});
it("should degrade quality with 4 and sellin with 1 when sellIn is equal to zero", () => {
const behavior = new ConjuredItemBehavior(
new Item("Conjured Mana Cake", 0, 5)
);
const result = behavior.update();
expect(result).toMatchObject({
name: "Conjured Mana Cake",
sellIn: -1,
quality: 1,
});
});
it("should degrade quality with 4 and sellin with 1 when sellIn is under zero", () => {
const behavior = new ConjuredItemBehavior(
new Item("Conjured Mana Cake", -1, 5)
);
const result = behavior.update();
expect(result).toMatchObject({
name: "Conjured Mana Cake",
sellIn: -2,
quality: 1,
});
});
it("shouldn't degrade quality under 0", () => {
const behavior = new ConjuredItemBehavior(
new Item("Conjured Mana Cake", 1, 1)
);
const result = behavior.update();
expect(result).toMatchObject({
name: "Conjured Mana Cake",
sellIn: 0,
quality: 0,
});
});
});

View File

@ -0,0 +1,16 @@
import { Item } from "@app/item";
import { IUpdateBehavior } from "@app/update-behaviors/update-behavior.interface";
export class ConjuredItemBehavior implements IUpdateBehavior {
constructor(private item: Item) {}
update(): Item {
const amountToSubtract = this.item.sellIn <= 0 ? 4 : 2;
this.item.quality = Math.max(this.item.quality - amountToSubtract, 0);
this.item.sellIn -= 1;
return this.item;
}
}

View File

@ -44,7 +44,7 @@ exports[`Gilded Rose Approval should match the snapshot for thirty Days 1`] = `
},
Item {
"name": "Conjured Mana Cake",
"quality": 5,
"quality": 4,
"sellIn": 2,
},
]
@ -94,7 +94,7 @@ exports[`Gilded Rose Approval should match the snapshot for thirty Days 2`] = `
},
Item {
"name": "Conjured Mana Cake",
"quality": 4,
"quality": 2,
"sellIn": 1,
},
]
@ -144,7 +144,7 @@ exports[`Gilded Rose Approval should match the snapshot for thirty Days 3`] = `
},
Item {
"name": "Conjured Mana Cake",
"quality": 3,
"quality": 0,
"sellIn": 0,
},
]
@ -194,7 +194,7 @@ exports[`Gilded Rose Approval should match the snapshot for thirty Days 4`] = `
},
Item {
"name": "Conjured Mana Cake",
"quality": 1,
"quality": 0,
"sellIn": -1,
},
]