mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-20 08:51:08 +00:00
Replaced all quality modification rules with a new enum rule based on a protocol
This commit is contained in:
parent
6323c90d96
commit
8f15db659d
@ -7,53 +7,29 @@ public class GildedRose {
|
|||||||
|
|
||||||
public func updateQuality() {
|
public func updateQuality() {
|
||||||
for i in 0..<items.count {
|
for i in 0..<items.count {
|
||||||
if (items[i].name != "Aged Brie" && items[i].name != "Backstage passes to a TAFKAL80ETC concert") {
|
items[i] = QualityModificationRule.process(item: items[i])
|
||||||
if (items[i].quality > 0) {
|
|
||||||
if (items[i].name != "Sulfuras, Hand of Ragnaros") {
|
|
||||||
items[i].quality = items[i].quality - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (items[i].quality < 50) {
|
|
||||||
items[i].quality = items[i].quality + 1
|
|
||||||
|
|
||||||
if (items[i].name == "Backstage passes to a TAFKAL80ETC concert") {
|
|
||||||
if (items[i].sellIn < 11) {
|
|
||||||
if (items[i].quality < 50) {
|
|
||||||
items[i].quality = items[i].quality + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (items[i].sellIn < 6) {
|
|
||||||
if (items[i].quality < 50) {
|
|
||||||
items[i].quality = items[i].quality + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (items[i].name != "Sulfuras, Hand of Ragnaros") {
|
if (items[i].name != "Sulfuras, Hand of Ragnaros") {
|
||||||
items[i].sellIn = items[i].sellIn - 1
|
items[i].sellIn = items[i].sellIn - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items[i].sellIn < 0) {
|
// if (items[i].sellIn < 0) {
|
||||||
if (items[i].name != "Aged Brie") {
|
// if (items[i].name != "Aged Brie") {
|
||||||
if (items[i].name != "Backstage passes to a TAFKAL80ETC concert") {
|
// if (items[i].name != "Backstage passes to a TAFKAL80ETC concert") {
|
||||||
if (items[i].quality > 0) {
|
// if (items[i].quality > 0) {
|
||||||
if (items[i].name != "Sulfuras, Hand of Ragnaros") {
|
// if (items[i].name != "Sulfuras, Hand of Ragnaros") {
|
||||||
items[i].quality = items[i].quality - 1
|
// items[i].quality = items[i].quality - 1
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
items[i].quality = items[i].quality - items[i].quality
|
// items[i].quality = items[i].quality - items[i].quality
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
if (items[i].quality < 50) {
|
// if (items[i].quality < 50) {
|
||||||
items[i].quality = items[i].quality + 1
|
// items[i].quality = items[i].quality + 1
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// QualityModificationRule.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Lucas van Dongen on 23/11/2020.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// These rules are really simple, you could handle more complex ones within their own class
|
||||||
|
enum QualityModificationRule: Rule {
|
||||||
|
typealias RuleType = Self
|
||||||
|
|
||||||
|
case regular,
|
||||||
|
increasesQuality,
|
||||||
|
qualityIncreasesFasterBeforeExpireThenDropsToZero,
|
||||||
|
legendary
|
||||||
|
|
||||||
|
static func rule(for item: Item) -> RuleType {
|
||||||
|
switch item.name {
|
||||||
|
case "Aged Brie":
|
||||||
|
return .increasesQuality
|
||||||
|
case "Backstage passes to a TAFKAL80ETC concert":
|
||||||
|
return .qualityIncreasesFasterBeforeExpireThenDropsToZero
|
||||||
|
case "Sulfuras, Hand of Ragnaros":
|
||||||
|
return .legendary
|
||||||
|
default:
|
||||||
|
return .regular
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func apply(to item: Item) -> Item {
|
||||||
|
switch self {
|
||||||
|
case .regular:
|
||||||
|
return applyRegularRule(to: item)
|
||||||
|
case .increasesQuality:
|
||||||
|
return applyIncreasesQualityRule(to: item)
|
||||||
|
case .qualityIncreasesFasterBeforeExpireThenDropsToZero:
|
||||||
|
return qualityIncreasesFasterBeforeExpireThenDropsToZeroRule(to: item)
|
||||||
|
case .legendary:
|
||||||
|
return applyLegendaryRule(to: item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyRegularRule(to item: Item) -> Item {
|
||||||
|
let modification = Self.isRegularItemExpired(sellIn: item.sellIn) ? -2 : -1
|
||||||
|
return Self.applyQualityThresholds(to: item, newQuality: item.quality + modification)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyIncreasesQualityRule(to item: Item) -> Item {
|
||||||
|
Self.applyQualityThresholds(to: item, newQuality: item.quality + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func qualityIncreasesFasterBeforeExpireThenDropsToZeroRule(to item: Item) -> Item {
|
||||||
|
let newQuality: Int
|
||||||
|
switch item.sellIn {
|
||||||
|
case ...0:
|
||||||
|
newQuality = 0
|
||||||
|
case 0...5:
|
||||||
|
newQuality = item.quality + 3
|
||||||
|
case 5...10:
|
||||||
|
newQuality = item.quality + 2
|
||||||
|
case 10...:
|
||||||
|
newQuality = item.quality + 1
|
||||||
|
default:
|
||||||
|
fatalError("All values of `sellIn` should be covered")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self.applyQualityThresholds(to: item, newQuality: newQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyLegendaryRule(to item: Item) -> Item {
|
||||||
|
return item // No change
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func applyQualityThresholds(to item: Item, newQuality: Int) -> Item {
|
||||||
|
let correctedQuality: Int
|
||||||
|
switch newQuality {
|
||||||
|
case ...0:
|
||||||
|
correctedQuality = 0
|
||||||
|
case 0...50:
|
||||||
|
correctedQuality = newQuality
|
||||||
|
case 50...:
|
||||||
|
correctedQuality = 50
|
||||||
|
default:
|
||||||
|
fatalError("All values of `quality` should be covered")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Item(name: item.name, sellIn: item.sellIn, quality: correctedQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func isRegularItemExpired(sellIn: Int) -> Bool {
|
||||||
|
return sellIn <= 0
|
||||||
|
}
|
||||||
|
}
|
||||||
23
swift/Sources/GildedRose/Rules/Rule.swift
Normal file
23
swift/Sources/GildedRose/Rules/Rule.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Lucas van Dongen on 23/11/2020.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol Rule {
|
||||||
|
associatedtype RuleType: Rule
|
||||||
|
|
||||||
|
func apply(to item: Item) -> Item
|
||||||
|
|
||||||
|
static func rule(for item: Item) -> RuleType
|
||||||
|
static func process(item: Item) -> Item
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Rule {
|
||||||
|
static func process(item: Item) -> Item {
|
||||||
|
return rule(for: item).apply(to: item)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,6 @@ extension Item {
|
|||||||
let system = GildedRose(items: [self])
|
let system = GildedRose(items: [self])
|
||||||
system.updateQuality()
|
system.updateQuality()
|
||||||
|
|
||||||
return self.quality == quality
|
return system.items.first?.quality == quality
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// TestSellInModificationRule.swift
|
||||||
|
// GildedRose
|
||||||
|
//
|
||||||
|
// Created by Lucas van Dongen on 23/11/2020.
|
||||||
|
//
|
||||||
|
|
||||||
|
@testable import GildedRose
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class TestSellInModificationRule: XCTestCase {
|
||||||
|
private let regularItem = Item(name: "Regular Item", sellIn: 1, quality: 5)
|
||||||
|
private let backstagePassesItem = Item(name: "Backstage passes to a TAFKAL80ETC concert", sellIn: 1, quality: 0)
|
||||||
|
private let brieItem = Item(name: "Aged Brie", sellIn: 2, quality: 0)
|
||||||
|
private let sulfuras = Item(name: "Sulfuras, Hand of Ragnaros", sellIn: 0, quality: 50)
|
||||||
|
|
||||||
|
//- All items have a SellIn value which denotes the number of days we have to sell the item
|
||||||
|
func testRuleSelection() {
|
||||||
|
XCTAssertEqual(QualityModificationRule.rule(for: regularItem), .regular)
|
||||||
|
XCTAssertEqual(QualityModificationRule.rule(for: backstagePassesItem), .qualityIncreasesFasterBeforeExpireThenDropsToZero)
|
||||||
|
XCTAssertEqual(QualityModificationRule.rule(for: brieItem), .increasesQuality)
|
||||||
|
XCTAssertEqual(QualityModificationRule.rule(for: sulfuras), .legendary)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testApplyQualityThresholds() {
|
||||||
|
let tooLow = Item(name: "Too low", sellIn: 0, quality: 0)
|
||||||
|
let tooHigh = Item(name: "Too high", sellIn: 0, quality: 50)
|
||||||
|
let unaltered = Item(name: "Too low", sellIn: 0, quality: 25)
|
||||||
|
|
||||||
|
XCTAssertEqual(QualityModificationRule.applyQualityThresholds(to: tooLow, newQuality: -1).quality, 0)
|
||||||
|
XCTAssertEqual(QualityModificationRule.applyQualityThresholds(to: tooHigh, newQuality: 51).quality, 50)
|
||||||
|
XCTAssertEqual(QualityModificationRule.applyQualityThresholds(to: unaltered, newQuality: 24).quality, 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIsRegularItemExpired() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user