Refactor Code and write Unit test

This commit is contained in:
Thang Tran 2023-03-02 14:30:12 +07:00
parent 0cff61e7e7
commit 8f762ee408
4 changed files with 41 additions and 23 deletions

9
config/item_mapping.php Normal file
View File

@ -0,0 +1,9 @@
<?php
return [
'Aged Brie' => 'GildedRose\Items\AgedBrieItem',
'Backstage passes' => 'GildedRose\Items\BackstagePassItem',
'Sulfuras' => 'GildedRose\Items\SulfurasItem',
'Conjured' => 'GildedRose\Items\ConjuredItem',
// Add more mappings here...
];

View File

@ -18,8 +18,13 @@ final class GildedRose
public function updateQuality(): void 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) { foreach ($this->items as $item) {
$itemInstance = ItemFactory::createItem($item); $itemInstance = $itemFactory->createItem($item);
$itemInstance->updateSellIn($item); $itemInstance->updateSellIn($item);
$itemInstance->updateQuality($item); $itemInstance->updateQuality($item);
} }

View File

@ -5,31 +5,35 @@ declare(strict_types=1);
namespace GildedRose\Items\Factory; namespace GildedRose\Items\Factory;
use GildedRose\Item; use GildedRose\Item;
use GildedRose\Items\AgedBrieItem;
use GildedRose\Items\BackstagePassItem;
use GildedRose\Items\ConjuredItem;
use GildedRose\Items\Interface\ItemInterface; use GildedRose\Items\Interface\ItemInterface;
use GildedRose\Items\NormalItem; use GildedRose\Items\NormalItem;
use GildedRose\Items\SulfurasItem;
class ItemFactory class ItemFactory
{ {
public const AGED_BRIE_ITEM = 'Aged Brie'; private array $itemMappings;
public const BACKSTAGE_ITEM = 'Backstage'; public function __construct(string $configFilePath)
public const SULFURAS_ITEM = 'Sulfuras';
public const CONJURED_ITEM = 'Conjured';
public static function createItem(Item $item): ItemInterface
{ {
return match (true) { $this->itemMappings = require $configFilePath;
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(), public function createItem(Item $item): ItemInterface
str_contains($item->name, self::CONJURED_ITEM) => new ConjuredItem(), {
default => new NormalItem() 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();
} }
} }

View File

@ -79,7 +79,7 @@ class GildedRoseTest extends TestCase
public function testBackstageIncreaseQualityBy2WhenSellInLessThanOrEqual10(): void public function testBackstageIncreaseQualityBy2WhenSellInLessThanOrEqual10(): void
{ {
$items = [ $items = [
new Item('Backstage', 9, 10), new Item('Backstage passes', 9, 10),
]; ];
$GildedRose = new GildedRose($items); $GildedRose = new GildedRose($items);
$GildedRose->updateQuality(); $GildedRose->updateQuality();
@ -90,7 +90,7 @@ class GildedRoseTest extends TestCase
public function testBackstageIncreaseQualityBy3WhenSellInLessThanOrEqual5(): void public function testBackstageIncreaseQualityBy3WhenSellInLessThanOrEqual5(): void
{ {
$items = [ $items = [
new Item('Backstage', 4, 10), new Item('Backstage passes', 4, 10),
]; ];
$GildedRose = new GildedRose($items); $GildedRose = new GildedRose($items);
$GildedRose->updateQuality(); $GildedRose->updateQuality();
@ -101,7 +101,7 @@ class GildedRoseTest extends TestCase
public function testBackstageSetQualityZeroWhenSellInLessThanOrEqualZero(): void public function testBackstageSetQualityZeroWhenSellInLessThanOrEqualZero(): void
{ {
$items = [ $items = [
new Item('Backstage', 0, 10), new Item('Backstage passes', 0, 10),
]; ];
$GildedRose = new GildedRose($items); $GildedRose = new GildedRose($items);
$GildedRose->updateQuality(); $GildedRose->updateQuality();