Skip to content

Commit

Permalink
Break apart test options, runner and display
Browse files Browse the repository at this point in the history
For jsdom#711, the test runner will execute in a web worker, but test results will be
displayed in the parent page or a shell. So, it is convenient to break the
options parsing, test running, and results display into their own modules for
reuse by other runners.
  • Loading branch information
lawnsea committed Jul 30, 2014
1 parent 049a523 commit 7e7222e
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 198 deletions.
201 changes: 3 additions & 198 deletions test/runner
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];

Expand All @@ -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",
Expand Down Expand Up @@ -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);
57 changes: 57 additions & 0 deletions test/runner-core.js
Original file line number Diff line number Diff line change
@@ -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;
};
Loading

0 comments on commit 7e7222e

Please sign in to comment.