tdd-deciphered.com

created by @parsingphase

Chapter 4: Technical groundwork

Note: if you want to follow along with this code, you’ll need the following installed on your system. Some of them may already be present depending on your operating system.

  • PHP, version 5.3.2 or better (ideally version 5.4 or better). You’ll only need the command-line version; we won’t be using a web server for most of this project.
  • Git, any reasonably recent version.
  • Composer, any reasonably recent version. I’ll assume that you’ve installed it globally as per the instructions.
  • A decent text editor or (much preferred) IDE. I use and enthusiastically endorse PHPStorm. Grab the free trial at least.
  • If you want to push your code to a public location, you’ll also need an account on Github or similar.

Besides ensuring that our code is functional, clean and correct, we also want to make sure that it’s as reusable and flexible as possible. To achieve this, we’ll create it as a publicly hosted, composer-installable library.

If you’re not familiar with composer, don’t worry - we’ll introduce it as we go along. Put simply though, it’s the standard mechanism for installing third-party PHP code and its dependencies from remote sources. It’s incredibly useful, as I noted in a recent blog post entitled “PHP as Framework”.

For now though, all that we need to know is that to make code available as a composer module, it needs a public location for the source code, and a composer.json file telling us a little about it.

Where you choose to host any project and what you call it is your own decision, but for the sake of example I’ve created a repository under my Github user account of “parsingphase”. We need a name for the repository, so I’ll just call it ‘enigma-simulator’. This gives us a repository location of https://github.com/parsingphase/enigma-simulator and a convenient two-part name (which we need for composer) of parsingphase/enigma-simulator.

As with composer, I’m not going to tell you everything about either git or github, but I will give you all the command-line instructions we need to perform the key tasks. To create a Github repository however, refer to https://help.github.com/articles/create-a-repo.

If you don't want to use Github, just type “git init” in your project root to create a local repository.

I’ve created my repo on Github with a default README file and a MIT licence, to which we now need to add a very simple composer.json file. In your favourite text editor or IDE, create this file in the root of your repository:

{
"name": "parsingphase/enigma-simulator",
"description": "Enigma Simulator, as built in the project described at http://tdd-deciphered.com/",
"type": "library",
"license": "MIT",
"authors": [
    {
        "name": "Richard George",
        "email": "richard@phase.org"
    }
],
"autoload": {
    "psr-0": {
        "Phase\\Enigma\\": "src/"
    }
},
"minimum-stability": "stable",
"require": {
    "php": "~5.4"
},
"require-dev": {
    "phpunit/phpunit": "~4.2"
},
"extra": {
    "branch-alias": {
        "dev-master": "0.1.x-dev"
    }
}
}

There are a few implicit decisions made in this file which deserve mention. We’ve specified that we’re going to adhere to the PSR-0 autoloading standard. This is one of the extremely useful community standards, created by the Framework Interoperability Group (http://www.php-fig.org), and requires the following of our code:

A fully-qualified namespace and class must have the following structure \()* Each namespace must have a top-level namespace ("Vendor Name"). Each namespace can have as many sub-namespaces as it wishes.

I always release code under the “Phase” vendor namespace, a shortened version of my github handle. Common practice says we should have a second-level namespace referencing the project itself, so we’ll use ‘Enigma’. This also determines the structure of our source directory (which we call ‘src’) and, implicitly, our test directory, so we create those folders, with placeholder files to ensure that git sees them:

mkdir -p src/Phase/Enigma tests/Phase/Enigma
touch src/Phase/Enigma/.placeholder tests/Phase/Enigma/.placeholder

We also specify a couple of requirements for running and developing the project. I want to have traits and short array syntax available, so I’m specifying that this code needs php 5.4 or better. We’re going to unit-test this code, so we also tell composer to install phpunit when we’re developing.

You can change a few of the class and developer names above to suit your own situation. In particular, please change “parsingphase” to something else if you think you might ever make the code public.

Once you’ve made all these changes, you can check that composer is properly installed and that this file is valid by running “composer validate” at a command prompt in the repository base directory; you should get the message “./composer.json is valid”.

Next, run the command “composer install” at a command prompt in that directory to fetch the phpunit tool that we’ve specified as being required for development. You now have a working project environment set up, albeit one that doesn’t actually do anything yet, so we’re ready to commit some changes to git.

Before we do this, we need to mask off some files that git doesn’t need to know about. To do this, create a file called .gitignore in the project root (don’t miss the leading dot!), with the following contents:

.idea
vendor
composer.lock

Note: .idea is the working folder that PHPStorm creates; yours may create different folders or files. Either way, we don’t need to commit them.

Running “git status” in our folder should now tell us that we have two files ready to commit: composer.json and .gitignore (you may also see a LICENSE and README.md file).

Commit all the known files and push them to your remote repository if you want:

git add composer.json .gitignore 
git commit -m 'Basic project setup’

(The git push command is left as an exercise to the reader as it depends on details of your repo setup. In my case it’s just git push origin master).

For the sake of those following the github project, I’ve tagged the code at this point as Chapter4-1-ProjectSetup

Now everything’s in place, we can start on our tests and code.