PHPSpec now running specs on itself with Composer and Travis!

PHPSpec now run its own specification examples on itself with the help of composer and travis.
Composer is the tool to automate dependencies. PHPSpec now has a direct dependency on Mockery/Mockery and when installed through composer on can run the tests with `./scripts/phpspec-composer.php spec/` provided previously we have run `composer.phar install`. If you don’t know how to get the install step take a look at the earlier posts that teach you just that.

In order to have a solid stable version of phpspec that can be well tested or rather specified we used `travis` continuous integration service. With travis we are able to tell it to test phpspec specifications in any version of php and in any pre-configured environment.
This is the PR send that implements all the changes: https://github.com/phpspec/phpspec/pull/59/files.
And here is the output on travis:

PSSMockeryBundle + PHPSpec: The Automation Of Mocking Services Begins!

Let’s say we want to spec a service we are trying to design and we want to use PHPSpec in order to do that.
Our system runs supported by the Symfony2 Components/Framework and according to the rules of the Dependency Injection game we have a client running the application from where we can get all the services of the project the container holds.
Since our service is meant to live within this “Sitz im Leben” or context and would need some interaction with other services we would like to develop the service classes right without leaving at any time this environment.

Welcome to PSSMockeryBundle world. Thanks to Jakub Zalas creator of PSSMockeryBundle, we have something that was meant to solve the problem indicated above by setting up a base class for the container in which we can easily mock any service on the container. Tie this with PHPSpec and you are about to discover a framework setup in which anyone can easily start creating, stubbing, mocking and perfecting their service design for their bundles and craft carefully their dependencies on other services.

<?php
namespace Acme\DemoBundle\Spec\Model;
 
use Symfony\Bundle\FrameworkBundle\Spec\WebSpec;
use Acme\DemoBundle\Model\MyService;
use Twig_Environment;
 
class DescribeMyService extends WebSpec
{
    protected $container;
    protected $client;
    protected $serviceUnderSpec;
 
    public function before()
    {
        $this->client = self::createClient();
        $this->container = $this->client->getContainer();
        $this->serviceUnderSpec = $this->spec(new MyService($this->container));
    }
 
    /**
     * Specking MyService class mocking another service directly related
     */
    public function itShouldGetCreateDirectoryUsingFileSystemServiceFromContainer()
    {
        $filesystemMock = $this->container->mock('filesystem', 'Symfony\Component\Filesystem\Filesystem');
        $filesystemMock->shouldReceive('mkdir')->once()->andReturn(true);
 
        $this->serviceUnderSpec->methodUsingFileSystem()->should->beTrue();
    }
 
    /**
     * Specking MyService method that uses the router service
     * we do not mock the routing but we do mock the Twig_Environment service
     * used by the router
     */
    public function itShouldIndirectlyMockServiceTheRouterDependsOn()
    {
        $twigEnvironmentMock = $this->container->mock('twig','\Twig_Environment');
        $this->serviceUnderSpec->methodUsingRouter()->should->be('/');
    }
}

We first have created a Spec class to speck our new service `MyService` non-existent at this time. The idea is to write one example method at a time. Here we have just gone ahead and written the two we are interested in demoing. Then we proceed to run:

~ phpspec src/Acme/DemoBundle/Spec/

Then we get an error telling us to create the methods on our empty class:

~ phpspec src/Acme/DemoBundle/Spec/
EE
 
Exceptions:
 
  1) Acme\DemoBundle\Spec\Model\MyService should get create directory using file system service from container
     Failure\Exception: $this->runExamples($exampleGroup, $reporter);
     ErrorException: Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Acme\DemoBundle\Model\MyService' does not have a method 'methodUsingFileSystem' in /home/cordoval/sites-2/spec-symfony/vendor/phpspec/src/PHPSpec/Specification/Interceptor/Object.php line 66
 
  2) Acme\DemoBundle\Spec\Model\MyService should run command on client
     Failure\Exception: $this->runExamples($exampleGroup, $reporter);
     ErrorException: Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Acme\DemoBundle\Model\MyService' does not have a method 'methodUsingRouter' in /home/cordoval/sites-2/spec-symfony/vendor/phpspec/src/PHPSpec/Specification/Interceptor/Object.php line 66
 
Finished in 0.052649 seconds
2 examples, 2 exceptions

Next is writing just about enough code on our Service class to make the examples pass. For that we take a look at our `MyService` class:

<?php
namespace Acme\DemoBundle\Model;
 
class MyService
{
    protected $container;
 
    public function __construct($container)
    {
        $this->container = $container;
    }
 
