TDD WordPress project – 02

Nailing down the basics.

Set up

I will use Composer to deal with th project production and development dependencies and will hence set up the project navigating to the folder it will live in:

$ cd wp-schedule
$ composer init

and after some interaction with Composer CLI I will end up with the following pristine composer.json file:

{
    "name": "lucatume/wp-schedule",
    "description": "Utility wrapping of WordPress cron scheduling system.",
    "license": "GPL 2.0",
    "authors": [
        {
            "name": "theAverageDev",
            "email": "[email protected]"
        }
    ],
    "minimum-stability": "dev",
    "require": {}
}

I will keep the source files in the /src folder and will use the WPSchedule_ pseudo-namespace root for the project:

$ mkidr src
$ cd src
$ mkdir WPSchedule

Autoloading for PHP 5.2

I will instruct Composer to autoload files from the just created src/WPSchedule folder modifying the composer.json file above to

{
    "name": "lucatume/wp-schedule",
    "description": "Utility wrapping of WordPress cron scheduling system.",
    "license": "GPL 2.0",
    "authors": [{
        "name": "theAverageDev",
        "email": "[email protected]"
    }],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "psr-0": {
            "WPSchedule_": "src/"
        }
    }
}

I will develop a PHP 5.2 compatible package, although development will happen in a PHP 5.4 environment, to stick with WordPress minimum requirements.
Composer itself requires PHP 5.3.2 to run and will assume (a safe assumption in almost any case) that same PHP version as the one the created package will run into; that’s not the case with WordPress and the benefit of Composer autoloading power would be lost in a PHP 5.2 environment.
Thanks to this package by “xrstf” a PHP 5.2 compatible autoloader file can be generated alongside the PHP 5.3 compatible one, the composer.json file changes again into

{
    "name": "lucatume/wp-schedule",
    "description": "Utility wrapping of WordPress cron scheduling system.",
    "license": "GPL 2.0",
    "authors": [{
        "name": "theAverageDev",
        "email": "[email protected]"
    }],
    "minimum-stability": "dev",
    "require": {
        "xrstf/composer-php52": "~1.0"
    },
    "scripts": {
        "post-install-cmd": ["xrstf\\Composer52\\Generator::onPostInstallCmd"],
        "post-update-cmd": ["xrstf\\Composer52\\Generator::onPostInstallCmd"],
        "post-autoload-dump": ["xrstf\\Composer52\\Generator::onPostInstallCmd"]
    },
    "autoload": {
        "psr-0": {
            "WPSchedule_": "src/"
        }
    }
} 

I won’t be using the PHP 5.2 autoload file yet but that’s a thing to know for a WordPress project meant to be “composed with Composer”.

Codeception and function-mocker

The testing tools I will use are Codeception and function-mocker both depending, among the others, on PHPUnit.
I will require them both for development purposes using Composer CLI:

$ composer require --dev codeception/codeception:~2.1 lucatume/function-mocker:~0.2

and will wait for the magic download and installation to happen.

Codeception set up

While a WordPress specific version of Codeception testing tools exists I won’t be using it for this project as I will be leveraging function-mocker not defined functions replacement capabilities to “simulate” an up-and-running WordPress environment.
After Composer finished its installation process setting up Codeception will not need much effort but for a single CLI command:

$ codecept bootstrap

Project structure and components

The project will have this structure

/src
    /WPSchedule
        /Schedule
            ScheduleInterface
            AbstractSchedule 
            Schedule
        /Interval
            IntervalInterface
            AbstractInterval
            Interval
        /Time
            TimeInterface
            AbstractTime
            Time 

and will use psr-0 naming convention for the files and the camelCase format for class names: while not WordPress standard it’s PHP standard and will play nice with auto-loading; e.g. the file src/WPSchedule/Schedule/Schedule.php will define the WPSchedule_Schedule_Schedule class and so on.
As for the pieces the idea is to build them as the need arises but a first planning based on the “as much type-hinting as possible” principle can easily forecast the need for an Interval object and a Time object: the idea is to wrap the wp_schedule_event function and the family of functions that goes along with it in a reusable and testable component and a quick glance to any of those functions will reveal the need for those classes.
Sticking to a TDD tradition I will create a first test case using Codeception CLI:

$ codecept generate:phpunit unit WPSchedule_Schedule_Schedule

will add a basic test to it

class WPSchedule_Schedule_ScheduleTest extends \PHPUnit_Framework_TestCase {

    /**
     * @var WPSchedule_Schedule_Schedule
     */
    protected $sut;

    /**
     * @var string
     */
    protected $sutClass = 'WPSchedule_Schedule_Schedule';

    protected function setUp() {
        $this->sut = new WPSchedule_Schedule_Schedule();
    }

    protected function tearDown() {
    }

    /**
     * @test
     * it should be initializable
     */
    public function it_should_be_initializable() {
        $this->assertInstanceOf( $this->sutClass, $this->sut );
    }

}

and will run it to watch it fail

$ codecept run unit

First wp-schedule failing test
After stubbing out the project structure I will run the test again and see the green light
First wp-schedule passing test

Next

I will go on with development putting function-mocker to the test (pun intended).