More on TDD in Haxe/NME - Game of Life

Recently I came across the Game of Life code kata, through Marcello Duarte, while doing some TDD practice in PHP. Due to the visual nature of this game, I decided to give it a try using Haxe. I had already done it in PHP a few times, and had established that there was nothing too complicated on the test, that would give me trouble with munit, or would require mocking (still haven’t looked into mocking frameworks for Haxe ;) ).

My first effort to do it in Haxe/NME is available on github (https://github.com/mlopes/NME-GameOfLife). This post will focus on how that code was created.

TDD

I tried to apply the principles of TDD and code it as if doing a code kata, so:

  • Write a test
  • Watch the test fail
  • Write just enough code to make it pass or to change the failing message
  • Refactor the code and tests, making sure the tests still pass
  • Go back to step 1

While doing the kata, always follow these principles. If you need some code to account to some odd situation that just occurred to you, write a test for it first and follow those 4 steps in that order.

Write a test

The first rule of the Game of Life as described in Wikipedia says:

“Any live cell with fewer than two live neighbors dies, as if caused by under-population.”

So, I decided to start by implementing this rule. In order to do this, I described my code as doing the following:

It returns false for live cell with less than two neighbors

This description of the code is used as the name of the first test, which then proceeds in describing how this will be achieved:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    ...

    import org.games.life.Life;

    ...

    class LifeTest
    {
        ...

        public function itReturnsFalseForLiveCellWithLessThanTwoNeighbours():Void
        {
            var life:Life = new Life();
            Assert.areEqual(0, life.getNextGenerationCellState(1, 0));
            Assert.areEqual(0, life.getNextGenerationCellState(1, 1));
        }

        ...
    }

What to do next? Let’s start writing some code!!!

WRONG!!!

Watch it fail

Now, we’re going to run our test and see it return red, which means it didn’t pass. There’s a bunch of reasons to do this. First to see if it fails for the right reasons, second to see if it fails at all, third to keep yourself into this rhythm of these 4 steps. Running the test will now complain that the class Life does not exist, so let’s create it. Now, because you just fixed the problem generating the failure message, you’ll need to run your test again. Do it, and you’ll see the message changing to say that the getNextGenerationCellState method does not exist. The test is still failing, but the fact that the message is now different, shows we’re on the right track. We should now create the method and our test will finally fail because 0 is not equal to whatever our empty method is now returning. Now we write the simplest piece of code that can make it pass, which is basically this:

Write just enough code to make it pass

1
2
3
4
5
6
...

public function getNextGenerationCellState(parentCellStatus:Int, numberOfNeighbours:Int):Int
{
    return 0;
}

You might say, that this doesn’t do what we want, but it does. Right now the only think our code needs to do is to return 0 in a given situation, the description (our tests) doesn’t even say it should not return 0 when the cell has 2 or more neighbors. Is this useful? Not at all, but we’re not done with our tests yet. So let’s leave it as this now.

Refactor

We can now look at our code and refactor it. Because we’re only on the first iteration and both our code and our test are very simple, I don’t think there’s anything to change here, which lead us back to step 1.

Write a test

So on to the second rule, which I described in the code as:

It returns true for live cell with two or three neighbors

And to test this:

1
2
3
4
5
6
    public function itReturnsTrueForLiveCellWithTwoOrThreeNeighbours():Void
    {
        var life:Life = new Life();
        Assert.areEqual(1, life.getNextGenerationCellState(1, 2));
        Assert.areEqual(1, life.getNextGenerationCellState(1, 3));
    }

Watch it fail

Run the test, and see it fail for the right reason, which is the test expected to receive 1 and received 0. Not really surprising, since our code only returns zeros, for now.

Write just enough code to make it pass

Now we will write again the minimal amount of code to make the test pass:

1
2
3
4
5
6
7
8
9
...

public function getNextGenerationCellState(parentCellStatus:Int, numberOfNeighbours:Int):Int
{
    if(numberOfNeighbours == 2 || numberOfNeighbours == 3) {
        return 1;
    }
    return 0;
}

And we now stop writing code, because our test passes. Again you’ll notice this is still not the ideal implementation, but it moved one step closer to it. Don’t worry, while writing tests and making them pass, and then refactoring your code, you’ll get to the point where it does exactly what it needs to, and because of the refactoring, it should do it in a very clean and simple way.

Refactor

Again, in the code there seems to have nothing worth refactoring yet, but now we have var life:Life = new Life(); repeated in our tests, which means we should refactor them. Create a property called life, instantiate it in the test setup method, and remove the object creating from the test methods.

And so on…

Now repeat these steps, until all the behavior is described in a test, and all the tests pass.

Consumer

In this example we have two more classes that we haven’t talked about yet: Game and Main.

Main.hx is the kind of file that comes with NME project templates, it’s the entry point to the application. As such, it’s not owned by us, and thus we should not test it.

Game is owned by us, so why is it not tested? Well, the Game class is not part of our game API. It is the consumer for our API, and it should be tested, but not by unit tests but rather by acceptance tests, which is out of the scope of this post.

Well… that’s it, pretty much

Take a good look at the test, and how they make the implementation evolve, give it a try to some code katas, practice TDD as much as you can, because you’ll see the benefits in your code every day. Remember that the way you approach the problem should be your own, and don’t let this example stick you to a certain path. Any questions, suggestions or improvements to this post, please, let me know.

Testing Haxe/NME Project With Munit

Anyone who ever used haxe as certainly noticed that it is a very promising language, with some very promising frameworks and libraries. NME specially is a very promising framework that didn’t fail to amaze me on how good it is at getting a single codebase to compile to several platforms. On the other hand, all of these projects seem to miss documentations and some guidance in general, and for someone who’s suddenly interested in giving it a try, it can be a bit painful to get going. I experienced such a situation recently when trying to do some TDD with haxe.

What to choose?

The first problem to overcome was, choosing a testing framework. Haxe itself has a small native testing API, but it looked very basic, and so I decided to look for something else. The Haxe community doesn’t seem much like a test driven community yet and it wasn’t easy to find comparisons or documentation that would let me fairly compare any of the testing frameworks I came across.

I ended up choosing munit because it seemed slightly better documented and it also seemed to be an relatively active project.

Installing and configuring munit

The documentation on how to install it is pretty good, and install it ended up being quite easy. Just run the following command:

1
$ haxelib install munit

Then, we need to configure munit for the project we want to test. Let’s say our project is called MyAwesomeProject. From inside the project folder do:

1
$ haxelib run munit config
Massive Unit - Copyright 2013 Massive Interactive. Version 2.0.0
Configure munit project settings
--------------------
test src dir (defaults to 'test') :
output build dir (defaults to 'build') : deploy
report dir (defaults to 'report') :
target class paths (comma delimitered, defaults to 'src') :
hxml file (defaults to 'test.hxml') :
resources dir (optional, defaults to 'null') :
templates dir (optional, defaults to 'null') :
coverage packages (optional, defaults to 'null') :
coverage ignored classes (optional, defaults to 'null') :

This will ask a few questions about the folders where your tests, source code and compiled files will be, and create a .munit and test.hxml files. The .munit file will contain the folder configuration for our project. So assuming our project tree looks like the following:

MyAwesomeProject
 |
 |-- deploy
 |-- report
 |-- src
 +-- test

The .munit file should look something like this:

1
2
3
4
5
6
version=2.0.0
src=test
bin=deploy
report=report
hxml=test.hxml
classPaths=src

We should now be able to run an example test, by executing the following command:

1
$ haxelib run munit test

This of course is not very useful, but we can now start creating our own useful tests. Let’s assume we’re going to create a test for our Game class in the com.MyAwesomeCompany.MyAwesomeProject package. I couldn’t find a way to mirror the exact path name for the tests, as the package name would conflict with the unit under test package name. Because of this, I decided to use the following rule: Assuming our package and class names are named as in the example referred above, my test will be called GameTest inside a package called com.MyAwesomeCompany.MyAwesomeProjectTest To create this test class, we can run:

1
$ haxelib run munit ct com.MyAwesomeCompany.MyAwesomeProject.GameTest

This will create a test template that we can then edit and add our tests.

NME and other libraries

To be able to test Classes that use libraries such as nme or actuate, we need to add them to the configuration for every target on the test.hxml, as on the example below:

## Flash 10+
-main TestMain
-lib munit
-lib hamcrest
-lib nme
-lib actuate
-cp src

-cp test
-swf-version 10

--next

You’ll only need the --next on the last line if other configurations ensue.

Some extras

To make it easier to run the tests, I created a couple of aliases to be able to run tests faster. Because the flash target compiles faster than the CPP targets, I create an alias munit that runs the tests for the as3 target only.

1
$ alias munit="haxelib run munit test -as3"

And an alias munitall that runs the tests for all the targets configured on the test.hxml file.

1
$ alias munitall="haxelib run munit test"

We can add these to one of our shell configuration files so they’re available at all times.

Mocks and Matchers

Unfortunately, due to poor documentation, I’m not completely sure if there’s any mock support directly on munit, but from what I could see, it seems there’s not. I found a few mock libraries, but couldn’t yet decide wich one should I use, and how compatible they are with munit. A similar situation happens with matchers, munit uses a hamcrest port for haxe, but I couldn’t find any documentation on how to access these matchers or which ones does this port implement. Hopefully with time, as I write tests I’ll find more about both mocks and matchers, at which time, I’ll surely add a new post about it.

Debug Tokens for Blackberry Playbook Development With NME

Why?

When I first started looking at generating debug tokens for the Blackberry Playbook, it was very hard to find the correct documentation on how to do it, and to distinguish between the deprecated and current ways of doing it. When my debug token expired, I had to generate a new one, and I immediately missed some documentation I could have created highlighting the steps I took when I did it the first time. After looking at some old e-mails and IRC logs, I was able to get enough information to do it again, and it even seems that the official documentation got improved. Nevertheless I decided to go ahead and document how I did it.

How?

First we’ll need to have a developer account on the Blackberry developers website so we can request a debug token signing file. When I did this, I received back an e-mail with a client-RDK-xxxxxxx.csj and a client-PBDT-xxxxxxx.csj file attached. The file we’ll need to use for signing your debug token is the client-PBDT-xxxxxxx.csj one. We will also need to have the Blackberry NDK installed on the computer we’ll be using to create and sign the token. In this post the NDK will be installed in /Developer/SDKs/bbndk-2.1.0-beta1 and the keys placed in ~/.bbkeys, therefore these are the paths we’ll be using on all the examples.

Before starting, we’ll need to get the PIN of the device we want to create a key for. On the Blackberry device, go to SettingAbout. From the View information about your tablet drop-down on the right, select Hardware and take note of the PIN. The PIN should look something like 1234ABCD.

Move into the ~/.bbkeys folder:

1
$ cd ~/.bbkeys

Now use the blackberry-debugtokenrequest utility, on the computer, to generate the token. We will need to provide the PIN we got from our device, the password used on our developer account to request the signing keys, and the name of the “bar” file which will be the token file itself.

1
$ /Developer/SDKs/bbndk-2.1.0-beta1/host/macosx/x86/usr/bin/blackberry-debugtokenrequest -storepass mystorepassword -devicepin 1234ABCD develop001.bar

If everything went ok, we should now have a developer001.bar file on our ~/.bbkeys folder. We will now need to install the debug token to the Blackberry device. This is done using the blackberry-deploy utility.

Before installing the token, lets get some information we will need from the device again. Open SettingsSecurity and find the Developer Mode section. Make note of the device IP address displayed on the Developer Mode section and activate the developer mode.

Back to the computer, lets run the blackberry-deploy utility using the name of the file created with the blackberry-debugtokenrequest, the password we set on our device when we enabled developer mode and the IP address we took note on the previous step:

1
$ /Developer/SDKs/bbndk-2.1.0-beta1/host/macosx/x86/usr/bin/blackberry-deploy -installDebugToken develop001.bar -device 169.254.0.1 -password mydevicepassowrd

And that’s it, we now have our debug token, and installed it to the Blackberry device…

… well not quite, there’s still one more step to go. The reason we went through all this trouble was to be able to test our Applications on our device, so now we need to sign our application with the debug token.

Adding it to our NME application

Making NME aware of our debug token is quite easy. All we need to do is to run nme setup blackberry and provide it with all the information it will ask us. At this point, we already possess all of this information, so it should be pretty straightforward. Just execute the following command:

1
$ nme setup blackberry

We can check, or manually change the configurations generated by this script by editing the .hxcpp_config.xml in our home folder. The contents of the file should look something like this (all non-blackberry related configurations are removed from this example):

1
2
3
4
5
6
7
8
9
<xml>
    <section id="vars">
        <set name="BLACKBERRY_DEVICE_PASSWORD" value="mydevicepassowrd" />
        <set name="BLACKBERRY_SETUP" value="true" />
        <set name="BLACKBERRY_DEVICE_IP" value="169.254.0.1" />
        <set name="BLACKBERRY_NDK_ROOT" value="/Developer/SDKs/bbndk-2.1.0-beta1" />
        <set name="BLACKBERRY_DEBUG_TOKEN" value="/Users/mlopes/.bbkeys/develop001.bar" />
    </section>
 </xml>

End

And that’s it, we should now be able to compile our application and test it on the blackberry device. Plug in the device and compile the application:

1
$ nme test amazingApp.nmml blackberry

Rvm or No Rvm?

What made me write this post, was that today I came across a limitation of using the ruby version managing tool rvm. My point is, rvm is a very good tool, and an extremely well thought idea. But… only when managing a pure gem system. If any other kind of applications has dependencies on ruby, then using multiple version of ruby can lead to some issues.

So, it all started when I decided to look for a plugin to preview markdown on vim. I quickly came across something called vim-preview, which should let me do exactly that: preview various documentation formats directly from vim. Not surprisingly nowadays, the plugin required vim to be compiled with support for ruby plugins. I quickly compiled vim using homebrew, and ended up with a vim binary with support for ruby plugins. Note that, because I use rvm, I first made sure that the system version of ruby (1.8.7) was selected. The reason for this, is to ensure my vim is linked to the right version of the ruby libraries and the one that should be more widely supported on my system.

After finishing the plugin installation, I changed into my Octopress folder, and used vim to edit a .md file. I immediately tried to test the plugin, so I executed:

1
 :PreviewMarkdown

And this was the result:

1
2
3
 Vim: Caught deadly signal SEGV
 Vim: Finished.
 Segmentation fault: 11

So why has this happened? The motive is very simple, and yet is the big weakness of rvm:

Octopress requires at least ruby 1.9.2, so when I installed Octopress I used rvm to have ruby 1.9.2 on my computer in parallel with the system version 1.8.7. To avoid having to manually change ruby versions each time I’m working on the blog, I create a .rvmrc file with the following contents:

1
rvm use 1.9.2@octopress

This basically changes my ruby version to 1.9.2 with the gem set octopress. When vim, which was compiled with ruby 1.8.7, tried to load gems from version 1.9.2, things were not what it was expecting, so it got a segmentation fault.

This is not an rvm problem, per se, this is a problem that comes from using different versions of ruby in parallel, that rvm fails to address. One could now discuss if it falls outside rvm’s scope to address this kind of issue, or even that it’s impossible to control all non-ruby software that in a way or another links to the ruby libraries available on a system on a given moment.

One way or the other, in my opinion, rvm is still by far the best platform that I know of, to manage multiple versions of the same language in use, in parallel, in one system.

First Post

Just finished setting up Octopress. It took me quite some time, mainly because the documentation is not great. It kind of assumes a level of experience installing ruby applications, that I simply don’t have. After following the installation instructions using rvm, on the Octopress documentation, I ended up with ruby 1.9.2 but gems would crash with the following error:

> ERROR: Loading command: install (LoadError) no such file to load -- zlib

I spent about one hour trying to get this issue fixed without any success. I tried compiling ruby with the zlib path set to $rvm_path/usr, I installed zlib via RVM and via apt, re-compiling ruby after that, none of those did the trick. The first clue to what was going on was when I ran:

bash
1
$ rvm requirements

And found the following:

> To install rbx and/or Ruby 1.9 head (MRI) (eg. 1.9.2-head),
> then you must install and use rvm 1.8.7 first.

I think this is a Linux, or maybe Debian specific issue, which probably is the reason for it not to be mentioned on the Octopress docs. Installing ruby 1.8.7, upgrading rubygems with it and then going back to ruby 1.9.2, fixed the issue.

After that I had no more problems, all the remaining setup went smothly.

Since, although I had heard about Octopress before, I decided to give it a try after reading the ”Uses Of Git” post, I would definitely like to see a pure git deployment strategy, using post-update hooks on the server side, or something of the sorts.