Upgrade: Symfony2 Ecommerce Strikes Again

Upgraded!

Yes Lean Book on Symfony2 Ecommerce is growing chapters and being written in 3 languages, integrating payment gateway advanced, so lots of work!

Screen Shot 2013-08-30 at 5.56.47 AM

The site will soon have more features proving that Ecommerce, even though not for the heart fainted can be made easy for those who seek :), and i will make sure it gets more easier hopefully soon!

Please spread the word, tweet, comment, point your friends to the book and support me so that i can keep working and writing on this journey!

Undeservedly glad,

your friend @cordoval

Porting your PHPUnit legacy test suite to PhpSpec Adventures: Part VI

Previous episodes:

Sharing some experiences while moving a phpunit test suite over to PhpSpec.

– The treatment of abstract classes, say in PhpSpec I find hard to describe an abstract class because it cannot be properly instantiated. There was one class Email.php in the namshi/notificator library that I had to skip. The class was abstract, however the implementation of the class which was a class Emailvision.php which extended this class was describable so I think it was sufficient to keep only that spec and not worrying about describing abstract classes.

– There were several classes that had `shouldHandle`, mainly all the handler implementations. This caused a bug in PhpSpec that prevented me from utilizing the methods to spec the object. PhpSpec thought I was trying to call a matcher directly on the object and therefore there were no matchers. I tried several workarounds however my friend Leszek @l3l0 suggested me to use `getWrappedObject` method. So I did and since I did not want to use phpunit asserts just for this temporary situation I just created if statements around the actual results of the invocation of these methods.

<?php
 
    // ...
 
    function it_should_handle_emailvision_notifications_only()
    {
        $emailvisionNotification = new EmailvisionNotification('a', 'b', []);
        $otherNotification = new EmailNotification('a', []);
        if (!$this->getWrappedObject()->shouldHandle($emailvisionNotification)) {
            throw new \Exception('fails');
        }
        if ($this->getWrappedObject()->shouldHandle($otherNotification)) {
            throw new \Exception('fails');
        }
    }

– On test suite migration the best feeling is that after it is finished every other new feature would become pluggable and that we would have a green state from where to start. And that we would use BDD all the way and have 100% coverage by methodology. In the way of exporting the suite I found some code, mainly getters and setters, which were not very clear why they were created since there was no need for the use cases described in the tests. In BDD we don’t write code that is not described so in these cases it is preferable to remove the unused getters and setters in each case and rely on utilization within the class on the direct properties.

– The usage of the gruntjs trick for running the tests continuously is an amazing help. There is a problem however when you describe a class or an interface which is not created and the test suite gets run but because grunt runs without interaction there is no way to type yes or no back to the console so one has to kill the watcher, run manually to prompt for generation of the class, and then run the grunt watcher again. Because it was an already written library the instances of this issue were minimum; however, I noticed it could have been worst should the number of creations of new classes were high.

– PhpSpec forces you to correct some problems in the library, such as avoiding breaking Demeter’s law, encourages encapsulation and injecting the right collaborators, improves the readability of tests via its snake case definition of spec methods, focuses on use cases rather than on testing, avoids boilerplate code, makes sure it is a unitary focus on the SUS, and overall helps defining and exploring the architecture.

– Using Phpunit with Prophecy library is better than just using Phpunit, however, using PhpSpec which has already integrated Prophecy is far better with less boilerplate code. After transferring a test suite to a spec suite, your brain starts to change, you start thinking on use cases rather than details on the implementation, and your mind gets ready to architect rather than to monkey code.

Please share your ideas on the comments below.
I will be looking at writing a bundle for the library using PhpSpec from the beginning.

If you would like to say thanks by supporting me please get the Lean Book on Symofony2 Ecommerce thanks!

undeservedly thankful, your friend @cordoval

PHPSpec It Like A Junior: Part V

Previous episodes:

Screen Shot 2013-08-24 at 4.49.31 AM

As I promised sometime and delivering now even though late, here is the Part V of the series.

So I got into phpspecking this Notificator library with this PR. In the way I wanted to have autocomplete for the method matchers so I ended up bootstrapping this stub library called cordoval/phpspec-stubs

Just add it to your composer.json:

