Thursday, October 27, 2011

Learning CoffeeScript With Unit Tests


CoffeeScript is a language that transcompiles to JavaScript and has syntax that looks more like Ruby or Python. In other words, it allows you to write JavaScript without writing JavaScript and with a lot less code. The generated JavaScript code even runs as fast, if not faster, than if you had written pure JavaScript.

I don't mind writing pure JavaScript but since I really like Python and Ruby, I figured I'd give a try since the syntax is familiar. CoffeeScript can even make jQuery even easier to write than it already is.

My Coworker Danny turned me on to using Koans to learn Ruby, and when he mentioned there's a CoffeeScript version, I immediately jumped on it.

Koans can aid in learning a new programming language. They're a Behavior Driven Development approach that turn learning into a kind of game where you fill in the blanks to make tests pass.

A CoffeeScript Koan consists of CoffeeScript code with Jasmine unit test files. The tests look like:
 # Sometimes we will ask you to fill in the values
 it 'should have filled in values', ->
   expect(FILL_ME_IN).toEqual(1 + 1)
You then compile the file (in this case AboutExpects.coffee) using the command-line coffee tool:
 $ coffee -c AboutExpects.coffee
which in turn creates the corresponding JavaScript file (in this case AboutExpects.js). If we were just writing CoffeeScript code, we could then run the .js file in a Web Browser, as usual. Or even execute the JavaScript file without a browser, if you have node.js installed, which we'll do in a minute:
 $ node yourFile.js
However, since we're doing Koans, we'll load the file using the bundled "KoansRunner.html" file, which loads our compiled .js file using the Jasmine Behavior Driven Development framework. This let's us know if our tests passed or failed.

Let's start by installing the CoffeeScript and the command-line compiler. Note that modern Ruby on Rails installs should already have CoffeeScript. For this tutorial I've only tested the following in Ubuntu Linux, but it should work for most Unix-like Systems. But you're always free to check for bundles for your system if you want to make it a little easier on yourself.

The coffee command-line tool is dependent on Node.js, so we'll need to install that first. Currently, the best way to install Node is to compile it yourself. So download it via the tarball or github repository, then run the usual:
$ ./configure && make && sudo make install
Now that Node is installed, we'll install the Node Package Manager (NPM):
 $ cd /tmp
 $ curl -O http://npmjs.org/install.sh
 $ sudo ./install.sh
Now you can install the coffescript command with:
 $ sudo npm install -g coffee-script
Once installed, typing coffee should show an interactive prompt like:
 coffee>
Type Ctrl-D to exit.

You're now ready to install the CoffeeScript Koans from the github repository. Assuming you're working from ~/src/:
 $ mkdir ~/src/koans
 $ cd ~/src/koans
 $ git clone https://github.com/sleepyfox/coffeescript-koans.git
 $ cd ~/src/koans/coffeescript-koans/
In the above screenshot image in this article, you can see I've split my Linux screen in half, with the top half a Web Browser running KoansRunner.html. The bottom half is AboutExpects.coffee open in Vim.

Note that the answers to the first two Koans are already filled out in my example. They're so overly simplistic that just by understanding those two answers you'll have learned as much as you otherwise would have, so don't feel cheated.

So now it will be your job to open koans/AboutExpects.coffee and fill in a test method with what you assume is the correct answer. Then compile it with:
 $ coffee -c koans/AboutExpects.coffee
and move the generated JavaScript file to the lib/koans directory and reload the KoansRunner.html file to see the new test results. Once you complete all the Koans in AboutExpects.coffee, you'll move onto the next Koans file, AboutArrays.coffee, and so on.

There are a couple of tips for making compiling and reloading easier. One tip is that at the root of the Koans directory, you can run a command called "cake", which was installed earlier during the coffee install process. You can verify this with:
 $ file $(which cake)
 /usr/local/bin/cake: symbolic link to `../lib/node_modules/coffee-script/bin/cake'
 $ file -L $(which cake)
 /usr/local/bin/cake: a node script text executable
Running:
 $ cake build
will compile all of the tests in the koans/ directory and automatically cp them to the lib/koans directory. This allows you to add a Vim keyboard mapping to your ~/.vimrc file, such as:

    nmap <Leader>c :!cake build<CR>

which lets you recompile the Koans by simplying typing \c in Vim. The "Leader" key on my system is a backslash, YMMV. Just make sure to run the shortcut from the root of the Koans directory so it can find the build file.

If you have Ruby and RubyGems installed, there's an even easier way to do this, using a "watch" command. The coffee command-line tool comes with an option called '-w', which watches for modified timestamps of files and then re-compiles the files automatically when they change. And the Koans come with a nice extension to this by including Ruby files called koans-linux.watchr, koans-win.watchr and koans-mac.watchr, respectively. To use it you need to install the watchr gem:
 $ gem install watchr
Now, if you were on a Linux machine, say, you would run this in a terminal:
 $ watchr koans-linux.watchr
Now you can edit and save your CoffeeScript koans and just hit refresh in your browser. The cake build step is taken care of automatically by the watchr!

Another thing that's nice to be able to do, is check our CoffeeScript code for syntax errors before we try to run it. This is known as "linting". The coffeescript command-line tool comes with an option called "-l" that lets you lint your files, but only if you have jslint installed first. So install it with:
 $ npm install jslint
At this point, you're breezing through the Koans and you start learning enough CoffeeScript that you actually start using it to write your JavaScript, and you open a coffee compiled .js file and you notice the JavaScript looks a little verbose. As a simple example, say you had written a Hello World function called hello.coffee like:
 sayHi = (name) ->
   return "Hello " + name

 console.log sayHi("Ryan")
and you compiled it and opened the .js file and noticed it looked like:
 (function() {
   var sayHi;
   sayHi = function(name) {
     return "Hello " + name;
   };
   console.log(sayHi("Ryan"));
 }).call(this);
As you might suspect, it's just there by default for global namespace cleanliness. You can either manually remove it, or compile your coffeescripts with "-b, --bare". Which would then look like simply:
 var sayHi;
 sayHi = function(name) {
   return "Hello " + name;
 };
 console.log(sayHi("Ryan"))
There is other verbosity such as it always declaring all variables with the var keyword. However, there's no good reason to take them things out since it's actually great to have CoffeeScript do all the tedious things for us that we often skip doing.

That's all for now. Please visit the main CoffeeScript and CoffeeScript Koans sites for more information.

No comments:

Post a Comment

Followers