London Web Standards: Javascript with Frances Berriman and Jake Archibald

Review: LWS March: JavaScript – The events that get left behind & Pro-bunfighting at The Square Pig, 30 - 32 Procter Street, Holborn, London, WC1V 6NX 19:00 to 20:30

This event was focussed on JavaScript, specifically the Glow 2 library from the BBC which both speakers are working on. Frances talked about coordinating work on a JavaScript project with a geographically distributed team, discussing some teamwork strategies and demonstrating some useful tools. Jake talked about the nightmare that is DOM Level 2 keyboard events and how he'd worked around the issues in Glow 2. Both of them were funny and engaging speakers, so much so that I feel I could hardly do them justice with a textual repetition of their talks. That and I didn't really take detailed notes this time, and had to leave before the Q&A... So, for a summary of what was said check out the usual live blog of the event from Jeff, meanwhile I'm going to have a play around with three of the JavaScript tools discussed: JSDoc, QUnit and Glow 2 keyboard events.

JSDoc

In team environments developers are supposed to liberally comment their code and also document the requirements before coding, and the APIs afterwards. Inevitably anything that developers are asked to do which is not strictly coding tends to take a back seat, especially when deadlines are approaching. Documentation requirements therefore get skimped or skipped, and often are not kept in sync as the code evolves. In the Enterprise development world this issue led to the development of tools like JavaDoc which, if you write your comments in a particular format, will automatically generate nicely formatted documentation for you when you've finished. This halves the amount of documentation you have to write, increasing the chance developers will do it, and keeps that documentation close to the source code to which it pertains, improving the chance it's kept up to date. JavaDoc has been much imitated, and the JavaScript equivalent is JSDoc.

So, how do you use JSDoc? First you have to download and extract the latest version, you also need to have a Java runtime installed, version 1.5 or later. Now you have to adjust your comments slightly, assuming you have comments in your code already :) I didn't, so I grabbed the complex.js file I'd copied out of the rhino book for my post on the canvas element. You can run JSDoc on that file as it stands and it will generate some documentation. Assuming you're in a command prompt in the directory where you extracted JSDoc (and, er, you're on Linux - adjust path separators if you're on Windows), issue a command line like this:

java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ ../code/complex.js

The command will produce a directory out with the generated documentation. This is what the basic documentation looks like:

The results of JSDoc on a standard JavaScript file

As you can see (check out the full results), it's found the constructor function but not much else - everything is in the global namespace. Let's annotate the comment before the constructor function and see what happens, this is what it looked like before:

/*
 * The first step in defining a class is defining the constructor
And here's what it looks like when it's JSDoc enabled:
/**
 * The first step in defining a class is defining the constructor
Can you see the difference? Look closely at the first line - there's one extra asterisk. That extra asterisk is what tells JSDoc to look in this comment for 'special' stuff. At the end of the comment I'm going to add an annotation:
 * @constructor
 */

Run the command again and suddenly there's a whole load more stuff:

The results of JSDoc on a JavaScript file with a single annotation

In the new version of the documentation there's a Complex class, and it's found all the methods. However, your fellow coders may appreciate a bit more than the basics. Perhaps you might want to document what the expected parameters and return values are? Additional annotations follow the same pattern as @constructor - an ampersand followed by a keyword. Some of the other keywords let you provide additional information, here's what parameters and return values look like:

/**
 *Add two complex numbers and return the result.
 *@param a {Complex} A complex number
 *@param b {Complex} A second complex number
 *@returns {Complex} The sum of a and b
 */

Now JSDoc adds your comments to the output, and additionally provides links to any other types you've defined:

The results of JSDoc on a JavaScript file with several annotations

You can have a look at the final output here.

QUnit

Unit testing is something I keep thinking I should learn how to do. The BBC Glow team is using the jQuery unit testing framework QUnit, so this seems like a good excuse to investigate it.

QUnit is very easy to set up, you just need to link to JQuery and the two QUnit files in your document head:

<script src="http://code.jquery.com/jquery-latest.js"></script>
<link rel="stylesheet" href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js"></script>
Then provide some HTML framework for the results to appear in:
<h1 id="qunit-header">QUnit example</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
Now you need to write some tests. To do this, simply add a function to $(document).ready that calls the test function:
test("Passing tests", function() {
  ok(true, "The truth is true");
  equals(1,1, "One is one");
});

These are obviously quite basic tests, and not actually testing anything, but demonstrate how easy it is. The ok test accepts a 'truthy' value and a string and succeeds if the value is true, the equals test accepts two values and a string and succeeds if they're equal.

Basic QUnit tests

To try some less basic tests I once again dragged out the complex.js file. The test functions can contain more than just the testing functions, you can put as much JavaScript in there as you need to do your test. Here's what I ended up with:

test("Basic class functionality", function() {
  expect(4);
  var real = 1.0;
  var imaginary = 1.0;
  var c;
  ok( c = new Complex(real,imaginary), "Class created" );
  equals( c, real, "Simple value comparison" );
  equals( c.toString(), "{" + real + "," + imaginary + "}", "String comparison");
  equals( c.magnitude(), Math.sqrt(2.0), "Magnitude comparison")
});

You can see I've used the ok test to confirm the object gets created, then done some simple comparisons to make sure the object created is what I expect. Unsurprisingly, all my tests pass:

Slightly less basic QUnit tests

Of course, this just demonstrates that QUnit is very straightforward to use rather than that some code I nicked out of a book works perfectly. There's a whole art to writing unit tests over and above the simple mechanics of the framework you're using, but I'm definitely not the person to be telling you about that. If anyone knows of any good, JS oriented tutorials for doing test driven development, please leave a comment.

Glow 2 Keyboard Events

Jake talked about the mess that is keyboard events in current browsers, and how he set about fixing it in Glow 2. The problem with keyboard events in browsers can be summed up by a quick look at the W3C DOM Level 2 Spec:

A visual comparison of the size of the mouse event spec with the much shorter keyboard event spec

Given the lack of spec it's hardly surprising that the browsers have all implemented keyboard events slightly differently. Not only have the browser implemented things differently from each other, there are also differences between the same browsers on different operating systems. Throw in the fact that keyboards in different countries have different sets of keys, and it all gets a bit messy. In Glow 2, the keyboard events have been normalised to keydown, keyup and keypress, with the same properties on the event object across browsers.

I've downloaded the Glow 2 source to have a go with these keyboard events. After downloading the extra libraries I've managed to get it to build with Ant, but I've not got the build itself working in a browser yet. It could be me, it could be a bug, I haven't figured it out yet - when I do I'll fix up my keyboard event example application and update this post.

Another excellent event, the two best speakers of the three events I've been to, 5 out of 5. Watch out for the next one on 26th April.

Technorati tags for this review: