Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

108 lines (79 sloc) 2.999 kB

Testing

Narwhal supports the CommonJS Unit Test API 1.0. You can run any unit test script with the "js -m test" command.

js -m test tests/all-tests.js

Some tests include a snippet on the bottom that allows them to self-run, in which case it is sufficient to run the script directly.

js tests/all-tests.js

The boilerplate looks like this:

if (require.main == module)
    require("os").exit(require("test").run(exports));

You can construct your own unit tests by creating a JavaScript module that exports test* functions, and uses the assert module to throw an AssertionError if a test fails.

exports.testFoo = function () {
    assert.ok(true);
    assert.equals(2 + 2, 5, "three sir!");
};

Alternately, if you prefer a test to continue running all test points even after one of the assertions fails, you can use the logging assertion mechansim, which is an assert object with the same API as the assert module that gets quietly passed to your test functions. It is a different logger object for each module.

exports['test my feature'] = function (assert) {
    assert.ok(false);
    assert.ok(true);
};

Customization

The CommonJS Unit Testing specification codifies a very small subset of the components you need for a unit testing framework, so that multiple frameworks can run interoperably. Two of the other pluggable parts are the test logging system and custom syntactic sugar for advanced assertions.

Logging

To have the test runner direct logs to an alternate system, pass an alternate logger object to the test module's run method.

require("test").run(exports, new Log());

The logger object needs to conform to the logger API set out in the test module. That involves providing implementations of the following function properties:

  • pass(message_opt)
  • fail(assertion)
  • error(exception)
  • section(name:String):Log

The assertion object has the following properties:

  • name AssertionError
  • message
  • actual
  • expected
  • operator

Assertions

You can create complex assertions by providing functions that can throw AssertionError. One fashionable technique is to provide a chaining API.

expect(x).is(y);

To enable this simple case:

var assert = require("assert");

var expect = function (actual) {
    var self = {};
    self.is = function (expected, message) {
        if (!is(expected, actual)) {
            throw new assert.AssertionError({
                "expected": expected,
                "actual": actual,
                "message": message,
                "operator": "is"
            });
        }
    };
    return self;
};

// from Caja
function is(x, y) {
    if (x === y) {
        return x !== 0 || 1/x === 1/y;
    } else {
        return x !== x && y !== y;
    }
}
Jump to Line
Something went wrong with that request. Please try again.