//...
    "require-dev": {
        "phpspec/phpspec": "dev-master",     
        "cordoval/phpspec-stubs": "dev-master"
    },

And run:

composer update cordoval/phpspec-stubs

Then you need only one more step to use these amazing stubs library:

<?php
namespace spec\Namshi\Notificator\Notification\Email;
 
use Cordoval\PhpSpec\ObjectBehaviorComplete;
 
class EmailNotificationSpec extends ObjectBehaviorComplete
{
    function let()
    {
        $this->beConstructedWith('recipient', []);
    }
 
    function it_is_initializable()
    {
        $this->shouldHaveType('Namshi\Notificator\Notification\Email\EmailNotification');
        $this->shouldHaveType('Namshi\Notificator\Notification');
        $this->shouldImplement('Namshi\Notificator\Notification\Email\EmailNotificationInterface');
    }
}

It will autocomplete the methods in PHPStorm. Now the library has a growing number of methods so your PR’s are welcome. I will try to explore how to generate the “`ObjectBehaviorComplete“` class from a command in the future. But for now enjoy your free stubs for autocompletion!

Last but not least, take a look at the book I am writing Lean Book on Symfony2 Ecommerce http://pilotci.com

More quality surprises coming in these blog posts but more in the book too!

Symfony2 Checks For Composer and Database

A friend of mine @markbadolato got me into using this git post-checkout hook:

https://gist.github.com/mbadolato/5869968
update: he also made a blog post with more explanations.

#!/bin/bash
 
# Put this file at: .git/hooks/post-checkout
# and make it executable
# You can install it system wide too, see http://stackoverflow.com/a/2293578/685587
 
PREV_COMMIT=$1
POST_COMMIT=$2
 
NOCOLOR='\x1B[0m'
REDCOLOR='\x1B[37;41m'
 
if [[ -f composer.lock ]]; then
    DIFF=`git diff --shortstat $PREV_COMMIT..$POST_COMMIT composer.lock`
    if [[ $DIFF != "" ]]; then
        echo -e "$REDCOLOR composer.lock has changed. You must run composer install$NOCOLOR"
    fi
fi
 
if [[ -f app/console ]]; then
    php app/console doctrine:schema:update --dump-sql
fi

Mind you need to do it as a post-checkout hook.

I added the doctrine part so that it also tells you if you need to run migrations or update the schema.

All credits to its author. I only added the last part. And I adapted it from @markbadolato polished version.

Enjoy and visit us also at the shop if you want to thank for sharing http://pilotci.com!

Grunt.js + Symfony2 Big Brother Watches Your PHPSpec Descriptions

Straight to the point!

Drop a couple of files into your Symfony2’s project directory or any php library:

Gruntfile.js

module.exports = function (grunt) {
    grunt.initConfig({
        shell: {
            tests: {
                command: [
                    'clear',
                    'vendor/bin/phpspec run -n --ansi'
                ].join('&&'),
                options: {
                    stdout: true
                }
            }
        },
        watch: {
            tests: {
                files: ['{lib,src,spec}/**/*.php'],
                tasks: ['shell:tests']
            }
        }
    });
 
    // plugins
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-shell');
 
    // tasks
    grunt.registerTask('tests', ['shell:tests', 'watch:tests']);
};

and

package.json

{
    "devDependencies": {
        "grunt": "~0.4.1",
        "grunt-contrib-watch": "~0.5.1",
        "grunt-shell": "~0.3.1",
        "grunt-cli": "~0.1.9"
    }
}

Then proceed to install the dependencies above similar to composer like a pro:

brew install node
npm install

Then for your commodity create a file like:

~ cat ./dev
#!/bin/bash
node_modules/.bin/grunt tests

and simply run:

./dev

And try to change a file in your folders src, lib or spec and you will see the watcher in action.

Now start doing PRs to your favourite repos with these changes and give the reference url if you want :)!

I credit @chadrien for helping me get up to speed with this technique.

You are welcome to say thanks buying http://pilotci.com The Lean Book on Symfony2 Ecommerce !

With the support I will buy a license of keynote to present my talk in Argentina in this conference:

http://www.phpconference.com.ar/schedule/?lang=en

undeservingly thankful, your friend

@cordoval