Saturday, March 9, 2013

The case of the mysterious failing date test

I had such an aha! moment this afternoon that I thought I'd share it.

This test case was failing for me, and I was positive that I hadn't made any changes which would affect that part of the system:


The trick here is when I was running the test: March 9, 2013, at 1:55pm EST. Turns out that tonight is daylight savings, when we "spring ahead" and lose an hour, and of course 23 hours does not a standard day make!


Friday, March 1, 2013

Using StealJS in Jasmine Tests with Grunt

Grunt Jasmine Configuration

In this post, I'll detail how to use StealJS to author Javascript unit tests in Jasmine, and run them from the command line using the headless grunt-contrib-jasmine runner.

If you look in the documentation for grunt-contrib-jasmine, you'll see a section on using a custom template to run tests which use RequireJS as a dependency manager. You'll end up doing the same bit for StealJS, but will use a different template plugin: grunt-template-jasmine-steal.

First, install the necessary plugins into your local grunt project workspace:

npm install grunt-contrib-jasmine --save-dev
npm install grunt-template-jasmine-steal --save-dev

Next, import the tasks into your Gruntfile.js:

grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.registerTask('test', ['connect:test', 'jasmine']);

Finally, define the connect and jasmine plugin configs. Note that I'm setting up the connect plugin to start a local web server on port 8000, for phantomjs to connect to when running the jasmine suite:

var jsFiles = [
    'src/**/*.js',
    '!src/can/**/*.js',
    '!src/steal/**/*.js',
    '!src/thirdparty/**/*.js'
];

connect: {
    test : {
        port : 8000
    }
},

jasmine: {
    tests: {
        src: jsFiles,
        options: {
            specs: 'src/**/*_spec.js',
            host: 'http://127.0.0.1:8000/',
            template: require('grunt-template-jasmine-steal'),
            templateOptions: {
                stealOptions: {
                    stealUrl: '/src/steal/steal.js',
                    baseUrl: ''
                }
            }
        }
    }
}

Take note of the jsFiles variable I defined; that concisely lists all of my javascript source files, excluding libraries.

Cleaning and Linting your Sources

Another important build step is to clean and lint (error check and validate) your code, and thankfully grunt makes this easy on us. I use the jsbeautifier and grunt-contrib-jshint plugins for this:

grunt.loadNpmTasks('grunt-jsbeautifier');
grunt.loadNpmTasks('grunt-contrib-jshint');

        jsbeautifier : {
          files : jsFiles
        },

        jshint: {
            files: jsFiles,
            options: {
                jshintrc: '.jshintrc'
            },
        },

Note: look at the documentation for jsbeautifier to see the available configuration options (the defaults work fine for me out of the box).

Putting it All Together

Here is a complete Gruntfile.js and .jshintrc, detailing what I went through in detail above. I've set it so that the default grunt task performs the code formatting, checks using jshint, and then runs the full jasmine test suite.




A deferred loading cache in Javascript

I was playing around with jQuery deferreds the other day, and thought up a neat use for them, in a client-side ajax response cache. I created a simple expiring cache abstraction, and then wrote a 'loading' cache around it, which populates the cache with $.Deferred instances which are resolved with the result of a $.get.

Here's the simple expiring cache:




And here's the deferred loading cache:




Jasmine spec for the loading cache:




In my next post, I'll show how to use a jasmine spec runner for steal to run jasmine steal specs in grunt.