Permalink
Browse files

Version3

Here I start designing my model. The use of <a
href="http://verraes.net/2014/06/named-constructors-in-php/"
target="_blank">Named
constructors</a> really helps here. It allows me to think purely about
the domain at the interface level. This, for me, is where the true power
of Modelling by Example is. It's BDD and indeed TDD in its truest form.

The fundamental thing to look at, is the language of the model and how
it maps so directly the conversation with the client
`$this->house->enterRoom($room)` etc. It's DDD at play, and is a big
step forward to the `$this->house->setRoom($room)` I may have done in
the past.

It also helps point out gaps in the initial story, considerations that
haven't come up previously and thus making your model more resilient.
  • Loading branch information...
jenkoian committed Oct 6, 2014
1 parent f3fc515 commit 9abb0ec5c8d7918537ba84ed28b999798414aab4
Showing with 124 additions and 7 deletions.
  1. +6 −6 features/navigating-house.feature
  2. +118 −1 tests/contexts/HomeOwnerContext.php
@@ -9,17 +9,13 @@ Feature: Navigating the house
Scenario: Getting room info
Given I am in the "hallway"
When I request room info
Then I should have room size and adjacent rooms
Then I should have dimensions and exits
Scenario: Leaving the house
Given I am in the "hallway"
When I leave through the front door
Then I should be in the "front garden"
Scenario: Entering a room that doesn't exist
Given I am in the "hallway"
Then I should not be able to enter the "made up" room
Scenario: Enter a room that does exist
Given there are the following locations in the house
| name | type | width | height |
@@ -28,4 +24,8 @@ Feature: Navigating the house
| living room | room | 300 | 300 |
| kitchen | room | 300 | 300 |
And I am in the "hallway"
Then I should be able to enter the "living room" room
Then I should be able to enter the "living room" room
Scenario: Entering a room that doesn't exist
Given I am in the "hallway"
Then I should not be able to enter the "made up" room
@@ -2,8 +2,125 @@
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\TableNode;
class HomeOwnerContext implements Context, SnippetAcceptingContext
{
private $house;
}
public function __construct()
{
$frontGarden = Garden::named('front garden');
$hallway = Room::named('hallway');
$livingRoom = Room::named('living room');
$kitchen = Room::named('kitchen');
$locations = [$frontGarden, $hallway, $livingRoom, $kitchen];
$this->house = House::build($locations);
}
/**
* @Given I am in the :location
*/
public function iAmInThe($location)
{
$this->house->setLocation($location);
}
/**
* @When I enter through the front door
*/
public function iEnterThroughTheFrontDoor()
{
$this->iEnterTheRoom('hallway');
}
/**
* @Then I should be in the :location
*/
public function iShouldBeInThe($location)
{
$whereAmI = $this->house->whereAmI();
PHPUnit_Framework_Assert::assertEquals(Room::named($location), $whereAmI);
}
/**
* @When I request room info
*/
public function iRequestRoomInfo()
{
$this->house->whereAmI()->getInformation();
}
/**
* @Then I should have dimensions and exits
*/
public function iShouldHaveDimensionsAndExits()
{
$information = $this->house->whereAmI()->getInformation();
PHPUnit_Framework_Assert::assertArrayHasKey('dimensions', $information);
PHPUnit_Framework_Assert::assertArrayHasKey('exits', $information);
}
/**
* @When I leave through the front door
*/
public function iLeaveThroughTheFrontDoor()
{
$frontGarden = Garden::named('front garden');
$this->house->exitRoom($frontGarden);
}
/**
* @Given there are the following locations in the house
*/
public function thereAreTheFollowingLocationsInTheHouse(TableNode $table)
{
$locations = [];
foreach ($table->getHash() as $data) {
$dimensions = Dimensions::fromWidthAndHeight($data['width'], $data['height']);
if ('garden' === $data['type']) {
$location = Garden::named($data['name']);
$location->setDimensions($dimensions);
} else {
$location = Room::named($data['name']);
$location->setDimensions($dimensions);
}
$locations[] = $location;
}
$this->house = House::buildHouse($locations);
}
/**
* @Then I should be able to enter the :roomName room
*/
public function iShouldBeAbleToEnterTheRoom($roomName)
{
$this->iEnterTheRoom($roomName);
}
/**
* @When I enter the :roomName room
*/
public function iEnterTheRoom($roomName)
{
$room = Room::named($roomName);
$this->house->enterRoom($room);
}
/**
* @Then I should not be able to enter the :roomName room
*/
public function iShouldNotBeAbleToEnterTheRoom($roomName)
{
try {
$this->iEnterTheRoom($roomName);
} catch (RoomDoesNotExistException $e) {
return true;
}
}
}

0 comments on commit 9abb0ec

Please sign in to comment.