Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Last active October 21, 2019 23:09
Show Gist options
  • Save davidwhitney/97898feb8dbaa30f86f8d02da35be2b4 to your computer and use it in GitHub Desktop.
Save davidwhitney/97898feb8dbaa30f86f8d02da35be2b4 to your computer and use it in GitHub Desktop.
A Typescript version of the guilded rose
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;
}
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);
});
});
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