mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-15 22:41:30 +00:00
Test is completed
This commit is contained in:
parent
864f34ccc1
commit
4ebd9c7bf4
@ -6,6 +6,7 @@ require_once __DIR__ . '/../vendor/autoload.php';
|
|||||||
|
|
||||||
use GildedRose\GildedRose;
|
use GildedRose\GildedRose;
|
||||||
use GildedRose\Item;
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolver;
|
||||||
|
|
||||||
echo 'OMGHAI!' . PHP_EOL;
|
echo 'OMGHAI!' . PHP_EOL;
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ $items = [
|
|||||||
new Item('Conjured Mana Cake', 3, 6),
|
new Item('Conjured Mana Cake', 3, 6),
|
||||||
];
|
];
|
||||||
|
|
||||||
$app = new GildedRose($items);
|
$app = new GildedRose($items, new StrategyResolver());
|
||||||
|
|
||||||
$days = 2;
|
$days = 2;
|
||||||
if (count($argv) > 1) {
|
if (count($argv) > 1) {
|
||||||
|
|||||||
@ -11,59 +11,25 @@ final class GildedRose
|
|||||||
*/
|
*/
|
||||||
private $items;
|
private $items;
|
||||||
|
|
||||||
public function __construct(array $items)
|
/**
|
||||||
|
* @var StrategyResolverInterface
|
||||||
|
*/
|
||||||
|
private $strategyResolver;
|
||||||
|
|
||||||
|
public function __construct(array $items, StrategyResolverInterface $strategyResolver)
|
||||||
{
|
{
|
||||||
$this->items = $items;
|
$this->items = $items;
|
||||||
|
$this->strategyResolver = $strategyResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateQuality(): void
|
public function updateQuality(): void
|
||||||
{
|
{
|
||||||
foreach ($this->items as $item) {
|
foreach ($this->items as $item) {
|
||||||
if ($item->name != 'Aged Brie' and $item->name != 'Backstage passes to a TAFKAL80ETC concert') {
|
$sellInStrategy = $this->strategyResolver->getSellInStrategy($item);
|
||||||
if ($item->quality > 0) {
|
$sellInStrategy->updateSellIn($item);
|
||||||
if ($item->name != 'Sulfuras, Hand of Ragnaros') {
|
|
||||||
$item->quality = $item->quality - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($item->quality < 50) {
|
|
||||||
$item->quality = $item->quality + 1;
|
|
||||||
if ($item->name == 'Backstage passes to a TAFKAL80ETC concert') {
|
|
||||||
if ($item->sell_in < 11) {
|
|
||||||
if ($item->quality < 50) {
|
|
||||||
$item->quality = $item->quality + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($item->sell_in < 6) {
|
|
||||||
if ($item->quality < 50) {
|
|
||||||
$item->quality = $item->quality + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($item->name != 'Sulfuras, Hand of Ragnaros') {
|
$qualityStrategy = $this->strategyResolver->getQualityStrategy($item);
|
||||||
$item->sell_in = $item->sell_in - 1;
|
$qualityStrategy->updateQuality($item);
|
||||||
}
|
|
||||||
|
|
||||||
if ($item->sell_in < 0) {
|
|
||||||
if ($item->name != 'Aged Brie') {
|
|
||||||
if ($item->name != 'Backstage passes to a TAFKAL80ETC concert') {
|
|
||||||
if ($item->quality > 0) {
|
|
||||||
if ($item->name != 'Sulfuras, Hand of Ragnaros') {
|
|
||||||
$item->quality = $item->quality - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$item->quality = $item->quality - $item->quality;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($item->quality < 50) {
|
|
||||||
$item->quality = $item->quality + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
php/src/QualityStrategy/AgedBrieQualityStrategy.php
Normal file
11
php/src/QualityStrategy/AgedBrieQualityStrategy.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
class AgedBrieQualityStrategy extends BasicQualityStrategy
|
||||||
|
{
|
||||||
|
public function __construct(int $decreasingSpeed = 1)
|
||||||
|
{
|
||||||
|
parent::__construct($decreasingSpeed * -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
php/src/QualityStrategy/BackstagePassesQualityStrategy.php
Normal file
45
php/src/QualityStrategy/BackstagePassesQualityStrategy.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class BackstagePassesQualityStrategy extends BasicQualityStrategy
|
||||||
|
{
|
||||||
|
protected const SELL_IN_LAST_5_DAYS = 5;
|
||||||
|
|
||||||
|
protected const SELL_IN_LAST_10_DAYS = 10;
|
||||||
|
|
||||||
|
protected const DECREASING_SPEED_AT_LAST_5_DAYS = -3;
|
||||||
|
|
||||||
|
protected const DECREASING_SPEED_AT_LAST_10_DAYS = -2;
|
||||||
|
|
||||||
|
public function __construct(int $decreasingSpeed = 1)
|
||||||
|
{
|
||||||
|
parent::__construct($decreasingSpeed * -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCurrentDecreasingSpeed(Item $item): int
|
||||||
|
{
|
||||||
|
$decreasingSpeed = parent::getCurrentDecreasingSpeed($item);
|
||||||
|
|
||||||
|
if ($item->sell_in <= self::SELL_IN_LAST_5_DAYS) {
|
||||||
|
$decreasingSpeed = self::DECREASING_SPEED_AT_LAST_5_DAYS;
|
||||||
|
} elseif ($item->sell_in <= self::SELL_IN_LAST_10_DAYS) {
|
||||||
|
$decreasingSpeed = self::DECREASING_SPEED_AT_LAST_10_DAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $decreasingSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setMinAndMaxQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
if ($item->sell_in < 0) {
|
||||||
|
$item->quality = 0;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::setMinAndMaxQuality($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
php/src/QualityStrategy/BasicQualityStrategy.php
Normal file
54
php/src/QualityStrategy/BasicQualityStrategy.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class BasicQualityStrategy implements QualityStrategyInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $decreasingSpeed;
|
||||||
|
|
||||||
|
public function __construct(int $decreasingSpeed = 1)
|
||||||
|
{
|
||||||
|
$this->decreasingSpeed = $decreasingSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
$item = $this->setInitialQuality($item);
|
||||||
|
|
||||||
|
$decreasingSpeed = $this->getCurrentDecreasingSpeed($item);
|
||||||
|
|
||||||
|
$item->quality -= $decreasingSpeed;
|
||||||
|
|
||||||
|
return $this->setFinalQuality($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCurrentDecreasingSpeed(Item $item): int
|
||||||
|
{
|
||||||
|
return $item->sell_in >= 0
|
||||||
|
? $this->decreasingSpeed
|
||||||
|
: $this->decreasingSpeed * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setInitialQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
return $this->setMinAndMaxQuality($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setFinalQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
return $this->setMinAndMaxQuality($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setMinAndMaxQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->quality = $item->quality > 0 ? $item->quality : 0;
|
||||||
|
$item->quality = $item->quality < self::QUALITY_MAX_LEVEL ? $item->quality : self::QUALITY_MAX_LEVEL;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
php/src/QualityStrategy/ConjuredQualityStrategy.php
Normal file
11
php/src/QualityStrategy/ConjuredQualityStrategy.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
class ConjuredQualityStrategy extends BasicQualityStrategy
|
||||||
|
{
|
||||||
|
public function __construct(int $decreasingSpeed = 1)
|
||||||
|
{
|
||||||
|
parent::__construct($decreasingSpeed * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
php/src/QualityStrategy/QualityStrategyInterface.php
Normal file
12
php/src/QualityStrategy/QualityStrategyInterface.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
interface QualityStrategyInterface
|
||||||
|
{
|
||||||
|
public const QUALITY_MAX_LEVEL = 50;
|
||||||
|
|
||||||
|
public function updateQuality(Item $item): Item;
|
||||||
|
}
|
||||||
18
php/src/QualityStrategy/SulfurasQualityStrategy.php
Normal file
18
php/src/QualityStrategy/SulfurasQualityStrategy.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\QualityStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class SulfurasQualityStrategy extends BasicQualityStrategy
|
||||||
|
{
|
||||||
|
public function __construct(int $decreasingSpeed = 0)
|
||||||
|
{
|
||||||
|
parent::__construct($decreasingSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setMinAndMaxQuality(Item $item): Item
|
||||||
|
{
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
php/src/SellInStrategy/BasicSellInStrategy.php
Normal file
15
php/src/SellInStrategy/BasicSellInStrategy.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\SellInStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class BasicSellInStrategy implements SellInStrategyInterface
|
||||||
|
{
|
||||||
|
public function updateSellIn(Item $item): Item
|
||||||
|
{
|
||||||
|
$item->sell_in--;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
php/src/SellInStrategy/SellInStrategyInterface.php
Normal file
10
php/src/SellInStrategy/SellInStrategyInterface.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\SellInStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
interface SellInStrategyInterface
|
||||||
|
{
|
||||||
|
public function updateSellIn(Item $item): Item;
|
||||||
|
}
|
||||||
13
php/src/SellInStrategy/SulfurasSellInStrategy.php
Normal file
13
php/src/SellInStrategy/SulfurasSellInStrategy.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose\SellInStrategy;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
|
||||||
|
class SulfurasSellInStrategy implements SellInStrategyInterface
|
||||||
|
{
|
||||||
|
public function updateSellIn(Item $item): Item
|
||||||
|
{
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
php/src/StrategyResolver.php
Normal file
46
php/src/StrategyResolver.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\QualityStrategy\AgedBrieQualityStrategy;
|
||||||
|
use GildedRose\QualityStrategy\BackstagePassesQualityStrategy;
|
||||||
|
use GildedRose\QualityStrategy\BasicQualityStrategy;
|
||||||
|
use GildedRose\QualityStrategy\ConjuredQualityStrategy;
|
||||||
|
use GildedRose\QualityStrategy\QualityStrategyInterface;
|
||||||
|
use GildedRose\QualityStrategy\SulfurasQualityStrategy;
|
||||||
|
use GildedRose\SellInStrategy\BasicSellInStrategy;
|
||||||
|
use GildedRose\SellInStrategy\SellInStrategyInterface;
|
||||||
|
use GildedRose\SellInStrategy\SulfurasSellInStrategy;
|
||||||
|
|
||||||
|
class StrategyResolver implements StrategyResolverInterface
|
||||||
|
{
|
||||||
|
public function getSellInStrategy(Item $item): SellInStrategyInterface
|
||||||
|
{
|
||||||
|
switch ($item->name) {
|
||||||
|
case self::ITEM_NAME_SULFURAS:
|
||||||
|
return new SulfurasSellInStrategy();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BasicSellInStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQualityStrategy(Item $item): QualityStrategyInterface
|
||||||
|
{
|
||||||
|
switch ($item->name) {
|
||||||
|
case self::ITEM_NAME_AGED_BRIE:
|
||||||
|
return new AgedBrieQualityStrategy();
|
||||||
|
case self::ITEM_NAME_SULFURAS:
|
||||||
|
return new SulfurasQualityStrategy();
|
||||||
|
case self::ITEM_NAME_BACKSTAGE_PASSES:
|
||||||
|
return new BackstagePassesQualityStrategy();
|
||||||
|
case self::ITEM_NAME_CONJURED:
|
||||||
|
return new ConjuredQualityStrategy();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BasicQualityStrategy();
|
||||||
|
}
|
||||||
|
}
|
||||||
21
php/src/StrategyResolverInterface.php
Normal file
21
php/src/StrategyResolverInterface.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\QualityStrategy\QualityStrategyInterface;
|
||||||
|
use GildedRose\SellInStrategy\SellInStrategyInterface;
|
||||||
|
|
||||||
|
interface StrategyResolverInterface
|
||||||
|
{
|
||||||
|
public const ITEM_NAME_AGED_BRIE = 'Aged Brie';
|
||||||
|
|
||||||
|
public const ITEM_NAME_SULFURAS = 'Sulfuras, Hand of Ragnaros';
|
||||||
|
|
||||||
|
public const ITEM_NAME_BACKSTAGE_PASSES = 'Backstage passes to a TAFKAL80ETC concert';
|
||||||
|
|
||||||
|
public const ITEM_NAME_CONJURED = 'Conjured Mana Cake';
|
||||||
|
|
||||||
|
public function getSellInStrategy(Item $item): SellInStrategyInterface;
|
||||||
|
|
||||||
|
public function getQualityStrategy(Item $item): QualityStrategyInterface;
|
||||||
|
}
|
||||||
172
php/tests/GildedRose/AgedBrieItemTest.php
Normal file
172
php/tests/GildedRose/AgedBrieItemTest.php
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolverInterface;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AgedBrieItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group AgedBrie
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQuality(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-1, qty decrease x2: 10->12' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 0, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -1, 12),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->0, qty: 10->11' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 0, 11),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: -100->1' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 10, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 9, 1),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-11, max qty: 49->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -10, 49),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -11, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->0, max qty: 50->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 1, 50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 0, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, max qty: 105->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 10, 105),
|
||||||
|
],
|
||||||
|
'expected'
|
||||||
|
=> [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 9, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group AgedBrie
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQualityThreeTimes(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-3, qty decrease x2: 10->16' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 0, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -3, 16),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->-2, qty: 10->15' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -2, 15),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, min qty: -100->3' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 10, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 7, 3),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-13, max qty: 45->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -10, 45),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -13, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->-2, max qty: 50->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 1, 50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -2, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, max qty: 105->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 10, 105),
|
||||||
|
],
|
||||||
|
'expected'
|
||||||
|
=> [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 7, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
197
php/tests/GildedRose/BackstagePassesItemTest.php
Normal file
197
php/tests/GildedRose/BackstagePassesItemTest.php
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolverInterface;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class BackstagePassesItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group BackstagePasses
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQuality(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 100->99, qty: 10->11' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 100, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 99, 11),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, qty increase +2: 10->12' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 9, 12),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 5->4, qty increase +3: 10->13' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 5, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 4, 13),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: -100->2' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 9, 2),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'concert is finished, si: 0->-1, min qty: 100->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 0, 100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, -1, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->0, max qty: 50->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 1, 50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 0, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, max qty: 105->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 9, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group BackstagePasses
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQualityThreeTimes(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 100->97, qty: 10->13' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 100, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 97, 13),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, qty increase +2: 10->16' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 7, 16),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 5->2, qty increase +3: 10->19' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 5, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 2, 19),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 7->4, qty increase +2 and +3: 10->18' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 7, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 4, 18),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, min qty: -100->6' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 7, 6),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'concert is finished, si: 2->-1, min qty: 100->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 2, 100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, -1, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 3->0, max qty: 50->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 3, 50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 0, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, max qty: 105->50' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 7, 50),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
181
php/tests/GildedRose/ConjuredItemTest.php
Normal file
181
php/tests/GildedRose/ConjuredItemTest.php
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolverInterface;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class ConjuredItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group ConjuredItem
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQuality(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-1, qty decrease x4: 10->8' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 0, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -1, 6),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->0, qty decrease x2: 10->9' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 0, 8),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: 0->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, 0),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 9, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-11, min qty: 3->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -10, 3),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -11, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: -50->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, -50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 9, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, max qty: 105->48' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, 105),
|
||||||
|
],
|
||||||
|
'expected'
|
||||||
|
=> [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 9, 48),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @skip
|
||||||
|
* @group ConjuredItem
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQualityThreeTimes(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-3, qty decrease x4: 20->8' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 0, 20),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -3, 8),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 3->0, qty decrease x2: 10->4' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 3, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 0, 4),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->-2, qty decrease x2 and x4: 20->10' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 1, 20),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -2, 10),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, min qty: 0->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, 0),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 7, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-13, qty: 11->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -10, 11),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -13, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, min qty: -50->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, -50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 7, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, max qty: 105->44' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 10, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 7, 44),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
169
php/tests/GildedRose/FooItemTest.php
Normal file
169
php/tests/GildedRose/FooItemTest.php
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class FooItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group FooItem
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQuality(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-1, qty decrease x2: 10->8' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 0, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', -1, 8),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->0, qty: 10->9' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 0, 9),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: 0->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 10, 0),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 9, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-11, qty: 1->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', -10, 1),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', -11, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, min qty: -50->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 10, -50),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 9, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->9, max qty: 105->49' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 10, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 9, 49),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group FooItem
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQualityThreeTimes(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'si: 0->-3, qty decrease x2: 10->4' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 0, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', -3, 4),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 3->0, qty: 10->7' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 3, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 0, 7),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 1->-2, qty decrease x1 and x2: 10->5' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', -2, 5),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, min qty: 0->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 10, 0),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 7, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: -10->-13, qty: 1->0' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', -10, 1),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', -13, 0),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'si: 10->7, max qty: 105->47' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item('foo', 10, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item('foo', 7, 47),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
116
php/tests/GildedRose/SulfurasItemTest.php
Normal file
116
php/tests/GildedRose/SulfurasItemTest.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\GildedRose;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolverInterface;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class SulfurasItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group Sulfuras
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQuality(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'sell-in const: -1->-1, qty const: 10->10' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, -1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, -1, 10),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sell-in const: 0->0, min qty: -100->-100' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 0, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 0, -100),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sell-in const: 1->1, max qty: 105->105' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 1, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 1, 105),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group Sulfuras
|
||||||
|
* @dataProvider sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider
|
||||||
|
*
|
||||||
|
* @param Item[] $items
|
||||||
|
* @param Item[] $expectedItems
|
||||||
|
*/
|
||||||
|
public function testSellInAndQualityIsCorrectAfterUpdatedQualityThreeTimes(
|
||||||
|
array $items,
|
||||||
|
array $expectedItems
|
||||||
|
): void {
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItems($expectedItems, $items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sellInAndQualityIsCorrectAfterUpdatedQualityThreeTimesDataProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'sell-in const: -1->-1, qty const: 10->10' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, -1, 10),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, -1, 10),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sell-in const: 0->0, min qty: -100->-100' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 0, -100),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 0, -100),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sell-in const: 1->1, max qty: 105->105' => [
|
||||||
|
'items' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 1, 105),
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'foo' => new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 1, 105),
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,17 +4,92 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
|
|
||||||
use GildedRose\GildedRose;
|
|
||||||
use GildedRose\Item;
|
use GildedRose\Item;
|
||||||
use PHPUnit\Framework\TestCase;
|
use GildedRose\StrategyResolverInterface;
|
||||||
|
|
||||||
class GildedRoseTest extends TestCase
|
class GildedRoseTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testFoo(): void
|
/**
|
||||||
|
* @group GildedRose
|
||||||
|
*/
|
||||||
|
public function testFooItemNameIsTheSameAfterUpdatedQuality(): void
|
||||||
{
|
{
|
||||||
$items = [new Item('foo', 0, 0)];
|
$items = [new Item('foo', 0, 0)];
|
||||||
$gildedRose = new GildedRose($items);
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
$gildedRose->updateQuality();
|
$gildedRose->updateQuality();
|
||||||
$this->assertSame('fixme', $items[0]->name);
|
|
||||||
|
$this->assertSame('foo', $items[0]->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group GildedRose
|
||||||
|
*/
|
||||||
|
public function testDifferentMultiItemsDataIsCorrectAfterUpdatedQuality(): void
|
||||||
|
{
|
||||||
|
$items = [
|
||||||
|
new Item('another foo', 1, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 0, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 777, 777),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 5, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 1, 10),
|
||||||
|
];
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItem(new Item('another foo', 0, 9), $items[0]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -1, 12), $items[1]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 777, 777), $items[2]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 4, 13), $items[3]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 0, 8), $items[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group GildedRose
|
||||||
|
*/
|
||||||
|
public function testSameMultiItemsDataIsCorrectAfterUpdatedQuality(): void
|
||||||
|
{
|
||||||
|
$items = [
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 0, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 1, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 5, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 10, 10),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 100, 10),
|
||||||
|
];
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, -1, 0), $items[0]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 0, 13), $items[1]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 4, 13), $items[2]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 9, 12), $items[3]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 99, 11), $items[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group GildedRose
|
||||||
|
*/
|
||||||
|
public function testDifferentMultiItemsDataIsCorrectAfterUpdatedQualityThirtyTimes(): void
|
||||||
|
{
|
||||||
|
$items = [
|
||||||
|
new Item('another super foo', 20, 60),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, 20, 0),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 777, 777),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 31, 0),
|
||||||
|
new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, 28, 777),
|
||||||
|
];
|
||||||
|
$gildedRose = $this->initializeGlidedRose($items);
|
||||||
|
|
||||||
|
for ($i = 0; $i < 30; $i++) {
|
||||||
|
$gildedRose->updateQuality();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSameItem(new Item('another super foo', -10, 10), $items[0]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_AGED_BRIE, -10, 40), $items[1]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_SULFURAS, 777, 777), $items[2]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_BACKSTAGE_PASSES, 1, 45), $items[3]);
|
||||||
|
$this->assertSameItem(new Item(StrategyResolverInterface::ITEM_NAME_CONJURED, -2, 0), $items[4]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
php/tests/ItemTest.php
Normal file
33
php/tests/ItemTest.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
use GildedRose\Item;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ItemTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group Item
|
||||||
|
*/
|
||||||
|
public function testItemCanBeCreated(): void
|
||||||
|
{
|
||||||
|
$item = new Item('foo', 1, 2);
|
||||||
|
|
||||||
|
$this->assertSame('foo', $item->name);
|
||||||
|
$this->assertSame(1, $item->sell_in);
|
||||||
|
$this->assertSame(2, $item->quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group Item
|
||||||
|
*/
|
||||||
|
public function testItemToStringIsCorrect(): void
|
||||||
|
{
|
||||||
|
$item = new Item('foo', 1, 2);
|
||||||
|
|
||||||
|
$this->assertSame('foo, 1, 2', (string) $item);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
php/tests/TestCase.php
Normal file
41
php/tests/TestCase.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
use GildedRose\GildedRose;
|
||||||
|
use GildedRose\Item;
|
||||||
|
use GildedRose\StrategyResolver;
|
||||||
|
use PHPUnit\Framework\TestCase as CoreTestCase;
|
||||||
|
|
||||||
|
abstract class TestCase extends CoreTestCase
|
||||||
|
{
|
||||||
|
public function assertSameItem(Item $expected, Item $actual, ?string $key = null): void
|
||||||
|
{
|
||||||
|
$actualKey = $key ?? $actual->name;
|
||||||
|
|
||||||
|
$this->assertSame($expected->name, $actual->name, sprintf('Item\'s "name" is not equal to expected; expected: %s, actual: %s', $expected->name, $actual->name));
|
||||||
|
$this->assertSame($expected->sell_in, $actual->sell_in, sprintf('Item\'s "sell in" is not equal to expected; expected: %d, actual: %d, key: %s', $expected->sell_in, $actual->sell_in, $actualKey));
|
||||||
|
$this->assertSame($expected->quality, $actual->quality, sprintf('Item\'s "quality" is not equal to expected; expected: %d, actual: %d, key: %s', $expected->quality, $actual->quality, $actualKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item[] $expected
|
||||||
|
* @param Item[] $actual
|
||||||
|
*/
|
||||||
|
public function assertSameItems(array $expected, array $actual): void
|
||||||
|
{
|
||||||
|
foreach ($actual as $key => $actualItem) {
|
||||||
|
$this->assertSameItem($expected[$key], $actualItem, $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item[] $items
|
||||||
|
*/
|
||||||
|
protected function initializeGlidedRose(array $items): GildedRose
|
||||||
|
{
|
||||||
|
return new GildedRose($items, new StrategyResolver());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
full_name:Gilded Rose Refactoring Kata
|
full_name:Gilded Rose Refactoring Kata
|
||||||
|
|
||||||
# set your preferred editor and diff tool.
|
# set your preferred editor and diff tool.
|
||||||
view_program:subl
|
view_program:nano
|
||||||
diff_program:meld
|
diff_program:diff
|
||||||
|
|
||||||
# Settings for the Python version
|
# Settings for the Python version
|
||||||
#executable:${TEXTTEST_HOME}/python/texttest_fixture.py
|
#executable:${TEXTTEST_HOME}/python/texttest_fixture.py
|
||||||
@ -31,4 +31,8 @@ diff_program:meld
|
|||||||
#executable:${TEXTTEST_HOME}/TypeScript/test/golden-master-text-test.js
|
#executable:${TEXTTEST_HOME}/TypeScript/test/golden-master-text-test.js
|
||||||
#interpreter:node
|
#interpreter:node
|
||||||
|
|
||||||
|
# Settings for the PHP version
|
||||||
|
executable:${TEXTTEST_HOME}/php/texttest_fixture.php
|
||||||
|
interpreter:php
|
||||||
|
|
||||||
filename_convention_scheme:standard
|
filename_convention_scheme:standard
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user