diff --git a/test/runner b/test/runner index 4a4e9a3dfb..7505599321 100755 --- a/test/runner +++ b/test/runner @@ -5,38 +5,8 @@ var nodeunit = require('nodeunit'), path = require('path'), AssertionError = require('assert').AssertionError; -var optimist = require('optimist') - .usage('Run the jsdom test suite') - .alias('s', 'suites') - .string('s') - .describe('s', 'suites that you want to run. ie: -s level1/core,1/html,html') - .alias('f', 'fail-fast') - .describe('f', 'stop on the first failed test') - .alias('h', 'help') - .describe('h', 'show the help') - .alias('t', 'tests') - .describe('t', 'choose the test cases to run. ie: -t jquery') - .alias('d', 'debug') - .describe('d', 'run in node\'s interactive debugger mode') - .alias('p', 'parser') - .describe('p', 'the HTML parser to use (e.g. html5); default is htmlparser') - .alias('v', 'verbose') - .describe('v', 'show all tests that are being run'); +var argv = require('./runner-options'); -var argv = optimist.argv; -if (argv.help) { - optimist.showHelp(); - process.exit(); -} - - -var totalTests = 0; -var failedTests = 0; -var passedTests = 0; -var modules = {}; -var currentModule = ""; -var moduleIndex = 0; -var start = new Date().getTime(); var fileFilter = []; var testFilter = []; @@ -51,28 +21,6 @@ if (argv.tests) { testFilter = argv.tests.replace(/\s/g, '').split(','); } -var assert = require('nodeunit/lib/assert'); -require('nodeunit/lib/assert').equal = function equal(actual, expected, message) { - if (actual != expected) { - if (actual && actual.nodeType) { - actual = actual.toString(); - } - - if (expected && expected.nodeType) { - expected = expected.toString(); - } - - assert.fail(actual, expected, message, '==', assert.equal); - } -}; - -assert.domSame = function(actual, expected, message) { - if(expected != actual) { - assert.equal(expected.nodeType, actual.nodeType); - assert.equal(expected.nodeValue, actual.nodeValue); - } -}; - var files = [ "level1/core.js", "level1/html.js", @@ -155,148 +103,5 @@ if (argv.parser) { browser.setDefaultParser(argv.parser); } -nodeunit.runModules(modulesToRun, { - moduleStart: function (name) { - currentModule = name.replace('.js', ''); - console.log("running", name, currentModule); - modules[currentModule] = { - total : 0, - fail : 0, - pass : 0 - }; - moduleIndex++; - }, - moduleDone: function (name, assertions) { - if (argv['verbose']) { - console.log(' '); - } - }, - testStart: function (test) { - modules[currentModule].total++; - if (argv['verbose']) { - process.stdout.write(' ' + test[0] + ' ...'); - } - }, - testDone: function (test, assertions) { - if (argv['verbose']) { - console.log(' done'); - } - totalTests++; - if (!assertions.failures()) { - passedTests++; - modules[currentModule].pass++; - } - else { - failedTests++; - modules[currentModule].fail++; - - console.log('✖ ' + currentModule + '/' + test); - assertions.forEach(function (a) { - if (a.failed()) { - if (a.error instanceof AssertionError) { - a = nodeunit.utils.betterErrors(a); - if (a.message) { - console.log( - 'Assertion Message: ' + assertion_message(a.message) + '\n' + - 'expected:', a.error.expected, 'got:', a.error.actual - ); - } - } else { - if (a.error.expected || a.error.actual) { - console.log('\nERROR', a.error.expected, 'vs', a.error.actual, '\n'); - } - - console.log(a.error.message, a.error.stack, (new Error()).stack); - } - } else { - console.log(a.message); - } - }); - - if (argv['fail-fast']) { - process.exit(); - } - } - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - var maxWidths = { - name : 0, - ratio : 0, - percent : 4 - }; - var width = 0; - var keys = Object.keys(modules); - - var calculateMax = function(name, value) { - if (!maxWidths[name] || value.length > maxWidths[name]) { - maxWidths[name] = value.length; - } - - width = 2; - Object.keys(maxWidths).forEach(function(v) { - width += maxWidths[v] + 2; - }); - } - - var pad = function(name, value, rightJustified) { - var ret = ''; - var padding = ''; - - var amount = maxWidths[name] - value.length; - while(amount--) { - padding += " "; - } - - if (rightJustified) { - return ' ' + padding + value + ' '; - } else { - return ' ' + value + padding + ' '; - } - } - - // First pass, calculate the max widths - keys.forEach(function(v) { - var module = modules[v]; - var ratio = module.pass + '/' + module.total; - var percentage = Math.floor((module.pass/module.total)*100) + '%'; - modules[v].ratio = ratio; - modules[v].percentage = percentage; - calculateMax('name', v); - calculateMax('ratio', ratio); - calculateMax('percentage', percentage); - }); - - var caps = ''; - var gen = width; - - while(gen--) { - caps += '-'; - } - - console.log(''); - Object.keys(modules).forEach(function(v) { - var module = modules[v]; - process.stdout.write(pad('name', v, false)); - process.stdout.write(pad('ratio', module.ratio, true)); - process.stdout.write(pad('percentage', module.percentage, true)); - process.stdout.write('\n'); - }); - console.log(caps); - var ratio = failedTests + '/' + totalTests; - var percent = 0; - if (totalTests === 0) { - percent = '100%'; - } else { - percent = Math.floor((passedTests/totalTests)*100) + '%'; - } - console.log('TOTALS: %s failed; %s success', ratio, percent); - console.log('TIME: %dms', duration); - - if (passedTests !== totalTests) { - process.exit(1); - } - - } -}); +var runner = require('./runner-core')(modulesToRun); +require('./runner-display')(runner, argv); diff --git a/test/runner-core.js b/test/runner-core.js new file mode 100644 index 0000000000..ef503c85ab --- /dev/null +++ b/test/runner-core.js @@ -0,0 +1,57 @@ +var EventEmitter = require('events').EventEmitter; +var nodeunit = require('nodeunit'); + +var assert = require('nodeunit/lib/assert'); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) { + if (actual && actual.nodeType) { + actual = actual.toString(); + } + + if (expected && expected.nodeType) { + expected = expected.toString(); + } + + assert.fail(actual, expected, message, '==', assert.equal); + } +}; + +assert.domSame = function(actual, expected, message) { + if(expected != actual) { + assert.equal(expected.nodeType, actual.nodeType); + assert.equal(expected.nodeValue, actual.nodeValue); + } +}; + +module.exports = function runModules(toRun) { + var emitter = new EventEmitter(); + + process.nextTick(function () { + nodeunit.runModules(toRun, { + moduleStart: function (name) { + emitter.emit('moduleStart', name); + }, + moduleDone: function (name, assertions) { + emitter.emit('moduleDone', name, assertions); + }, + testStart: function (name) { + emitter.emit('testStart', name); + }, + testReady: function (name) { + emitter.emit('testReady', name); + }, + testDone: function (test, assertions) { + emitter.emit('testDone', test, assertions); + }, + log: function (assertion) { + emitter.emit('log', assertion); + }, + done: function (assertions) { + emitter.emit('done', assertions); + } + }); + }); + + return emitter; +}; diff --git a/test/runner-display.js b/test/runner-display.js new file mode 100644 index 0000000000..87960d7f90 --- /dev/null +++ b/test/runner-display.js @@ -0,0 +1,165 @@ +var AssertionError = require('assert').AssertionError; + +var totalTests = 0; +var failedTests = 0; +var passedTests = 0; +var modules = {}; +var currentModule = ""; +var moduleIndex = 0; +var start; +var argv; + +var runnerHandlers = { + moduleStart: function (name) { + currentModule = name.replace('.js', ''); + console.log("running", name, currentModule); + modules[currentModule] = { + total : 0, + fail : 0, + pass : 0 + }; + moduleIndex++; + }, + moduleDone: function (name, assertions) { + if (argv['verbose']) { + console.log(' '); + } + }, + testStart: function (test) { + modules[currentModule].total++; + if (argv['verbose']) { + process.stdout.write(' ' + test[0] + ' ...'); + } + }, + testDone: function (test, assertions) { + if (argv['verbose']) { + console.log(' done'); + } + totalTests++; + if (!assertions.failures()) { + passedTests++; + modules[currentModule].pass++; + } + else { + failedTests++; + modules[currentModule].fail++; + + console.log('✖ ' + currentModule + '/' + test); + assertions.forEach(function (a) { + if (a.failed()) { + if (a.error instanceof AssertionError) { + a = nodeunit.utils.betterErrors(a); + if (a.message) { + console.log( + 'Assertion Message: ' + assertion_message(a.message) + '\n' + + 'expected:', a.error.expected, 'got:', a.error.actual + ); + } + } else { + if (a.error.expected || a.error.actual) { + console.log('\nERROR', a.error.expected, 'vs', a.error.actual, '\n'); + } + + console.log(a.error.message, a.error.stack, (new Error()).stack); + } + } else { + console.log(a.message); + } + }); + + if (argv['fail-fast']) { + process.exit(); + } + } + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + var maxWidths = { + name : 0, + ratio : 0, + percent : 4 + }; + var width = 0; + var keys = Object.keys(modules); + + var calculateMax = function(name, value) { + if (!maxWidths[name] || value.length > maxWidths[name]) { + maxWidths[name] = value.length; + } + + width = 2; + Object.keys(maxWidths).forEach(function(v) { + width += maxWidths[v] + 2; + }); + } + + var pad = function(name, value, rightJustified) { + var ret = ''; + var padding = ''; + + var amount = maxWidths[name] - value.length; + while(amount--) { + padding += " "; + } + + if (rightJustified) { + return ' ' + padding + value + ' '; + } else { + return ' ' + value + padding + ' '; + } + } + + // First pass, calculate the max widths + keys.forEach(function(v) { + var module = modules[v]; + var ratio = module.pass + '/' + module.total; + var percentage = Math.floor((module.pass/module.total)*100) + '%'; + modules[v].ratio = ratio; + modules[v].percentage = percentage; + calculateMax('name', v); + calculateMax('ratio', ratio); + calculateMax('percentage', percentage); + }); + + var caps = ''; + var gen = width; + + while(gen--) { + caps += '-'; + } + + console.log(''); + Object.keys(modules).forEach(function(v) { + var module = modules[v]; + process.stdout.write(pad('name', v, false)); + process.stdout.write(pad('ratio', module.ratio, true)); + process.stdout.write(pad('percentage', module.percentage, true)); + process.stdout.write('\n'); + }); + console.log(caps); + var ratio = failedTests + '/' + totalTests; + var percent = 0; + if (totalTests === 0) { + percent = '100%'; + } else { + percent = Math.floor((passedTests/totalTests)*100) + '%'; + } + console.log('TOTALS: %s failed; %s success', ratio, percent); + console.log('TIME: %dms', duration); + + if (passedTests !== totalTests) { + process.exit(1); + } + + } +}; + +module.exports = function (runner, args) { + argv = args; + start = new Date().getTime(); + + Object.keys(runnerHandlers).forEach(function (event) { + runner.on(event, runnerHandlers[event]); + }); +}; diff --git a/test/runner-options.js b/test/runner-options.js new file mode 100644 index 0000000000..f184af594d --- /dev/null +++ b/test/runner-options.js @@ -0,0 +1,25 @@ +var optimist = require('optimist') + .usage('Run the jsdom test suite') + .alias('s', 'suites') + .string('s') + .describe('s', 'suites that you want to run. ie: -s level1/core,1/html,html') + .alias('f', 'fail-fast') + .describe('f', 'stop on the first failed test') + .alias('h', 'help') + .describe('h', 'show the help') + .alias('t', 'tests') + .describe('t', 'choose the test cases to run. ie: -t jquery') + .alias('d', 'debug') + .describe('d', 'run in node\'s interactive debugger mode') + .alias('p', 'parser') + .describe('p', 'the HTML parser to use (e.g. html5); default is htmlparser') + .alias('v', 'verbose') + .describe('v', 'show all tests that are being run'); + +var argv = optimist.argv; +if (argv.help) { + optimist.showHelp(); + process.exit(); +} + +module.exports = argv;