Ensure immutability outside of class with Readonly

This commit is contained in:
Jesper 2022-04-13 17:39:29 +02:00
parent 4dffac3dcf
commit 3f2fb9d506
2 changed files with 20 additions and 19 deletions

View File

@ -1,37 +1,37 @@
export class Item { export class Item {
name: string; name: string
sellIn: number; sellIn: number
quality: number; quality: number
constructor(name, sellIn, quality) { constructor(name, sellIn, quality) {
this.name = name; this.name = name
this.sellIn = sellIn; this.sellIn = sellIn
this.quality = quality; this.quality = quality
} }
} }
export class GildedRose { export class GildedRose {
items: Array<Item>; items: Array<Item>
constructor(items = [] as Array<Item>) { constructor(items = [] as Array<Item>) {
this.items = items; this.items = items
} }
updateQuality() { updateQuality() {
this.items = updateItems(this.items) this.items = [...updateItems(this.items)]
return this.items; return this.items
} }
} }
function updateItems(items: Item[]): Item[] { function updateItems(items: readonly Readonly<Item>[]): readonly Readonly<Item>[] {
return items return items
.map(item => ({ ...item, quality: updateItemQuality(item) })) .map(item => ({ ...item, quality: updateItemQuality(item) }))
.map(item => ({ ...item, sellIn: updateItemSellIn(item) })) .map(item => ({ ...item, sellIn: updateItemSellIn(item) }))
.map(item => ({ ...item, quality: updateExpiredItemQuality(item) })) .map(item => ({ ...item, quality: updateExpiredItemQuality(item) }))
} }
function updateItemQuality({ name, quality, sellIn, ...rest }: Item): number { function updateItemQuality({ name, quality, sellIn, ...rest }: Readonly<Item>): number {
switch (name) { switch (name) {
case 'Sulfuras, Hand of Ragnaros': return quality case 'Sulfuras, Hand of Ragnaros': return quality
case 'Aged Brie': return incrementQuality({ quality }); case 'Aged Brie': return incrementQuality({ quality });
@ -46,14 +46,14 @@ function updateItemQuality({ name, quality, sellIn, ...rest }: Item): number {
} }
} }
function updateItemSellIn({ name, sellIn }: Item) { function updateItemSellIn({ name, sellIn }: Readonly<Item>) {
switch (name) { switch (name) {
case 'Sulfuras, Hand of Ragnaros': return sellIn case 'Sulfuras, Hand of Ragnaros': return sellIn
default: return sellIn - 1 default: return sellIn - 1
} }
} }
function updateExpiredItemQuality({ quality, name, sellIn }: Item): number { function updateExpiredItemQuality({ quality, name, sellIn }: Readonly<Item>): number {
const isExpired = sellIn < 0 const isExpired = sellIn < 0
if (!isExpired) return quality if (!isExpired) return quality
@ -65,12 +65,12 @@ function updateExpiredItemQuality({ quality, name, sellIn }: Item): number {
} }
} }
function decrementQuality({ quality }: Pick<Item, 'quality'>): number { function decrementQuality({ quality }: Readonly<Pick<Item, 'quality'>>): number {
if (quality < 1) return quality if (quality < 1) return quality
return quality - 1 return quality - 1
} }
function incrementQuality({ quality }: Pick<Item, 'quality'>): number { function incrementQuality({ quality }: Readonly<Pick<Item, 'quality'>>): number {
if (quality >= 50) return quality if (quality >= 50) return quality
return quality + 1 return quality + 1
} }

View File

@ -61,11 +61,12 @@ export class AcceptanceGildedRose {
} }
} }
test('acceptance tests', () => {
const names = ['Aged Brie', 'Backstage passes to a TAFKAL80ETC concert', 'Sulfuras, Hand of Ragnaros', 'Other'] const names = ['Aged Brie', 'Backstage passes to a TAFKAL80ETC concert', 'Sulfuras, Hand of Ragnaros', 'Other']
const sellIns = [-1, 0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15] const sellIns = [-1, 0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15]
const qualities = [-1, 1, 2, 48, 49, 50, 51] const qualities = [-1, 1, 2, 48, 49, 50, 51]
test('acceptance tests', () => {
for (const name of names) { for (const name of names) {
for (const sellIn of sellIns) { for (const sellIn of sellIns) {
for (const quality of qualities) { for (const quality of qualities) {