From 8f762ee408140de03c8abd713c7f5705a492dfc5 Mon Sep 17 00:00:00 2001 From: Thang Tran Date: Thu, 2 Mar 2023 14:30:12 +0700 Subject: [PATCH] Refactor Code and write Unit test --- config/item_mapping.php | 9 +++++++ src/GildedRose.php | 7 +++++- src/Items/Factory/ItemFactory.php | 42 +++++++++++++++++-------------- tests/GildedRoseTest.php | 6 ++--- 4 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 config/item_mapping.php diff --git a/config/item_mapping.php b/config/item_mapping.php new file mode 100644 index 00000000..0c73d21b --- /dev/null +++ b/config/item_mapping.php @@ -0,0 +1,9 @@ + 'GildedRose\Items\AgedBrieItem', + 'Backstage passes' => 'GildedRose\Items\BackstagePassItem', + 'Sulfuras' => 'GildedRose\Items\SulfurasItem', + 'Conjured' => 'GildedRose\Items\ConjuredItem', + // Add more mappings here... +]; \ No newline at end of file diff --git a/src/GildedRose.php b/src/GildedRose.php index 87b832e9..07dde689 100644 --- a/src/GildedRose.php +++ b/src/GildedRose.php @@ -18,8 +18,13 @@ final class GildedRose public function updateQuality(): void { + // We don't use symfony, so tempory load the mapping file simple like this. + // In symfony we can use ParameterBagInterface to load yaml config + $mappingFile = __DIR__ . '/../config/item_mapping.php'; + $itemFactory = new ItemFactory($mappingFile); + foreach ($this->items as $item) { - $itemInstance = ItemFactory::createItem($item); + $itemInstance = $itemFactory->createItem($item); $itemInstance->updateSellIn($item); $itemInstance->updateQuality($item); } diff --git a/src/Items/Factory/ItemFactory.php b/src/Items/Factory/ItemFactory.php index 387c6809..50cdce29 100644 --- a/src/Items/Factory/ItemFactory.php +++ b/src/Items/Factory/ItemFactory.php @@ -5,31 +5,35 @@ declare(strict_types=1); namespace GildedRose\Items\Factory; use GildedRose\Item; -use GildedRose\Items\AgedBrieItem; -use GildedRose\Items\BackstagePassItem; -use GildedRose\Items\ConjuredItem; use GildedRose\Items\Interface\ItemInterface; use GildedRose\Items\NormalItem; -use GildedRose\Items\SulfurasItem; class ItemFactory { - public const AGED_BRIE_ITEM = 'Aged Brie'; + private array $itemMappings; - public const BACKSTAGE_ITEM = 'Backstage'; - - public const SULFURAS_ITEM = 'Sulfuras'; - - public const CONJURED_ITEM = 'Conjured'; - - public static function createItem(Item $item): ItemInterface + public function __construct(string $configFilePath) { - return match (true) { - str_contains($item->name, self::AGED_BRIE_ITEM) => new AgedBrieItem(), - str_contains($item->name, self::BACKSTAGE_ITEM) => new BackstagePassItem(), - str_contains($item->name, self::SULFURAS_ITEM) => new SulfurasItem(), - str_contains($item->name, self::CONJURED_ITEM) => new ConjuredItem(), - default => new NormalItem() - }; + $this->itemMappings = require $configFilePath; + } + + public function createItem(Item $item): ItemInterface + { + foreach ($this->itemMappings as $itemName => $itemClassName) { + if (! class_exists($itemClassName)) { + throw new \RuntimeException(sprintf('Class "%s" does not exist', $itemClassName)); + } + + if (str_contains($item->name, $itemName)) { + $reflection = new \ReflectionClass($itemClassName); + $instance = $reflection->newInstance(); + + if (! $instance instanceof ItemInterface) { + throw new \RuntimeException(sprintf('Class "%s" does not implement ItemInterface', $itemClassName)); + } + return $instance; + } + } + return new NormalItem(); } } diff --git a/tests/GildedRoseTest.php b/tests/GildedRoseTest.php index 80c456da..2f4f80f1 100644 --- a/tests/GildedRoseTest.php +++ b/tests/GildedRoseTest.php @@ -79,7 +79,7 @@ class GildedRoseTest extends TestCase public function testBackstageIncreaseQualityBy2WhenSellInLessThanOrEqual10(): void { $items = [ - new Item('Backstage', 9, 10), + new Item('Backstage passes', 9, 10), ]; $GildedRose = new GildedRose($items); $GildedRose->updateQuality(); @@ -90,7 +90,7 @@ class GildedRoseTest extends TestCase public function testBackstageIncreaseQualityBy3WhenSellInLessThanOrEqual5(): void { $items = [ - new Item('Backstage', 4, 10), + new Item('Backstage passes', 4, 10), ]; $GildedRose = new GildedRose($items); $GildedRose->updateQuality(); @@ -101,7 +101,7 @@ class GildedRoseTest extends TestCase public function testBackstageSetQualityZeroWhenSellInLessThanOrEqualZero(): void { $items = [ - new Item('Backstage', 0, 10), + new Item('Backstage passes', 0, 10), ]; $GildedRose = new GildedRose($items); $GildedRose->updateQuality();