Lightweight Headless Test for Trailing Commas in JavaScript

Yesterday one of my co-workers spent hours reproducing and tracking down a bug that turned out to be a stray comma.

Unfortunately, Microsoft Internet Explorer doesn’t support trailing commas in JavaScript arrays and object literals.  Code like this won’t parse:

    var chord = ["do", "mi", "so",];
    var json = { truth:"beauty", beauty:true, };

Those final commas will cause syntax errors in IE.

“How many thousands of developer hours have been lost to random IE bugs like this?” I asked myself. I decided that there had to be a good way to detect this problem in an automated way, without firing up a copy of IE and running a full test suite.

It turns out that these and other syntax errors can be detected automatically from the Windows command line, using the Windows Scripting Host (WSH).  On Windows XP and higher, the command-line tool “cscript.exe” can be used to run JavaScript (ahem, JScript) headlessly (outside of any browser).

Just create a file called “wsh-parser.js” like this:

var fso = new ActiveXObject( "Scripting.FileSystemObject" );

function parse(fname) {
    var file = fso.OpenTextFile( fname, 1 );
    ret = file.ReadAll();
    file.Close();
    try {
        eval("(function(){\n"+ret+"\n});");
    } catch (e) {
        WScript.Echo("Syntax error parsing " + fname);
        WScript.Echo("  " + e.message);
    }
}

function findJavaScript(folder) {
    for (var fc = new Enumerator(folder.files); !fc.atEnd(); fc.moveNext()) {
        var file=fc.item();
        if (/.js$/.test(file.Name)) {
            parse(file);
        }
    }
    for (var fc = new Enumerator(folder.subfolders); !fc.atEnd(); fc.moveNext()) {
        var subfolder = fc.item();
        if (subfolder.Name == ".svn") continue; // ignore .svn folders
        findJavaScript(subfolder);
    }
}

var rootPath = "src/main/javascript";
var rootFolder = fso.GetFolder(rootPath);

findJavaScript(rootFolder);

Then run it like this:

    cscript //E:javascript //nologo wsh-parser.js

The script will automatically examine every JavaScript file in the specified rootPath, reporting errors in any file that won’t parse correctly.

There’s a bit of magic going on here in the “parse” function to guarantee that we’re only verifying the syntax of our JavaScript, without actually running it.  The magic line is:

    eval("(function(){\n"+ret+"\n});");

The “eval” command would normally execute the provided string, but here we wrap the code in an anonymous function declaration.  We improve the performance and the maintainability of our test by declaring the function without actually using it.

Note that you can also use JsLint to detect trailing commas, but it will probably report a bunch of other problems with your code that you may or may not care about.

Automated validators like these should be used together with headless unit tests as well as live browser tests.  (I would recommend Selenium for automated browser tests.  There are a ton of excellent headless JavaScript unit test tools, including Schaible’s JsUnit, RhinoUnit, and DOH.  Note that Hieatt’s JsUnit is not headless.)

But I recommend running automated validators first, because they’re fast and the errors they report are easy to debug/fix.  Once the automated validators are happy, run your unit tests.  When your unit tests pass, run your live browser tests.

Discussion

  • http://www.diversesolutions.com Andrew Mattie

    I feel your pain. Me and my coworker have encountered this same exact issue at least twice now, and it’s certainly been one of the more frustrating things that we’ve had to track down and fix. It’s not just that it doesn’t parse in IE — it doesn’t error either. At least FF w/ Firebug will throw an error when something isn’t right.

    One validator that you didn’t mention, Julien Lecomte’s YUI Compressor (http://www.julienlecomte.net/yuicompressor/), also serves double-duty as a safe JavaScript compression utility. I don’t remember if it specifically addresses the comma issue you mentioned, but it’s well worth tossing it in the mix nonetheless.

  • http://blog.caffeinatedsoftware.com Robbie Paplin

    This is great for stand-alone javascript files, but how do guys validate script that is embedded inside of HTML markup?

  • http://www.discount-nike-dunk-shoes.com nike dunk shoes

    Hhe article's content rich variety which make us move for our mood after reading this article. surprise, here you will find what you want! Recently, I found some wedsites which commodity is colorful of fashion.
    http://www.scarf8.net