diff --git a/.travis.yml b/.travis.yml
index f98ed8d..edfae32 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,9 @@ language: php
sudo: false
php:
- - 7.0
- 7.1
- 7.2
+ - 7.3
matrix:
fast_finish: true
diff --git a/Behavioral/ChainOfResponsibilities/Tests/ChainTest.php b/Behavioral/ChainOfResponsibilities/Tests/ChainTest.php
index c61f1fb..e9d4cb4 100644
--- a/Behavioral/ChainOfResponsibilities/Tests/ChainTest.php
+++ b/Behavioral/ChainOfResponsibilities/Tests/ChainTest.php
@@ -33,7 +33,7 @@ class ChainTest extends TestCase
->willReturn('GET');
$request->method('getUri')->willReturn($uri);
- $this->assertEquals('Hello In Memory!', $this->chain->handle($request));
+ $this->assertSame('Hello In Memory!', $this->chain->handle($request));
}
public function testCanRequestKeyInSlowStorage()
@@ -47,6 +47,6 @@ class ChainTest extends TestCase
->willReturn('GET');
$request->method('getUri')->willReturn($uri);
- $this->assertEquals('Hello World!', $this->chain->handle($request));
+ $this->assertSame('Hello World!', $this->chain->handle($request));
}
}
diff --git a/Behavioral/Command/Tests/CommandTest.php b/Behavioral/Command/Tests/CommandTest.php
index 2479321..e14e215 100644
--- a/Behavioral/Command/Tests/CommandTest.php
+++ b/Behavioral/Command/Tests/CommandTest.php
@@ -16,6 +16,6 @@ class CommandTest extends TestCase
$invoker->setCommand(new HelloCommand($receiver));
$invoker->run();
- $this->assertEquals('Hello World', $receiver->getOutput());
+ $this->assertSame('Hello World', $receiver->getOutput());
}
}
diff --git a/Behavioral/Command/Tests/UndoableCommandTest.php b/Behavioral/Command/Tests/UndoableCommandTest.php
index 9569cb1..b76c17b 100644
--- a/Behavioral/Command/Tests/UndoableCommandTest.php
+++ b/Behavioral/Command/Tests/UndoableCommandTest.php
@@ -17,17 +17,17 @@ class UndoableCommandTest extends TestCase
$invoker->setCommand(new HelloCommand($receiver));
$invoker->run();
- $this->assertEquals('Hello World', $receiver->getOutput());
+ $this->assertSame('Hello World', $receiver->getOutput());
$messageDateCommand = new AddMessageDateCommand($receiver);
$messageDateCommand->execute();
$invoker->run();
- $this->assertEquals("Hello World\nHello World [".date('Y-m-d').']', $receiver->getOutput());
+ $this->assertSame("Hello World\nHello World [".date('Y-m-d').']', $receiver->getOutput());
$messageDateCommand->undo();
$invoker->run();
- $this->assertEquals("Hello World\nHello World [".date('Y-m-d')."]\nHello World", $receiver->getOutput());
+ $this->assertSame("Hello World\nHello World [".date('Y-m-d')."]\nHello World", $receiver->getOutput());
}
}
diff --git a/Behavioral/Iterator/Tests/IteratorTest.php b/Behavioral/Iterator/Tests/IteratorTest.php
index 5a63078..ed8c830 100644
--- a/Behavioral/Iterator/Tests/IteratorTest.php
+++ b/Behavioral/Iterator/Tests/IteratorTest.php
@@ -4,8 +4,6 @@ namespace DesignPatterns\Behavioral\Iterator\Tests;
use DesignPatterns\Behavioral\Iterator\Book;
use DesignPatterns\Behavioral\Iterator\BookList;
-use DesignPatterns\Behavioral\Iterator\BookListIterator;
-use DesignPatterns\Behavioral\Iterator\BookListReverseIterator;
use PHPUnit\Framework\TestCase;
class IteratorTest extends TestCase
@@ -23,7 +21,7 @@ class IteratorTest extends TestCase
$books[] = $book->getAuthorAndTitle();
}
- $this->assertEquals(
+ $this->assertSame(
[
'Learning PHP Design Patterns by William Sanders',
'Professional Php Design Patterns by Aaron Saray',
@@ -48,7 +46,7 @@ class IteratorTest extends TestCase
$books[] = $book->getAuthorAndTitle();
}
- $this->assertEquals(
+ $this->assertSame(
['Professional Php Design Patterns by Aaron Saray'],
$books
);
diff --git a/Behavioral/Memento/Tests/MementoTest.php b/Behavioral/Memento/Tests/MementoTest.php
index 656a58c..8bcd42b 100644
--- a/Behavioral/Memento/Tests/MementoTest.php
+++ b/Behavioral/Memento/Tests/MementoTest.php
@@ -15,18 +15,18 @@ class MementoTest extends TestCase
// open the ticket
$ticket->open();
$openedState = $ticket->getState();
- $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState());
+ $this->assertSame(State::STATE_OPENED, (string) $ticket->getState());
$memento = $ticket->saveToMemento();
// assign the ticket
$ticket->assign();
- $this->assertEquals(State::STATE_ASSIGNED, (string) $ticket->getState());
+ $this->assertSame(State::STATE_ASSIGNED, (string) $ticket->getState());
// now restore to the opened state, but verify that the state object has been cloned for the memento
$ticket->restoreFromMemento($memento);
- $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState());
+ $this->assertSame(State::STATE_OPENED, (string) $ticket->getState());
$this->assertNotSame($openedState, $ticket->getState());
}
}
diff --git a/Behavioral/Specification/uml/Specification.uml b/Behavioral/Specification/uml/Specification.uml
index 003e549..c28b2a1 100644
--- a/Behavioral/Specification/uml/Specification.uml
+++ b/Behavioral/Specification/uml/Specification.uml
@@ -1,55 +1,52 @@
-
-
- PHP
- \DesignPatterns\Behavioral\Specification\AbstractSpecification
-
- \DesignPatterns\Behavioral\Specification\PriceSpecification
- \DesignPatterns\Behavioral\Specification\Not
- \DesignPatterns\Behavioral\Specification\SpecificationInterface
- \DesignPatterns\Behavioral\Specification\Plus
- \DesignPatterns\Behavioral\Specification\AbstractSpecification
- \DesignPatterns\Behavioral\Specification\Either
- \DesignPatterns\Behavioral\Specification\Item
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fields
- Constants
- Constructors
- Methods
-
- private
-
-
+
+
+ PHP
+ \DesignPatterns\Behavioral\Specification\AndSpecification
+
+ \DesignPatterns\Behavioral\Specification\OrSpecification
+ \DesignPatterns\Behavioral\Specification\PriceSpecification
+ \DesignPatterns\Behavioral\Specification\NotSpecification
+ \DesignPatterns\Behavioral\Specification\Item
+ \DesignPatterns\Behavioral\Specification\AndSpecification
+ \DesignPatterns\Behavioral\Specification\SpecificationInterface
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \DesignPatterns\Behavioral\Specification\AndSpecification
+
+
+ Fields
+ Constants
+ Constructors
+ Methods
+
+ private
+
+
diff --git a/Behavioral/Specification/uml/uml.png b/Behavioral/Specification/uml/uml.png
index 0b31e49..1728ac4 100644
Binary files a/Behavioral/Specification/uml/uml.png and b/Behavioral/Specification/uml/uml.png differ
diff --git a/Behavioral/Specification/uml/uml.svg b/Behavioral/Specification/uml/uml.svg
index cfab544..90e205c 100644
--- a/Behavioral/Specification/uml/uml.svg
+++ b/Behavioral/Specification/uml/uml.svg
@@ -1,761 +1,116 @@
-
+
diff --git a/Behavioral/State/ContextOrder.php b/Behavioral/State/ContextOrder.php
deleted file mode 100644
index b05537d..0000000
--- a/Behavioral/State/ContextOrder.php
+++ /dev/null
@@ -1,26 +0,0 @@
-done();
- }
-
- public function getStatus(): string
- {
- return static::$state->getStatus();
- }
-}
diff --git a/Behavioral/State/CreateOrder.php b/Behavioral/State/CreateOrder.php
deleted file mode 100644
index 9c95b61..0000000
--- a/Behavioral/State/CreateOrder.php
+++ /dev/null
@@ -1,16 +0,0 @@
-setStatus('created');
- }
-
- protected function done()
- {
- static::$state = new ShippingOrder();
- }
-}
diff --git a/Behavioral/State/OrderContext.php b/Behavioral/State/OrderContext.php
new file mode 100644
index 0000000..183ea98
--- /dev/null
+++ b/Behavioral/State/OrderContext.php
@@ -0,0 +1,34 @@
+state = new StateCreated();
+
+ return $order;
+ }
+
+ public function setState(State $state)
+ {
+ $this->state = $state;
+ }
+
+ public function proceedToNext()
+ {
+ $this->state->proceedToNext($this);
+ }
+
+ public function toString()
+ {
+ return $this->state->toString();
+ }
+}
diff --git a/Behavioral/State/README.rst b/Behavioral/State/README.rst
index 85a6e76..dbbe5b0 100644
--- a/Behavioral/State/README.rst
+++ b/Behavioral/State/README.rst
@@ -20,27 +20,33 @@ Code
You can also find this code on `GitHub`_
-ContextOrder.php
+OrderContext.php
-.. literalinclude:: ContextOrder.php
+.. literalinclude:: OrderContext.php
:language: php
:linenos:
-StateOrder.php
+State.php
-.. literalinclude:: StateOrder.php
+.. literalinclude:: State.php
:language: php
:linenos:
-ShippingOrder.php
+StateCreated.php
-.. literalinclude:: ShippingOrder.php
+.. literalinclude:: StateCreated.php
:language: php
:linenos:
-CreateOrder.php
+StateShipped.php
-.. literalinclude:: CreateOrder.php
+.. literalinclude:: StateShipped.php
+ :language: php
+ :linenos:
+
+StateDone.php
+
+.. literalinclude:: StateDone.php
:language: php
:linenos:
diff --git a/Behavioral/State/ShippingOrder.php b/Behavioral/State/ShippingOrder.php
deleted file mode 100644
index 06032eb..0000000
--- a/Behavioral/State/ShippingOrder.php
+++ /dev/null
@@ -1,16 +0,0 @@
-setStatus('shipping');
- }
-
- protected function done()
- {
- $this->setStatus('completed');
- }
-}
diff --git a/Behavioral/State/State.php b/Behavioral/State/State.php
new file mode 100644
index 0000000..a6d4218
--- /dev/null
+++ b/Behavioral/State/State.php
@@ -0,0 +1,10 @@
+setState(new StateShipped());
+ }
+
+ public function toString(): string
+ {
+ return 'created';
+ }
+}
diff --git a/Behavioral/State/StateDone.php b/Behavioral/State/StateDone.php
new file mode 100644
index 0000000..355aa7e
--- /dev/null
+++ b/Behavioral/State/StateDone.php
@@ -0,0 +1,16 @@
+details['status'] = $status;
- $this->details['updatedTime'] = time();
- }
-
- protected function getStatus(): string
- {
- return $this->details['status'];
- }
-}
diff --git a/Behavioral/State/StateShipped.php b/Behavioral/State/StateShipped.php
new file mode 100644
index 0000000..f891b00
--- /dev/null
+++ b/Behavioral/State/StateShipped.php
@@ -0,0 +1,16 @@
+setState(new StateDone());
+ }
+
+ public function toString(): string
+ {
+ return 'shipped';
+ }
+}
diff --git a/Behavioral/State/Tests/StateTest.php b/Behavioral/State/Tests/StateTest.php
index 834c02c..73273bc 100644
--- a/Behavioral/State/Tests/StateTest.php
+++ b/Behavioral/State/Tests/StateTest.php
@@ -2,30 +2,42 @@
namespace DesignPatterns\Behavioral\State\Tests;
-use DesignPatterns\Behavioral\State\ContextOrder;
-use DesignPatterns\Behavioral\State\CreateOrder;
+use DesignPatterns\Behavioral\State\OrderContext;
use PHPUnit\Framework\TestCase;
class StateTest extends TestCase
{
- public function testCanShipCreatedOrder()
+ public function testIsCreatedWithStateCreated()
{
- $order = new CreateOrder();
- $contextOrder = new ContextOrder();
- $contextOrder->setState($order);
- $contextOrder->done();
+ $orderContext = OrderContext::create();
- $this->assertEquals('shipping', $contextOrder->getStatus());
+ $this->assertSame('created', $orderContext->toString());
}
- public function testCanCompleteShippedOrder()
+ public function testCanProceedToStateShipped()
{
- $order = new CreateOrder();
- $contextOrder = new ContextOrder();
- $contextOrder->setState($order);
- $contextOrder->done();
- $contextOrder->done();
+ $contextOrder = OrderContext::create();
+ $contextOrder->proceedToNext();
- $this->assertEquals('completed', $contextOrder->getStatus());
+ $this->assertSame('shipped', $contextOrder->toString());
+ }
+
+ public function testCanProceedToStateDone()
+ {
+ $contextOrder = OrderContext::create();
+ $contextOrder->proceedToNext();
+ $contextOrder->proceedToNext();
+
+ $this->assertSame('done', $contextOrder->toString());
+ }
+
+ public function testStateDoneIsTheLastPossibleState()
+ {
+ $contextOrder = OrderContext::create();
+ $contextOrder->proceedToNext();
+ $contextOrder->proceedToNext();
+ $contextOrder->proceedToNext();
+
+ $this->assertSame('done', $contextOrder->toString());
}
}
diff --git a/Behavioral/Strategy/Context.php b/Behavioral/Strategy/Context.php
index 6279f0e..6478492 100644
--- a/Behavioral/Strategy/Context.php
+++ b/Behavioral/Strategy/Context.php
@@ -20,4 +20,4 @@ class Context
return $elements;
}
-}
\ No newline at end of file
+}
diff --git a/Behavioral/Strategy/Tests/StrategyTest.php b/Behavioral/Strategy/Tests/StrategyTest.php
index 0d25c7c..69f4dca 100644
--- a/Behavioral/Strategy/Tests/StrategyTest.php
+++ b/Behavioral/Strategy/Tests/StrategyTest.php
@@ -49,7 +49,7 @@ class StrategyTest extends TestCase
$elements = $obj->executeStrategy($collection);
$firstElement = array_shift($elements);
- $this->assertEquals($expected, $firstElement);
+ $this->assertSame($expected, $firstElement);
}
/**
@@ -64,6 +64,6 @@ class StrategyTest extends TestCase
$elements = $obj->executeStrategy($collection);
$firstElement = array_shift($elements);
- $this->assertEquals($expected, $firstElement);
+ $this->assertSame($expected, $firstElement);
}
}
diff --git a/Behavioral/TemplateMethod/Tests/JourneyTest.php b/Behavioral/TemplateMethod/Tests/JourneyTest.php
index 25bdd51..7fbe673 100644
--- a/Behavioral/TemplateMethod/Tests/JourneyTest.php
+++ b/Behavioral/TemplateMethod/Tests/JourneyTest.php
@@ -12,7 +12,7 @@ class JourneyTest extends TestCase
$beachJourney = new TemplateMethod\BeachJourney();
$beachJourney->takeATrip();
- $this->assertEquals(
+ $this->assertSame(
['Buy a flight ticket', 'Taking the plane', 'Swimming and sun-bathing', 'Taking the plane'],
$beachJourney->getThingsToDo()
);
@@ -20,10 +20,10 @@ class JourneyTest extends TestCase
public function testCanGetOnAJourneyToACity()
{
- $beachJourney = new TemplateMethod\CityJourney();
- $beachJourney->takeATrip();
+ $cityJourney = new TemplateMethod\CityJourney();
+ $cityJourney->takeATrip();
- $this->assertEquals(
+ $this->assertSame(
[
'Buy a flight ticket',
'Taking the plane',
@@ -31,7 +31,7 @@ class JourneyTest extends TestCase
'Buy a gift',
'Taking the plane'
],
- $beachJourney->getThingsToDo()
+ $cityJourney->getThingsToDo()
);
}
}
diff --git a/Creational/AbstractFactory/AbstractFactory.php b/Creational/AbstractFactory/AbstractFactory.php
deleted file mode 100644
index 85bd878..0000000
--- a/Creational/AbstractFactory/AbstractFactory.php
+++ /dev/null
@@ -1,12 +0,0 @@
-skipHeaderLine = $skipHeaderLine;
+ }
+
+ public function parse(string $input): array
+ {
+ $headerWasParsed = false;
+ $parsedLines = [];
+
+ foreach (explode(PHP_EOL, $input) as $line) {
+ if (!$headerWasParsed && $this->skipHeaderLine === self::OPTION_CONTAINS_HEADER) {
+ $headerWasParsed = true;
+ continue;
+ }
+
+ $parsedLines[] = str_getcsv($line);
+ }
+
+ return $parsedLines;
+ }
+}
diff --git a/Creational/AbstractFactory/HtmlFactory.php b/Creational/AbstractFactory/HtmlFactory.php
deleted file mode 100644
index ba44216..0000000
--- a/Creational/AbstractFactory/HtmlFactory.php
+++ /dev/null
@@ -1,11 +0,0 @@
-createText('foobar');
+ $factory = new ParserFactory();
+ $parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_HEADER);
- $this->assertInstanceOf(HtmlText::class, $text);
+ $this->assertInstanceOf(CsvParser::class, $parser);
}
- public function testCanCreateJsonText()
+ public function testCsvParserCanParse()
{
- $factory = new JsonFactory();
- $text = $factory->createText('foobar');
+ $factory = new ParserFactory();
+ $parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_NO_HEADER);
- $this->assertInstanceOf(JsonText::class, $text);
+ $result = $parser->parse("A0,A1,A2\nB0,B1,B2\nC0,C1,C2");
+
+ $this->assertEquals(
+ [
+ ['A0', 'A1', 'A2'],
+ ['B0', 'B1', 'B2'],
+ ['C0', 'C1', 'C2']
+ ],
+ $result
+ );
+ }
+
+ public function testCsvParserCanSkipHeader()
+ {
+ $factory = new ParserFactory();
+ $parser = $factory->createCsvParser(CsvParser::OPTION_CONTAINS_HEADER);
+
+ $result = $parser->parse("A0,A1,A2\nB0,B1,B2\nC0,C1,C2");
+
+ $this->assertEquals(
+ [
+ ['B0', 'B1', 'B2'],
+ ['C0', 'C1', 'C2']
+ ],
+ $result
+ );
+ }
+
+ public function testCanCreateJsonParser()
+ {
+ $factory = new ParserFactory();
+ $parser = $factory->createJsonParser();
+
+ $this->assertInstanceOf(JsonParser::class, $parser);
}
}
diff --git a/Creational/AbstractFactory/Text.php b/Creational/AbstractFactory/Text.php
deleted file mode 100644
index 3573801..0000000
--- a/Creational/AbstractFactory/Text.php
+++ /dev/null
@@ -1,16 +0,0 @@
-text = $text;
- }
-}
diff --git a/Creational/AbstractFactory/uml/AbstractFactory.uml b/Creational/AbstractFactory/uml/AbstractFactory.uml
index 224cc06..bcd4efb 100644
--- a/Creational/AbstractFactory/uml/AbstractFactory.uml
+++ b/Creational/AbstractFactory/uml/AbstractFactory.uml
@@ -1,50 +1,35 @@
PHP
- \DesignPatterns\Creational\AbstractFactory\AbstractFactory
+ \DesignPatterns\Creational\AbstractFactory\CsvParser
- \DesignPatterns\Creational\AbstractFactory\JsonFactory
- \DesignPatterns\Creational\AbstractFactory\AbstractFactory
- \DesignPatterns\Creational\AbstractFactory\HtmlFactory
- \DesignPatterns\Creational\AbstractFactory\JsonText
- \DesignPatterns\Creational\AbstractFactory\HtmlText
- \DesignPatterns\Creational\AbstractFactory\Text
+ \DesignPatterns\Creational\AbstractFactory\Parser
+ \DesignPatterns\Creational\AbstractFactory\ParserFactory
+ \DesignPatterns\Creational\AbstractFactory\JsonParser
+ \DesignPatterns\Creational\AbstractFactory\CsvParser
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
-
-
- \DesignPatterns\Creational\AbstractFactory\AbstractFactory
-
+
+
- Methods
- Constants
Fields
+ Constants
+ Constructors
+ Methods
private
diff --git a/Creational/AbstractFactory/uml/uml.png b/Creational/AbstractFactory/uml/uml.png
index 68d3a8b..fc1db5d 100644
Binary files a/Creational/AbstractFactory/uml/uml.png and b/Creational/AbstractFactory/uml/uml.png differ
diff --git a/Creational/AbstractFactory/uml/uml.svg b/Creational/AbstractFactory/uml/uml.svg
index e7eff24..ecd8021 100644
--- a/Creational/AbstractFactory/uml/uml.svg
+++ b/Creational/AbstractFactory/uml/uml.svg
@@ -1,560 +1,82 @@
-