Last active
October 21, 2019 23:09
-
-
Save davidwhitney/97898feb8dbaa30f86f8d02da35be2b4 to your computer and use it in GitHub Desktop.
A Typescript version of the guilded rose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Item { | |
name: string; | |
sellIn: number; | |
quality: number; | |
constructor(name: string, sellIn: number, quality: number) { | |
this.name = name; | |
this.sellIn = sellIn; | |
this.quality = quality; | |
} | |
} | |
export class GildedRose { | |
private readonly items: Array<Item>; | |
private readonly immutableItems: String[]; | |
private readonly itemsThatAgeWell: String[]; | |
constructor(items: Item[]) { | |
this.items = items; | |
this.immutableItems = [ "Sulfuras, Hand of Ragnaros" ]; | |
this.itemsThatAgeWell = [ "Aged Brie" ]; | |
} | |
public updateQuality(): Item[] { | |
for (let i: number = 0; i < this.items.length; i++) { | |
const item: Item = this.items[i]; | |
this.processSingleItem(item); | |
} | |
return this.items; | |
} | |
private processSingleItem(item: Item): void { | |
if (this.isImmutable(item)) { | |
return; | |
} | |
item.sellIn--; | |
const rules = [ | |
{ rule: (x: Item) => this.isImmutable(x), delta: 0 }, | |
{ rule: (x: Item) => this.agesWell(x), delta: 1 }, | |
{ rule: (x: Item) => this.isScarce(x) && x.sellIn <= 0, delta: this.setToZero }, | |
{ rule: (x: Item) => this.isScarce(x) && x.sellIn <= 5, delta: 3 }, | |
{ rule: (x: Item) => this.isScarce(x) && x.sellIn <= 10, delta: 2 }, | |
{ rule: (x: Item) => this.isConjured(x), delta: -2 }, | |
{ rule: (x: Item) => this.sellByPassed(x), delta: -2 }, | |
]; | |
const itemChange = rules.find((r: any) => r.rule(item)) || { rule: null, delta: -1 }; | |
item.quality += itemChange.delta; | |
item.quality = item.quality < 0 ? 0 : item.quality; | |
item.quality = item.quality > 50 ? 50 : item.quality; | |
return; | |
} | |
private setToZero: number = -100000; | |
private isImmutable = (i: Item): boolean => this.immutableItems.lastIndexOf(i.name) > -1; | |
private isScarce = (i: Item): boolean => i.name.toLowerCase().lastIndexOf("backstage passes") > -1; | |
private agesWell = (i: Item): boolean => this.itemsThatAgeWell.lastIndexOf(i.name) > -1; | |
private isConjured = (i: Item): boolean => i.name.toLowerCase().lastIndexOf("conjured") > -1; | |
private sellByPassed = (i: Item): boolean => i.sellIn < 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Item, GildedRose } from "./gilded-rose"; | |
describe("Gilded Rose", () => { | |
it("Items have properties that work as expected.", () => { | |
const someItem: Item = new Item("foo", 1, 2); | |
expect(someItem.name).toEqual("foo"); | |
expect(someItem.sellIn).toEqual(1); | |
expect(someItem.quality).toEqual(2); | |
}); | |
it("Both SellIn and Quality lower each tick", () => { | |
const gildedRose = new GildedRose([ new Item("foo", 1, 1) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].sellIn).toBe(0); | |
expect(items[0].quality).toBe(0); | |
}); | |
it("Quality of an item can never be negative", () => { | |
const gildedRose = new GildedRose([ new Item("foo", 0, 0) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(0); | |
}); | |
it("Once the sell by date has passed, quality degrades twice as fast", () => { | |
const gildedRose = new GildedRose([ new Item("Foo", 0, 10) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(8); | |
}); | |
it("Aged brie increases in quality as it ages", () => { | |
const gildedRose = new GildedRose([ new Item("Aged Brie", 10, 10) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(11); | |
}); | |
it("The quality of an item cannot exceed 50", () => { | |
const gildedRose = new GildedRose([ new Item("Aged Brie", 10, 50) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(50); | |
}); | |
it("Sulfuras never has to be sold, nor decreases in quality", () => { | |
const gildedRose = new GildedRose([ new Item("Sulfuras, Hand of Ragnaros", 10, 80) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].sellIn).toBe(10); | |
expect(items[0].quality).toBe(80); | |
}); | |
it("Backstage passes increases in quality by 3 when there is 5 days or less to go", () => { | |
const pass = new Item("Backstage passes to a TAFKAL80ETC concert", 5, 1); | |
const gildedRose = new GildedRose([ pass ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(4); | |
}); | |
it("Backstage passes increases in quality by 2 when there is 10 days or less to go", () => { | |
const pass = new Item("Backstage passes to a TAFKAL80ETC concert", 10, 1); | |
const gildedRose = new GildedRose([ pass ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(3); | |
}); | |
it("Backstage passes worthless after the concert", () => { | |
const pass = new Item("Backstage passes to a TAFKAL80ETC concert", 0, 50); | |
const gildedRose = new GildedRose([ pass ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(0); | |
}); | |
it("Conjured items degrade twice as fast", () => { | |
const gildedRose = new GildedRose([ new Item("Conjured something", 10, 10) ]); | |
const items = gildedRose.updateQuality(); | |
expect(items[0].quality).toBe(8); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Item { | |
name: string; | |
sellIn: number; | |
quality: number; | |
constructor(name, sellIn, quality) { | |
this.name = name; | |
this.sellIn = sellIn; | |
this.quality = quality; | |
} | |
} | |
export class GildedRose { | |
items: Array<Item>; | |
constructor(items = [] as Array<Item>) { | |
this.items = items; | |
} | |
updateQuality() { | |
for (let i = 0; i < this.items.length; i++) { | |
if (this.items[i].name != 'Aged Brie' && this.items[i].name != 'Backstage passes to a TAFKAL80ETC concert') { | |
if (this.items[i].quality > 0) { | |
if (this.items[i].name != 'Sulfuras, Hand of Ragnaros') { | |
this.items[i].quality = this.items[i].quality - 1 | |
} | |
} | |
} else { | |
if (this.items[i].quality < 50) { | |
this.items[i].quality = this.items[i].quality + 1 | |
if (this.items[i].name == 'Backstage passes to a TAFKAL80ETC concert') { | |
if (this.items[i].sellIn < 11) { | |
if (this.items[i].quality < 50) { | |
this.items[i].quality = this.items[i].quality + 1 | |
} | |
} | |
if (this.items[i].sellIn < 6) { | |
if (this.items[i].quality < 50) { | |
this.items[i].quality = this.items[i].quality + 1 | |
} | |
} | |
} | |
} | |
} | |
if (this.items[i].name != 'Sulfuras, Hand of Ragnaros') { | |
this.items[i].sellIn = this.items[i].sellIn - 1; | |
} | |
if (this.items[i].sellIn < 0) { | |
if (this.items[i].name != 'Aged Brie') { | |
if (this.items[i].name != 'Backstage passes to a TAFKAL80ETC concert') { | |
if (this.items[i].quality > 0) { | |
if (this.items[i].name != 'Sulfuras, Hand of Ragnaros') { | |
this.items[i].quality = this.items[i].quality - 1 | |
} | |
} | |
} else { | |
this.items[i].quality = this.items[i].quality - this.items[i].quality | |
} | |
} else { | |
if (this.items[i].quality < 50) { | |
this.items[i].quality = this.items[i].quality + 1 | |
} | |
} | |
} | |
} | |
return this.items; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment