This post is inspired in the development here.
I received great help from jbohn.
So we are starting according to certain scenario.
Feature: Member rents video
As a video-club member
I want to rent a video
So that I can take it away with me and watch it conveniently at home
Feature: Members rents video
As a video-club member
I want to rent a video
So that I can take it away with me and watch it conveniently at home
Scenario: Renting single video from oldies section
Given I am in the "review" page
And the selected video is "Revolution OS"
When I click on "Rent"
Then "£2" is added to my total
Scenario: Renting 3 videos from oldies promotion
Given I am in the "review" page
And "Revolution OS" is selected
And "Blade Runner" is selected
And "The Wall" is selected
When I click on "Rent"
Then "£5" is added to my total
Then we run behat on the file and we are getting:

There is an error with the view already. The reason why we have passed the first step is only because there is already a router for the framework and debugging enabled. However the page that is gotten back by the step is not really a valid page. Once we are at this point we go deeper into the PHPSpec cycle now.
We run the following command because phpspec installed via pear is not the one we are using. Why? Because it does not have knowledge of our updates and also it does not have knowledge of our third party libraries, and also because we want to have full control on what gets loaded. I ran into a redefine issue with function any() conflict between phpunit and hamcrest library.
So here is the command I use:
~/sites-2/FormModelProjectBundle (phpspec) vendor/phpspec/scripts/phpspec.php vendor/bundles/Cordova/Bundle/FormModelBundle/
The `phpspec` script is smart enough to look for the right Spec folder under the bundle and runs the phpspec for IndexSpec.php which is made locatable because of its Spec.php ending.
The resulting output of the previous command is:
E
Exceptions:
1) Cordova\Bundle\FormModelBundle\Specs\views\Index renders the selected video
Failure\Exception: $this->runExamples($exampleGroup, $reporter);
InvalidArgumentException: Unable to find template "CordovaFormModelBundle:index.html.twig".
Finished in 0.134287 seconds
1 example, 1 exception
Notice here that it tells us that we have the wrong path for our template. Which theoretically is unimplemented. The exact error means that we actually need to insert the logical controller name between the ::. This is familiar to sf2 developers. So we do the change and having a lame default controller we have now the following error:
F
Failures:
1) Cordova\Bundle\FormModelBundle\Specs\views\Index renders the selected video
Failure\Error: $output->should->contain('Revolution OS');
expected to contain 'Revolution OS', found no match (using contain())
# ./vendor/bundles/Cordova/Bundle/FormModelBundle/Specs/views/IndexSpec.php:16
Finished in 1.080713 seconds
1 example, 1 failure
Notice: we could have used the generation of a bundle. However since controllers are mostly custom code then there is no point really in using generator unless it is a new action to be placed in a new bundle. So there is no need in sf2 to use a generation command here unless in the case where we are putting things into a new bundle. For all other cases we just copy/paste a controller common template.
Now we know where all our efforts must concentrate, namely here $output->should->contain('Revolution OS');. This means the template rendered has nowhere the label `Revolution OS`. The major problem here is that we need to work on the loading of matchers for Symfony2.
Once we worked on the matcher `Contain` we can run the phpspec command again and we get:
vendor/phpspec/scripts/phpspec.php vendor/bundles/Cordova/Bundle/FormModelBundle/Specs/views/IndexSpec.php
.
Finished in 1.029784 seconds
1 example
Now we are ready to head onto developing the C standing for the controller layer. The controller basically is in charge of doing the dispatching of things. So we need to work again on the Symfony2 controller version of things.
<?php
class DescribeIndex extends View
{
function itRendersTheSelectedVideo()
{
$video = \Mockery::mock(
'Application_Model_Video', array('getName' => 'Revolution OS'));
$output = $this->render('MyBundle:Video:detail.html.twig', array(
'video' => $video,
);
$output->should->contain('Revolution OS');
}
}
<?php
use PHPSpec\Context;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
class View extends Context
{
private $engine;
public function setTemplatingEngine(EngineInterface $engine)
{
$this->engine = $engine;
}
public function spec()
{
$interceptor = call_user_func_array(
array(
'\PHPSpec\Specification\Interceptor\InterceptorFactory',
'create'), func_get_args()
);
$interceptor->addMatchers(array('contain', 'haveSelector'));
return $interceptor;
}
public function render($template, array $templateContext = array())
{
if (is_null($this->engine)) {
throw new \LogicException('No templating engine set.');
}
return $this->spec($this->engine->render($template, $templateContext));
}
}