Permalink
Browse files

Version4

This is the point where I move in a level to actually writing the domain
models designed from behat. Here I use PHPSpec to aid me in the creation
of these models. The benefits of this is that it re-enforces that
approach of designing through the interface, but it also ensures
mistakes are caught and even more, it basically writes the models for
you, with it's excellent interactive spec runner.

Finally (no pun intended) you may spot the use of final in front of the
class names. I had seen this been used but wasn't really sure why, until
I heard @everzet's explanation of it at Symfony Live London 2014 and
subsequently the <a
href="http://ocramius.github.io/blog/when-to-declare-classes-final/"
target="_blank">excellent blog post by @Ocramius on when to use
final</a>. I know see why using final is a must and it has even
subsequently altered how I think when designing classes.
  • Loading branch information...
jenkoian committed Oct 6, 2014
1 parent 9abb0ec commit 5661411bc0a6f5a0b942f9922150b045709be1c3
@@ -0,0 +1,26 @@
<?php
namespace spec\Jenko\House;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class GardenSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedThrough('named', ['front garden']);
}
function it_is_initializable()
{
$this->shouldHaveType('Jenko\House\Garden');
}
function it_should_be_created_with_a_name()
{
$garden = self::named('front garden');
$garden->shouldHaveType('Jenko\House\Garden');
$garden->getName()->shouldEqual('front garden');
}
}
@@ -0,0 +1,40 @@
<?php
namespace spec\Jenko\House;
use Jenko\House\Garden;
use Jenko\House\Room;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class HouseSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedThrough('build', [$this->createLocations()]);
}
function createLocations()
{
$frontGarden = Garden::named('front garden');
$hallway = Room::named('hallway');
$livingRoom = Room::named('living room');
$kitchen = Room::named('kitchen');
return [$frontGarden, $hallway, $livingRoom, $kitchen];
}
function it_is_initializable()
{
$this->shouldHaveType('Jenko\House\House');
}
function it_should_build_with_locations()
{
$locations = $this->createLocations();
$house = self::build($locations);
$house->shouldHaveType('Jenko\House\House');
$house->getLocations()->shouldEqual($locations);
}
}
@@ -0,0 +1,26 @@
<?php
namespace spec\Jenko\House;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class RoomSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedThrough('named', ['hallway']);
}
function it_is_initializable()
{
$this->shouldHaveType('Jenko\House\Room');
}
function it_should_be_created_with_a_name()
{
$garden = self::named('living room');
$garden->shouldHaveType('Jenko\House\Room');
$garden->getName()->shouldEqual('living room');
}
}
View
@@ -0,0 +1,36 @@
<?php
namespace Jenko\House;
final class Garden
{
/**
* @var string
*/
private $name;
/**
* @param string $name
*/
private function __construct($name)
{
$this->name = $name;
}
/**
* @param string $name
* @return Room
*/
public static function named($name)
{
return new Garden($name);
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
View
@@ -0,0 +1,36 @@
<?php
namespace Jenko\House;
final class House
{
/**
* @var array
*/
private $locations;
/**
* @param array $locations
*/
private function __construct(array $locations)
{
$this->locations = $locations;
}
/**
* @param array $locations
* @return House
*/
public static function build(array $locations)
{
return new House($locations);
}
/**
* @return array
*/
public function getLocations()
{
return $this->locations;
}
}
View
@@ -0,0 +1,36 @@
<?php
namespace Jenko\House;
final class Room
{
/**
* @var string
*/
private $name;
/**
* @param string $name
*/
private function __construct($name)
{
$this->name = $name;
}
/**
* @param string $name
* @return Room
*/
public static function named($name)
{
return new Room($name);
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
@@ -3,6 +3,9 @@
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\TableNode;
use Jenko\House\Garden;
use Jenko\House\House;
use Jenko\House\Room;
class HomeOwnerContext implements Context, SnippetAcceptingContext
{
@@ -123,4 +126,22 @@ public function iShouldNotBeAbleToEnterTheRoom($roomName)
return true;
}
}
/**
* @Then I should have room size and adjacent rooms
*/
public function iShouldHaveRoomSizeAndAdjacentRooms()
{
$information = $this->house->whereAmI()->getInformation();
PHPUnit_Framework_Assert::assertArrayHasKey('dimensions', $information);
PHPUnit_Framework_Assert::assertArrayHasKey('exits', $information);
}
/**
* @Given I am in the hallway
*/
public function iAmInTheHallway()
{
$this->iEnterTheRoom('hallway');
}
}

0 comments on commit 5661411

Please sign in to comment.