Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 25 additions & 41 deletions src/GildedRose.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
<?php

namespace App;
use App\ItemTypes;

class GildedRose
{
private $items;
private $itemTypes = [];

public function __construct(array $items)
public function __construct(array $items, array $itemTypes = null)
{
$this->items = $items;

if($itemTypes === NULL) {
$itemTypes = [
new ItemTypes\AgedBrieItemTypes,
new ItemTypes\BackstagePassesItemTypes,
new ItemTypes\ConjuredItemTypes,
new ItemTypes\NormalItemTypes,
new ItemTypes\SulfurasItemTypes,
];
}

$this->itemTypes = $itemTypes;
}

public function getItem($which = null)
Expand All @@ -22,48 +36,18 @@ public function getItem($which = null)
public function nextDay()
{
foreach ($this->items as $item) {
if ($item->name != 'Aged Brie' and $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 {
if ($item->quality < 50) {
$item->quality = $item->quality + 1;
if ($item->name == 'Backstage passes to a TAFKAL80ETC concert') {
if ($item->sellIn < 11) {
if ($item->quality < 50) {
$item->quality = $item->quality + 1;
}
}
if ($item->sellIn < 6) {
if ($item->quality < 50) {
$item->quality = $item->quality + 1;
}
}
}
$undeclared = true;
foreach ($this->itemTypes as $type) {
if ($type->itemType($item)) {
$type->nextDay($item);
$undeclared = false;
}
}
if ($item->name != 'Sulfuras, Hand of Ragnaros') {
$item->sellIn = $item->sellIn - 1;
}
if ($item->sellIn < 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;
}
}

if($undeclared) {
throw new \UnexpectedValueException(
sprintf('Item type for %s was not found', $item)
);
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions src/ItemTypes/AgedBrieItemTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Aged Brie Item Types
* All items have a SellIn value which denotes the number of days we have to sell the item
* All items have a Quality value which denotes how valuable the item is
* At the end of each day our system lowers both values for every item

* Once the sell by date has passed, Quality degrades twice as fast
* The Quality of an item is never negative
* "Aged Brie" actually increases in Quality the older it gets
* The Quality of an item is never more than 50
*/

namespace App\ItemTypes;

use App\Item;

class AgedBrieItemTypes
{
public function itemType(Item $item): bool {
return ($item->name == 'Aged Brie');
}

public function nextDay(Item $item) {
// Initial values
$quality = 1;
$sellIn = -1;

$item->sellIn = $item->sellIn + $sellIn;
if($item->sellIn < 1) { $quality = 2; }

// Check that qualty will not exceed 50
if($item->quality + $quality > 50) { $quality = 50 - $item->quality; }
$item->quality = $item->quality + $quality;
}
}
41 changes: 41 additions & 0 deletions src/ItemTypes/BackstagePassesItemTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* Backstage Passes Item Types
* All items have a SellIn value which denotes the number of days we have to sell the item
* All items have a Quality value which denotes how valuable the item is
* At the end of each day our system lowers both values for every item

* The Quality of an item is never more than 50
* "Backstage passes", like aged brie, increases in Quality as its SellIn value approaches;
* Quality increases by 2 when there are 10 days or less and by 3 when there are 5 days or less but
* Quality drops to 0 after the concert
*/

namespace App\ItemTypes;

use App\Item;

class BackstagePassesItemTypes
{
public function itemType(Item $item): bool {
return ($item->name == 'Backstage passes to a TAFKAL80ETC concert');
}

public function nextDay(Item $item) {
// Initial values
$quality = 1;
$sellIn = -1;

// If sell in gets closer to concert quality increases
// After concert, quality is 0
if ($item->sellIn < 1) { $quality = 0 - $item->quality;
} elseif ($item->sellIn <= 5) { $quality = 3;
} elseif ($item->sellIn <= 10) { $quality = 2; }

// Check quality does not exceed 50
if($item->quality + $quality >= 50) { $quality = 50 - $item->quality; }

$item->sellIn = $item->sellIn + $sellIn;
$item->quality = $item->quality + $quality;
}
}
37 changes: 37 additions & 0 deletions src/ItemTypes/ConjuredItemTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Conjured Item Types
* All items have a SellIn value which denotes the number of days we have to sell the item
* All items have a Quality value which denotes how valuable the item is
* At the end of each day our system lowers both values for every item

* Once the sell by date has passed, Quality degrades twice as fast
* The Quality of an item is never negative
* The Quality of an item is never more than 50

* "Conjured" items degrade in Quality twice as fast as normal items
*/

namespace App\ItemTypes;

use App\Item;

class ConjuredItemTypes
{
public function itemType(Item $item): bool {
return ($item->name == 'Conjured Mana Cake');
}

public function nextDay(Item $item) {
// Initial values
$quality = -2;
$sellIn = -1;

$item->sellIn = $item->sellIn + $sellIn;
if($item->sellIn < 1) { $quality = -4; }

// Check quality does not drop below 0
if($item->quality + $quality < 0) { $item->quality = abs($quality); }
$item->quality = $item->quality + $quality;
}
}
35 changes: 35 additions & 0 deletions src/ItemTypes/NormalItemTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
* Normal Item Types
* All items have a SellIn value which denotes the number of days we have to sell the item
* All items have a Quality value which denotes how valuable the item is
* At the end of each day our system lowers both values for every item

* Once the sell by date has passed, Quality degrades twice as fast
* The Quality of an item is never negative
* The Quality of an item is never more than 50
*/

namespace App\ItemTypes;

use App\Item;

class NormalItemTypes
{
public function itemType(Item $item): bool {
return ($item->name == 'normal');
}

public function nextDay(Item $item) {
// initial values
$quality = -1;
$sellIn = -1;

$item->sellIn = $item->sellIn + $sellIn;
if($item->sellIn < 1) { $quality = -2; }

// Check if quality will drop below 0
if($item->quality + $quality < 0) { $item->quality = abs($quality); }
$item->quality = $item->quality + $quality;
}
}
21 changes: 21 additions & 0 deletions src/ItemTypes/SulfurasItemTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Sulfuras Item Types
* "Sulfuras", being a legendary item, never has to be sold or decreases in Quality
*/

namespace App\ItemTypes;

use App\Item;

class SulfurasItemTypes
{
public function itemType(Item $item): bool {
return ($item->name == 'Sulfuras, Hand of Ragnaros');
}

public function nextDay(Item $item) {
// Nothing to see here! Although it something changes..
return true;
}
}
70 changes: 40 additions & 30 deletions tests/Unit/GuildedRoseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,36 +167,46 @@ public function itemProvider(): array
/**
* Conjured items
*/
// 'conjured item before sell date' => [
// 'item' => new Item('Conjured Mana Cake', 10, 10),
// 'expectedQuality' => 8,
// 'expectedSellIn' => 9,
// ],
// 'conjured item at zero quality' => [
// 'item' => new Item('Conjured Mana Cake', 0, 10),
// 'expectedQuality' => 0,
// 'expectedSellIn' => 9,
// ],
// 'conjured item on sell date' => [
// 'item' => new Item('Conjured Mana Cake', 10, 0),
// 'expectedQuality' => 6,
// 'expectedSellIn' => -1,
// ],
// 'conjured item on sell date at zero quality' => [
// 'item' => new Item('Conjured Mana Cake', 0, 0),
// 'expectedQuality' => 0,
// 'expectedSellIn' => -1,
// ],
// 'conjured item after sell date' => [
// 'item' => new Item('Conjured Mana Cake', 10, -10),
// 'expectedQuality' => 6,
// 'expectedSellIn' => -11,
// ],
// 'conjured item after sell date at zero quality' => [
// 'item' => new Item('Conjured Mana Cake', 0, -10),
// 'expectedQuality' => 0,
// 'expectedSellIn' => -11,
// ],
'conjured item at only one quality before sell date' => [
'item' => new Item('Conjured Mana Cake', 1, 10),
'expectedQuality' => 0,
'expectedSellIn' => 9,
],
'conjured item at only one quality after sell date' => [
'item' => new Item('Conjured Mana Cake', 1, -10),
'expectedQuality' => 0,
'expectedSellIn' => -11,
],
'conjured item before sell date' => [
'item' => new Item('Conjured Mana Cake', 10, 10),
'expectedQuality' => 8,
'expectedSellIn' => 9,
],
'conjured item at zero quality' => [
'item' => new Item('Conjured Mana Cake', 0, 10),
'expectedQuality' => 0,
'expectedSellIn' => 9,
],
'conjured item on sell date' => [
'item' => new Item('Conjured Mana Cake', 10, 0),
'expectedQuality' => 6,
'expectedSellIn' => -1,
],
'conjured item on sell date at zero quality' => [
'item' => new Item('Conjured Mana Cake', 0, 0),
'expectedQuality' => 0,
'expectedSellIn' => -1,
],
'conjured item after sell date' => [
'item' => new Item('Conjured Mana Cake', 10, -10),
'expectedQuality' => 6,
'expectedSellIn' => -11,
],
'conjured item after sell date at zero quality' => [
'item' => new Item('Conjured Mana Cake', 0, -10),
'expectedQuality' => 0,
'expectedSellIn' => -11,
],
];
}
}