mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-04 17:21:38 +00:00
Refactor tests
- moved snapshot tests to better named folder - refactored gilded-rose tests to unit tests in their right location. - mock implementation details in gilded rose test - wrote unit tests for behavior resolver - fix testing config to account for the changes
This commit is contained in:
parent
372111147f
commit
cc8a2b35b0
40
TypeScript/app/gilded-rose.spec.ts
Normal file
40
TypeScript/app/gilded-rose.spec.ts
Normal file
@ -0,0 +1,40 @@
|
||||
const getUpdateBehaviorMock = jest.fn((item: Item) => new MockBehavior(item));
|
||||
const updateMock = jest.fn((item: Item) => item);
|
||||
|
||||
jest.mock("@app/update-behaviors", () => ({
|
||||
getUpdateBehaviorFor: getUpdateBehaviorMock,
|
||||
}));
|
||||
|
||||
import { GildedRose } from "@app/gilded-rose";
|
||||
import { Item } from "@app/item";
|
||||
import { IUpdateBehavior } from "@app/update-behaviors";
|
||||
|
||||
export class MockBehavior implements IUpdateBehavior {
|
||||
constructor(public item: Item) {}
|
||||
update() {
|
||||
return updateMock(this.item);
|
||||
}
|
||||
}
|
||||
|
||||
describe("Gilded Rose", () => {
|
||||
it("should have an empty array as items when no constructor parameter is provided", () => {
|
||||
const gildedRose = new GildedRose();
|
||||
expect(gildedRose.items).toEqual([]);
|
||||
});
|
||||
|
||||
it("should call the behavior resolver and update function for each item", () => {
|
||||
const item1 = new Item("item 1", 0, 0);
|
||||
const item2 = new Item("item 2", 0, 0);
|
||||
const gildedRose = new GildedRose([item1, item2]);
|
||||
|
||||
gildedRose.updateQuality();
|
||||
|
||||
expect(getUpdateBehaviorMock).toHaveBeenCalledWith(item1);
|
||||
expect(getUpdateBehaviorMock).toHaveBeenCalledWith(item2);
|
||||
|
||||
expect(updateMock).toHaveBeenCalledWith(item1);
|
||||
expect(updateMock).toHaveBeenCalledWith(item2);
|
||||
});
|
||||
|
||||
// to implement: "Conjured" items degrade in Quality twice as fast as normal items
|
||||
});
|
||||
18
TypeScript/app/update-behaviors/behavior-resolver.spec.ts
Normal file
18
TypeScript/app/update-behaviors/behavior-resolver.spec.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Item } from "@app/item";
|
||||
import { getUpdateBehaviorFor } from "./behavior-resolver";
|
||||
import { AgedBrieBehavior } from "./implementations/aged-brie-behavior";
|
||||
import { LegacyBehavior } from "./implementations/legacy-behavior";
|
||||
|
||||
describe("Behavior resolver", () => {
|
||||
it("should correctly resolve Aged Brie", () => {
|
||||
expect(getUpdateBehaviorFor(new Item("Aged Brie", 0, 0))).toBeInstanceOf(
|
||||
AgedBrieBehavior
|
||||
);
|
||||
});
|
||||
|
||||
it("should correctly resolve the rest to Legacy behavior", () => {
|
||||
expect(
|
||||
getUpdateBehaviorFor(new Item("some other item", 0, 0))
|
||||
).toBeInstanceOf(LegacyBehavior);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,40 @@
|
||||
import { Item } from "@app/item";
|
||||
import { AgedBrieBehavior } from "./aged-brie-behavior";
|
||||
|
||||
describe("AgedBrie Behavior", () => {
|
||||
it("should increase quality of Aged Brie as it gets older", () => {
|
||||
const behavior = new AgedBrieBehavior(new Item("Aged Brie", 1, 1));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: 0,
|
||||
quality: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Aged Brie twice as fast after sell in date", () => {
|
||||
const behavior = new AgedBrieBehavior(new Item("Aged Brie", 0, 1));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: -1,
|
||||
quality: 3,
|
||||
});
|
||||
});
|
||||
|
||||
it("should never increase quality of Aged Brie over 50", () => {
|
||||
const behavior = new AgedBrieBehavior(new Item("Aged Brie", 0, 50));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: -1,
|
||||
quality: 50,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,110 @@
|
||||
import { Item } from "@app/item";
|
||||
import { LegacyBehavior } from "./legacy-behavior";
|
||||
|
||||
describe("Legacy Behavior", () => {
|
||||
it("should degrade sell inn and quality each day", () => {
|
||||
const behavior = new LegacyBehavior(new Item("standard item", 1, 1));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: 0,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should degrade quality twice as fast after sell in date", () => {
|
||||
const behavior = new LegacyBehavior(new Item("standard item", 0, 2));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: -1,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should not degrade quality below 0", () => {
|
||||
const behavior = new LegacyBehavior(new Item("standard item", 1, 0));
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: 0,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should not change quality of Sulfuras", () => {
|
||||
const behavior = new LegacyBehavior(
|
||||
new Item("Sulfuras, Hand of Ragnaros", 0, 80)
|
||||
);
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Sulfuras, Hand of Ragnaros",
|
||||
sellIn: 0,
|
||||
quality: 80,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 1 if sell in date is more than 10 days away", () => {
|
||||
const behavior = new LegacyBehavior(
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 11, 20)
|
||||
);
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 10,
|
||||
quality: 21,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 2 if sell in date is less than 10 days away but more than 5", () => {
|
||||
const behavior = new LegacyBehavior(
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 9, 20)
|
||||
);
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 8,
|
||||
quality: 22,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 3 if sell in date is less than 5 days away", () => {
|
||||
const behavior = new LegacyBehavior(
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 4, 20)
|
||||
);
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 3,
|
||||
quality: 23,
|
||||
});
|
||||
});
|
||||
|
||||
it("should drop quality of Backstage passes to 0 after sell in date", () => {
|
||||
const behavior = new LegacyBehavior(
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 0, 20)
|
||||
);
|
||||
|
||||
const result = behavior.update();
|
||||
|
||||
expect(result).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: -1,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,13 +1,15 @@
|
||||
import { pathsToModuleNameMapper } from "ts-jest";
|
||||
import { compilerOptions } from './tsconfig.json'
|
||||
import { pathsToModuleNameMapper } from "ts-jest";
|
||||
import { compilerOptions } from "./tsconfig.json";
|
||||
|
||||
export default {
|
||||
roots: ['<rootDir>/app', '<rootDir>/test/jest'],
|
||||
roots: ["<rootDir>/app", "<rootDir>/snapshot-tests"],
|
||||
collectCoverage: true,
|
||||
coverageDirectory: 'coverage',
|
||||
coverageProvider: 'v8',
|
||||
coverageDirectory: "coverage",
|
||||
coverageProvider: "v8",
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
"^.+\\.tsx?$": "ts-jest",
|
||||
},
|
||||
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' } ),
|
||||
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
|
||||
prefix: "<rootDir>/",
|
||||
}),
|
||||
};
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
"version": "1.0.0",
|
||||
"description": "Gilded Rose kata in TypeScript",
|
||||
"scripts": {
|
||||
"precompile": "rimraf app/**/*.js test/**/*.js",
|
||||
"precompile": "rimraf app/**/*.js snapshot-tests/**/*.js",
|
||||
"compile": "tsc",
|
||||
"pretest": "rimraf app/**/*.js test/**/*.js",
|
||||
"pretest": "rimraf app/**/*.js snapshot-tests/**/*.js",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watchAll"
|
||||
},
|
||||
|
||||
@ -1,153 +0,0 @@
|
||||
import { GildedRose } from "@app/gilded-rose";
|
||||
import { Item } from "@app/item";
|
||||
|
||||
describe("Gilded Rose", () => {
|
||||
it("should have an empty array as items when no constructor parameter is provided", () => {
|
||||
const gildedRose = new GildedRose();
|
||||
expect(gildedRose.items).toEqual([]);
|
||||
});
|
||||
|
||||
it("should degrade sell inn and quality each day", () => {
|
||||
const gildedRose = new GildedRose([new Item("standard item", 1, 1)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: 0,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should degrade quality twice as fast after sell in date", () => {
|
||||
const gildedRose = new GildedRose([new Item("standard item", 0, 2)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: -1,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should not degrade quality below 0", () => {
|
||||
const gildedRose = new GildedRose([new Item("standard item", 1, 0)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "standard item",
|
||||
sellIn: 0,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Aged Brie as it gets older", () => {
|
||||
const gildedRose = new GildedRose([new Item("Aged Brie", 1, 1)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: 0,
|
||||
quality: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Aged Brie twice as fast after sell in date", () => {
|
||||
const gildedRose = new GildedRose([new Item("Aged Brie", 0, 1)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: -1,
|
||||
quality: 3,
|
||||
});
|
||||
});
|
||||
|
||||
it("should never increase quality of Aged Brie over 50", () => {
|
||||
const gildedRose = new GildedRose([new Item("Aged Brie", 0, 50)]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Aged Brie",
|
||||
sellIn: -1,
|
||||
quality: 50,
|
||||
});
|
||||
});
|
||||
|
||||
it("should not change quality of Sulfuras", () => {
|
||||
const gildedRose = new GildedRose([
|
||||
new Item("Sulfuras, Hand of Ragnaros", 0, 80),
|
||||
]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Sulfuras, Hand of Ragnaros",
|
||||
sellIn: 0,
|
||||
quality: 80,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 1 if sell in date is more than 10 days away", () => {
|
||||
const gildedRose = new GildedRose([
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 11, 20),
|
||||
]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 10,
|
||||
quality: 21,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 2 if sell in date is less than 10 days away but more than 5", () => {
|
||||
const gildedRose = new GildedRose([
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 9, 20),
|
||||
]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 8,
|
||||
quality: 22,
|
||||
});
|
||||
});
|
||||
|
||||
it("should increase quality of Backstage passes by 3 if sell in date is less than 5 days away", () => {
|
||||
const gildedRose = new GildedRose([
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 4, 20),
|
||||
]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: 3,
|
||||
quality: 23,
|
||||
});
|
||||
});
|
||||
|
||||
it("should drop quality of Backstage passes to 0 after sell in date", () => {
|
||||
const gildedRose = new GildedRose([
|
||||
new Item("Backstage passes to a TAFKAL80ETC concert", 0, 20),
|
||||
]);
|
||||
|
||||
const items = gildedRose.updateQuality();
|
||||
|
||||
expect(items[0]).toMatchObject({
|
||||
name: "Backstage passes to a TAFKAL80ETC concert",
|
||||
sellIn: -1,
|
||||
quality: 0,
|
||||
});
|
||||
});
|
||||
|
||||
// to implement: "Conjured" items degrade in Quality twice as fast as normal items
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user