diff --git a/.idea/php.xml b/.idea/php.xml index f6159c8..8b29ba5 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -1,4 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/Good.php b/src/Good.php index 2e540c6..f0b6968 100644 --- a/src/Good.php +++ b/src/Good.php @@ -8,8 +8,19 @@ public static function milk(): self return new Milk; } + public static function wool(): self + { + return new Wool; + } + public function isMilk(): bool { return false; } + + + public function isWool(): bool + { + return false; + } } diff --git a/src/Market.php b/src/Market.php index 3d43053..2de72d9 100644 --- a/src/Market.php +++ b/src/Market.php @@ -3,16 +3,25 @@ final class Market { + /** @var PriceList[] */ + private $priceLists = []; + + public function __construct() + { + $this->priceLists[Milk::class] = PriceListBuilder::milkPrices(); + $this->priceLists[Wool::class] = PriceListBuilder::woolPrices(); + } + + public function priceFor(Good $good): Pound { - return new Pound(5); + return $this->priceLists[get_class($good)]->current(); } public function sellTo(Offer $offer): Pound { - return new Pound( - $offer->amount()->amount() * - $this->priceFor($offer->good())->amount() - ); + $profit = $this->priceLists[get_class($offer->good())]->current()->multiply($offer->amount()); + $this->priceLists[get_class($offer->good())]->increaseStock($offer->amount()); + return $profit; } } diff --git a/src/Milk.php b/src/Milk.php index 8689abe..7714b98 100644 --- a/src/Milk.php +++ b/src/Milk.php @@ -1,4 +1,5 @@ amount = $unit; + $this->amount = $quantity; $this->good = $good; } diff --git a/src/Pound.php b/src/Pound.php index 1be124e..9313c3f 100644 --- a/src/Pound.php +++ b/src/Pound.php @@ -17,4 +17,9 @@ public function amount(): int { return $this->amount; } + + public function multiply(Quantity $quantity): Pound + { + return new Pound($this->amount * $quantity->amount()); + } } diff --git a/src/PriceList.php b/src/PriceList.php index 8a6a231..3dd91c0 100644 --- a/src/PriceList.php +++ b/src/PriceList.php @@ -30,4 +30,16 @@ public function current(): Pound { return $this->prices[$this->position]; } + + + public function increaseStock(Quantity $quantity): void + { + $this->position = max($this->position - $quantity->amount(), 0); + } + + + public function decreaseStock(Quantity $quantity): void + { + $this->position = min($this->position + $quantity->amount(), count($this->prices)-1); + } } diff --git a/src/PriceListBuilder.php b/src/PriceListBuilder.php index bc0da06..b458c99 100644 --- a/src/PriceListBuilder.php +++ b/src/PriceListBuilder.php @@ -3,7 +3,7 @@ final class PriceListBuilder { - public function milkPrices(): PriceList + public static function milkPrices(): PriceList { return PriceList::fromList( new Pound(3), @@ -18,4 +18,20 @@ public function milkPrices(): PriceList new Pound(8) ); } + + public static function woolPrices(): PriceList + { + return PriceList::fromList( + new Pound(3), + new Pound(3), + new Pound(4), + new Pound(4), + new Pound(5), + new Pound(5), + new Pound(6), + new Pound(6), + new Pound(7), + new Pound(8 ) + ); + } } diff --git a/src/Wool.php b/src/Wool.php new file mode 100644 index 0000000..f0b5afe --- /dev/null +++ b/src/Wool.php @@ -0,0 +1,12 @@ + '/Pound.php', 'clansofcaledonia\\pricelist' => '/PriceList.php', 'clansofcaledonia\\pricelistbuilder' => '/PriceListBuilder.php', - 'clansofcaledonia\\quantity' => '/Quantity.php' + 'clansofcaledonia\\quantity' => '/Quantity.php', + 'clansofcaledonia\\wool' => '/Wool.php' ); } $cn = strtolower($class); diff --git a/tests/GoodTest.php b/tests/GoodTest.php index f44ff47..0b777fd 100644 --- a/tests/GoodTest.php +++ b/tests/GoodTest.php @@ -6,6 +6,7 @@ /** * @covers \ClansOfCaledonia\Good * @covers \ClansOfCaledonia\Milk + * @covers \ClansOfCaledonia\Wool */ final class GoodTest extends TestCase { @@ -14,5 +15,15 @@ public function testCanBeMilk(): void $milk = Good::milk(); $this->assertTrue($milk->isMilk()); + $this->assertFalse($milk->isWool()); + } + + + public function testCanBeWool(): void + { + $wool = Good::wool(); + + $this->assertTrue($wool->isWool()); + $this->assertFalse($wool->isMilk()); } } diff --git a/tests/MarketTest.php b/tests/MarketTest.php index 466685d..4332121 100644 --- a/tests/MarketTest.php +++ b/tests/MarketTest.php @@ -5,19 +5,25 @@ /** * @covers \ClansOfCaledonia\Market + * @covers \ClansOfCaledonia\PriceListBuilder * * @uses \ClansOfCaledonia\Pound * @uses \ClansOfCaledonia\Good * @uses \ClansOfCaledonia\Offer * @uses \ClansOfCaledonia\Quantity + * @uses \ClansOfCaledonia\PriceList */ final class MarketTest extends TestCase { - public function testMilkCosts5PoundsInitially(): void + + /** + * @dataProvider initialGoodProvider + */ + public function testInitiallyGoodCost(Good $good, int $amount): void { $market = new Market; - $this->assertEquals(new Pound(5), $market->priceFor(Good::milk())); + $this->assertEquals(new Pound($amount), $market->priceFor($good)); } public function testMilkCanBeSoldToTheMarket(): Market @@ -43,4 +49,37 @@ public function testSellingMilkToTheMarketReducesMilkPrice(Market $market): void { $this->assertEquals(new Pound(4), $market->priceFor(Good::milk())); } + + public function testWoolCanBeSoldToTheMarket(): Market + { + $market = new Market; + + $payment = $market->sellTo( + new Offer( + new Quantity(1), + Good::wool() + ) + ); + + $this->assertEquals(new Pound(4), $payment); + + return $market; + } + + /** + * @depends testWoolCanBeSoldToTheMarket + */ + public function testSellingWoolToTheMarketReducesWoolPrice(Market $market): void + { + $this->assertEquals(new Pound(4), $market->priceFor(Good::wool())); + } + + + public function initialGoodProvider() + { + return [ + 'initialMilkCosts5Pound' => [Good::milk(), 5], + 'initialWoolCosts4Pound' => [Good::wool(), 4], + ]; + } } diff --git a/tests/PoundTest.php b/tests/PoundTest.php index 3d3ec6d..af87e4b 100644 --- a/tests/PoundTest.php +++ b/tests/PoundTest.php @@ -5,6 +5,8 @@ /** * @covers \ClansOfCaledonia\Pound + * + * @uses \ClansOfCaledonia\Quantity */ final class PoundTest extends TestCase { @@ -16,4 +18,25 @@ public function testHasAmount(): void $this->assertSame($amount, $p->amount()); } + + + /** + * @dataProvider multiplyDataProvider + */ + public function testPoundCanMultiply(int $amount, Quantity $factor, int $expected) + { + $p = new Pound($amount); + + $this->assertSame($expected, $p->multiply($factor)->amount()); + } + + + public function multiplyDataProvider() + { + return [ + [ 5, new Quantity(2), 10], + [ 1, new Quantity(100), 100], + [ -3, new Quantity(4), -12], + ]; + } } diff --git a/tests/PriceListTest.php b/tests/PriceListTest.php index aba7abb..01b2d8a 100644 --- a/tests/PriceListTest.php +++ b/tests/PriceListTest.php @@ -1,4 +1,5 @@ assertEquals(new Pound(4), $prices->current()); } + + public function testInreaseStock() + { + $prices = $this->priceList(); + $this->assertEquals(new Pound(4), $prices->current()); + $prices->increaseStock(new Quantity(1)); + $this->assertEquals(new Pound(3), $prices->current()); + $prices->increaseStock(new Quantity(2)); + $this->assertEquals(new Pound(1), $prices->current()); + $prices->increaseStock(new Quantity(1)); + $this->assertEquals(new Pound(1), $prices->current()); + } + + public function testDecreaseStock(): void + { + $prices = $this->priceList(); + $this->assertEquals(new Pound(4), $prices->current()); + $prices->decreaseStock(new Quantity(1)); + $this->assertEquals(new Pound(5), $prices->current()); + $prices->decreaseStock(new Quantity(2)); + $this->assertEquals(new Pound(7), $prices->current()); + $prices->decreaseStock(new Quantity(1)); + $this->assertEquals(new Pound(8), $prices->current()); + $prices->decreaseStock(new Quantity(2)); + $this->assertEquals(new Pound(10), $prices->current()); + $prices->decreaseStock(new Quantity(1)); + $this->assertEquals(new Pound(10), $prices->current()); + } + + public function priceList(): PriceList + { + return PriceList::fromList( + new Pound(1), + new Pound(2), + new Pound(3), + new Pound(4), + new Pound(5), + new Pound(6), + new Pound(7), + new Pound(8), + new Pound(9), + new Pound(10) + ); + } } diff --git a/tests/QuantityTest.php b/tests/QuantityTest.php index a705965..a9bf0c1 100644 --- a/tests/QuantityTest.php +++ b/tests/QuantityTest.php @@ -10,9 +10,9 @@ final class QuantityTest extends TestCase { public function testHasAmount(): void { - $unit = new Quantity(1); + $quantity = new Quantity(1); - $this->assertSame(1, $unit->amount()); + $this->assertSame(1, $quantity->amount()); } /**