mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-14 22:21:20 +00:00
MP - рефакторинг обработки дефолтного товара
This commit is contained in:
parent
e4946ea50e
commit
50b98c1b98
5
php/description.txt
Normal file
5
php/description.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
на мой взгляд задача описана не полностью и на реальном проекте я бы такую задачу не брал в работу.
|
||||||
|
по-моему мнению ее следовало бы дополнительно обсудить с бизнес аналитиком.
|
||||||
|
как минимум вопросы
|
||||||
|
- поэтому у него нет срока хранения - что значит нет срока? ноль? если уже какой-то был указан обнулить или просто не учитывать?
|
||||||
|
- качество увеличивается пропорционально возрасту - тут по идее нужен какой-то коэффицинт пропорционалности
|
||||||
@ -4,6 +4,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace GildedRose;
|
namespace GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Handlers\AgedBrieItemHandler;
|
||||||
|
use GildedRose\Handlers\BackStageItemHandler;
|
||||||
|
use GildedRose\Handlers\ConjuredItemHandler;
|
||||||
|
use GildedRose\Handlers\DefaultItemHandler;
|
||||||
|
use GildedRose\Handlers\SulfarusItemHandler;
|
||||||
|
|
||||||
final class GildedRose
|
final class GildedRose
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -14,7 +20,7 @@ final class GildedRose
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateQuality(): void
|
public function updateQuality(): array
|
||||||
{
|
{
|
||||||
foreach ($this->items as $item) {
|
foreach ($this->items as $item) {
|
||||||
if ($item->name != 'Aged Brie' and $item->name != 'Backstage passes to a TAFKAL80ETC concert') {
|
if ($item->name != 'Aged Brie' and $item->name != 'Backstage passes to a TAFKAL80ETC concert') {
|
||||||
@ -63,5 +69,26 @@ final class GildedRose
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateQuality1(): array
|
||||||
|
{
|
||||||
|
foreach ($this->items as $item) {
|
||||||
|
$handler = match ($item->name) {
|
||||||
|
'Aged Brie' => new AgedBrieItemHandler(),
|
||||||
|
'Sulfuras, Hand of Ragnaros' => new SulfarusItemHandler(),
|
||||||
|
'Backstage passes to a TAFKAL80ETC concert' => new BackStageItemHandler(),
|
||||||
|
'Conjured Mana Cake' => new ConjuredItemHandler(),
|
||||||
|
default => new DefaultItemHandler(),
|
||||||
|
};
|
||||||
|
|
||||||
|
$handler->handle($item);
|
||||||
|
|
||||||
|
unset($handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
php/src/Handlers/AgedBrieItemHandler.php
Normal file
28
php/src/Handlers/AgedBrieItemHandler.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class AgedBrieItemHandler implements ItemHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sellIn = $this->changeSallIn($item->sellIn);
|
||||||
|
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function changeQuality(int $quality, int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $quality;
|
||||||
|
}
|
||||||
|
private function changeSallIn(int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $sallIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
php/src/Handlers/BackStageItemHandler.php
Normal file
28
php/src/Handlers/BackStageItemHandler.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class BackStageItemHandler implements ItemHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sellIn = $this->changeSallIn($item->sellIn);
|
||||||
|
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function changeQuality(int $quality, int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $quality;
|
||||||
|
}
|
||||||
|
private function changeSallIn(int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $sallIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
php/src/Handlers/ConjuredItemHandler.php
Normal file
28
php/src/Handlers/ConjuredItemHandler.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class ConjuredItemHandler implements ItemHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sellIn = $this->changeSallIn($item->sellIn);
|
||||||
|
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function changeQuality(int $quality, int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $quality;
|
||||||
|
}
|
||||||
|
private function changeSallIn(int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $sallIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
php/src/Handlers/DefaultItemHandler.php
Normal file
40
php/src/Handlers/DefaultItemHandler.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class DefaultItemHandler implements ItemHandlerInterface
|
||||||
|
{
|
||||||
|
private const KOEF_DECREASE = 2;
|
||||||
|
|
||||||
|
public function handle(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sellIn = $this->changeSallIn($item->sellIn);
|
||||||
|
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function changeQuality(int $quality, int $sallIn): int
|
||||||
|
{
|
||||||
|
if ($quality === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sallIn === 0) {
|
||||||
|
return $quality - self::KOEF_DECREASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $quality - 1;
|
||||||
|
}
|
||||||
|
private function changeSallIn(int $sallIn): int
|
||||||
|
{
|
||||||
|
if ($sallIn === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sallIn - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
php/src/Handlers/ItemHandlerInterface.php
Normal file
10
php/src/Handlers/ItemHandlerInterface.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
interface ItemHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(Item $item): Item;
|
||||||
|
}
|
||||||
28
php/src/Handlers/SulfarusItemHandler.php
Normal file
28
php/src/Handlers/SulfarusItemHandler.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\Handlers;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class SulfarusItemHandler implements ItemHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sellIn = $this->changeSallIn($item->sellIn);
|
||||||
|
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function changeQuality(int $quality, int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $quality;
|
||||||
|
}
|
||||||
|
private function changeSallIn(int $sallIn): int
|
||||||
|
{
|
||||||
|
//Todo добавить реализацию метода
|
||||||
|
return $sallIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Tests;
|
|
||||||
|
|
||||||
use GildedRose\GildedRose;
|
|
||||||
use GildedRose\Item;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use ApprovalTests\Approvals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
|
|
||||||
*
|
|
||||||
* There are two test cases here with different styles:
|
|
||||||
* <li>"foo" is more similar to the unit test from the 'Java' version
|
|
||||||
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
|
|
||||||
*
|
|
||||||
* I suggest choosing one style to develop and deleting the other.
|
|
||||||
*/
|
|
||||||
class ApprovalTest extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
public function testFoo(): void
|
|
||||||
{
|
|
||||||
$items = [new Item('foo', 0, 0)];
|
|
||||||
$app = new GildedRose($items);
|
|
||||||
$app->updateQuality();
|
|
||||||
|
|
||||||
Approvals::verifyList($items);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testThirtyDays(): void
|
|
||||||
{
|
|
||||||
ob_start();
|
|
||||||
|
|
||||||
$argv = ["", "30"];
|
|
||||||
include(__DIR__.'/../fixtures/texttest_fixture.php');
|
|
||||||
|
|
||||||
$output = ob_get_clean();
|
|
||||||
|
|
||||||
Approvals::approveString($output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
55
php/tests/DefaultItemTest.php
Normal file
55
php/tests/DefaultItemTest.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
use GildedRose\GildedRose;
|
||||||
|
use GildedRose\Item;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
|
||||||
|
*
|
||||||
|
* There are two test cases here with different styles:
|
||||||
|
* <li>"foo" is more similar to the unit test from the 'Java' version
|
||||||
|
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
|
||||||
|
*
|
||||||
|
* I suggest choosing one style to develop and deleting the other.
|
||||||
|
*/
|
||||||
|
class DefaultItemTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDefaultChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', 1, 1)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', 0, 0)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultAfterSallInChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', -1, 6)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', -2, 4)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaulWithZeroSallInChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', 0, 10)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', -1, 8)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Tests;
|
|
||||||
|
|
||||||
use GildedRose\GildedRose;
|
|
||||||
use GildedRose\Item;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
class GildedRoseTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testFoo(): void
|
|
||||||
{
|
|
||||||
$items = [new Item('foo', 0, 0)];
|
|
||||||
$gildedRose = new GildedRose($items);
|
|
||||||
$gildedRose->updateQuality();
|
|
||||||
$this->assertSame('fixme', $items[0]->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
php/tests/beforeRefactoring/DefaultItemTest.php
Normal file
56
php/tests/beforeRefactoring/DefaultItemTest.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\beforeRefactoring;
|
||||||
|
|
||||||
|
use GildedRose\GildedRose;
|
||||||
|
use GildedRose\Item;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ApprovalTests\Approvals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
|
||||||
|
*
|
||||||
|
* There are two test cases here with different styles:
|
||||||
|
* <li>"foo" is more similar to the unit test from the 'Java' version
|
||||||
|
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
|
||||||
|
*
|
||||||
|
* I suggest choosing one style to develop and deleting the other.
|
||||||
|
*/
|
||||||
|
class DefaultItemTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDefaultChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', 1, 1)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', 0, 0)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultAfterSallInChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', -1, 6)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', -2, 4)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaulWithZeroSallInChange(): void
|
||||||
|
{
|
||||||
|
$items = [new Item('default', 0, 10)];
|
||||||
|
$app = new GildedRose($items);
|
||||||
|
$actualAItems = $app->updateQuality();
|
||||||
|
|
||||||
|
$itemsExpected = [new Item('default', -1, 8)];
|
||||||
|
|
||||||
|
Assert::assertEquals($itemsExpected, $actualAItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user