    public function methodUsingFileSystem()
    {
        $filesystem = $this->container->get('filesystem');
        return $filesystem->mkdir('folder1');
    }
 
    public function methodUsingRouter()
    {
        $router = $this->container->get('router');
        return $router->generate('_welcome');
    }
 
    public function checkInternalResponse()
    {
        return true;
    }
}

If you fail to meet the requirements with the writing of your methods, don’t worry PHPSpec is here to guide you make that example green:

~ phpspec src/Acme/DemoBundle/Spec/
.F
 
Failures:
 
  1) Acme\DemoBundle\Spec\Model\MyService should run command on client
     Failure\Error: $this->serviceUnderSpec->methodUsingRouter()->should->be('/somepath');
     expected '/somepath', got '/' (using be())
     # ./src/Acme/DemoBundle/Spec/Model/MyServiceSpec.php:39

Finished in 0.060213 seconds
2 examples, 1 failure

If we get everything right after all we should get:

~ phpspec src/Acme/DemoBundle/Spec/ -fd -c -b
Acme\DemoBundle\Spec\Model\MyService
  should get create directory using file system service from container
  should run command on client
 
Finished in 0.074234 seconds
2 examples

Notice that the examples are simple and are meant for you to see how easy is to use PHPSpec with PSSMockeryBundle within Symfony. We are using the spec-symfony sandbox available in our PHPSpec repos. A lot of effort is being put these days in bringing powerful tools for BDD Spec type of BDD methodology into Symfony2. PHPSpecBundle is the leading bundle along these lines that will have commands to generate the skeletons required to practice good BDD Spec type on Symfony2. BDD Spec and BDD Scenario complement each other so that is why it is important to keep the and use them together because they are more powerful together than separate.

I thank the Lord Jesus Christ for all the help in completing this effort through good friends and very good willing people like Jakub who is an expert in symfony2. We brainstormed once and next day he had the bundle ready. This is a very interesting community accomplishment! bravo!

PHPSpec With Composer: The Short And Simple Story

We wanted to do something more with composer and so we dug further and found composer allows us to really simplify setup of our phpspec projects.
For our main project we create a composer.json on the root folder of our project as follows:

{
    "config": { "bin-dir": "." },
    "require": {
        "php": ">=5.3.2",
        "cordoval/phpspec": "master"
    }
}

What this will do is to install all dependencies so we can work with phpspec and its dependencies and also have a standalone script with the phpspec version of our like. In this case we are using the only version existent at the time of writing which is `master`. The script linking magic is accomplished by the composer.json in phpspec as shown here:

{
    "name": "cordoval/phpspec",
    "description": "PHPSpec: The BDD Specification Library",
    "keywords": ["bdd", "spec", "test"],
    "homepage": "http://phpspec.net",
    "license": "MIT",
    "authors": [
        {
            "name": "PHPSpec Team",
            "homepage": "https://github.com/phpspec/phpspec/contributors"
        }
    ],
    "bin": ["scripts/phpspec-composer.php"],
    "autoload": {
        "psr-0": { "PHPSpec\\": "src/" }
    },
    "require": {
        "php": ">=5.3.2",
        "cordoval/mockery": "master-dev"
    }
}

Of course you don’t need to write this anymore as it is taken care by us.

Instructions for installing the composer are easy. You can either create the composer.json on your personal project or clone this sample project.

git clone git://github.com/cordoval/phpspec-composer.git
cd phpspec-composer

The only thing besides writing the short composer.json above is to install composer. It is simple:

wget http://getcomposer.org/composer.phar
php composer.phar install

If you have composer installed as in a development setup like in a previous post you just do `composer install`.
The last command will install phpspec and all its dependencies included in the phpspec composer.json package specification, that is to say: Mockery.
Now run phpspec with:

~ ./phpspec-composer.php -h
Usage: phpspec (FILE|DIRECTORY) + [options]
 
    -b, --backtrace          Enable full backtrace
    -c, --colour, --color    Enable color in the output
    -e, --example STRING     Run examples whose full nested names include STRING
    -f, --formater FORMATTER Choose a formatter
                              [p]rogress (default - dots)
                              [d]ocumentation (group and example names)
                              [h]tml
                              [j]unit
                              custom formatter class name
    --bootstrap FILENAME     Specify a bootstrap file to run before the tests
    -h, --help               You're looking at it
    --fail-fast              Abort the run on first failure.
    --version                Show version

I thank the Lord Jesus Christ. And the opportunity to have received much help through helpful top guys like Stof, Seldaek, igorw and the developers of composer.