/* * This module is not a plain nodeunit test suite, but instead uses the * assert module to ensure a basic level of functionality is present, * allowing the rest of the tests to be written using nodeunit itself. * * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. * Only code on that line will be removed, its mostly to avoid requiring code * that is node specific */ var assert = require('assert'), // @REMOVE_LINE_FOR_BROWSER async = require('../deps/async'), // @REMOVE_LINE_FOR_BROWSER nodeunit = require('../lib/nodeunit'); // @REMOVE_LINE_FOR_BROWSER // NOT A TEST - util function to make testing faster. // retries the assertion until it passes or the timeout is reached, // at which point it throws the assertion error var waitFor = function (fn, timeout, callback, start) { start = start || new Date().getTime(); callback = callback || function () {}; try { fn(); callback(); } catch (e) { if (e instanceof assert.AssertionError) { var now = new Date().getTime(); if (now - start >= timeout) { throw e; } else { async.nextTick(function () { waitFor(fn, timeout, callback, start); }); } } else { throw e; } } }; // TESTS: // Are exported tests actually run? - store completed tests in this variable // for checking later var tests_called = {}; // most basic test that should run, the tests_called object is tested // at the end of this module to ensure the tests were actually run by nodeunit exports.testCalled = function (test) { tests_called.testCalled = true; test.done(); }; // generates test functions for nodeunit assertions var makeTest = function (method, args_pass, args_fail) { return function (test) { var test1_called = false; var test2_called = false; // test pass nodeunit.runTest( 'testname', function (test) { test[method].apply(test, args_pass); test.done(); }, {testDone: function (name, assertions) { assert.equal(assertions.length, 1); assert.equal(assertions.failures(), 0); }}, function () { test1_called = true; } ); // test failure nodeunit.runTest( 'testname', function (test) { test[method].apply(test, args_fail); test.done(); }, {testDone: function (name, assertions) { assert.equal(assertions.length, 1); assert.equal(assertions.failures(), 1); }}, function () { test2_called = true; } ); // ensure tests were run waitFor(function () { assert.ok(test1_called); assert.ok(test2_called); tests_called[method] = true; }, 500, test.done); }; }; // ensure basic assertions are working: exports.testOk = makeTest('ok', [true], [false]); exports.testEquals = makeTest('equals', [1, 1], [1, 2]); exports.testSame = makeTest('same', [{test: 'test'}, {test: 'test'}], [{test: 'test'}, {monkey: 'penguin'}] ); // from the assert module: exports.testEqual = makeTest('equal', [1, 1], [1, 2]); exports.testNotEqual = makeTest('notEqual', [1, 2], [1, 1]); exports.testDeepEqual = makeTest('deepEqual', [{one: 1}, {one: 1}], [{one: 1}, {two: 2}] ); exports.testNotDeepEqual = makeTest('notDeepEqual', [{one: 1}, {two: 2}], [{one: 1}, {one: 1}] ); exports.testStrictEqual = makeTest('strictEqual', [1, 1], [1, true]); exports.testNotStrictEqual = makeTest('notStrictEqual', [true, 1], [1, 1]); exports.testThrows = makeTest('throws', [function () { throw new Error('test'); }], [function () { return; }] ); exports.testThrowsWithReGex = makeTest('throws', [function () { throw new Error('test'); }, /test/], [function () { throw new Error('test'); }, /fail/] ); exports.testThrowsWithErrorValidation = makeTest('throws', [function () { throw new Error('test'); }, function(err) { return true; }], [function () { throw new Error('test'); }, function(err) { return false; }] ); exports.testDoesNotThrows = makeTest('doesNotThrow', [function () { return; }], [function () { throw new Error('test'); }] ); exports.testIfError = makeTest('ifError', [false], [new Error('test')]); exports.testExpect = function (test) { var test1_called = false, test2_called = false, test3_called = false; // correct number of tests run nodeunit.runTest( 'testname', function (test) { test.expect(2); test.ok(true); test.ok(true); test.done(); }, {testDone: function (name, assertions) { test.equals(assertions.length, 2); test.equals(assertions.failures(), 0); }}, function () { test1_called = true; } ); // no tests run nodeunit.runTest( 'testname', function (test) { test.expect(2); test.done(); }, {testDone: function (name, assertions) { test.equals(assertions.length, 1); test.equals(assertions.failures(), 1); }}, function () { test2_called = true; } ); // incorrect number of tests run nodeunit.runTest( 'testname', function (test) { test.expect(2); test.ok(true); test.ok(true); test.ok(true); test.done(); }, {testDone: function (name, assertions) { test.equals(assertions.length, 4); test.equals(assertions.failures(), 1); }}, function () { test3_called = true; } ); // ensure callbacks fired waitFor(function () { assert.ok(test1_called); assert.ok(test2_called); assert.ok(test3_called); tests_called.expect = true; }, 1000, test.done); }; // tests are async, so wait for them to be called waitFor(function () { assert.ok(tests_called.testCalled); assert.ok(tests_called.ok); assert.ok(tests_called.equals); assert.ok(tests_called.same); assert.ok(tests_called.expect); }, 10000);