TDD WordPress project - 02
December 4, 2014
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": "luca@theaveragedev.com"
}
],
"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": "luca@theaveragedev.com"
}],
"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": "luca@theaveragedev.com"
}],
"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
[](http://theaveragedev.local/wordpress/wp-content/uploads/2014/12/2014-12-04-at-10.12.png) After stubbing out the project structure I will run the test again and see the green light [
](http://theaveragedev.local/wordpress/wp-content/uploads/2014/12/2014-12-04-at-10.17.png)
Next
I will go on with development putting function-mocker to the test (pun intended).