-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring a lot. Use original qunit now which will solve a lot of bugs
- Loading branch information
Showing
15 changed files
with
762 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[submodule "deps/jscoverage"] | ||
path = deps/jscoverage | ||
url = http://github.com/visionmedia/node-jscoverage.git | ||
[submodule "deps/qunit"] | ||
path = deps/qunit | ||
url = https://github.com/jquery/qunit.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
module.exports = require("./lib/qunit"); | ||
module.exports = require("./lib/testrunner"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
var path = require('path'), | ||
$ = require('sharedjs'), | ||
options = JSON.parse(process.argv[2]); | ||
|
||
var currentModule = path.basename(options.code.path, '.js'), | ||
currentTest; | ||
|
||
// make qunit api global, like it is in the browser | ||
$.extend(global, require('../deps/qunit/qunit/qunit')); | ||
|
||
function load(res) { | ||
var requirePath = res.path.replace(/\.js$/, ''); | ||
|
||
// test resource can define'namespace'to expose its exports as a named object | ||
if (res.namespace) { | ||
global[res.namespace] = require(requirePath); | ||
} else { | ||
$.extend(global, require(requirePath)); | ||
} | ||
} | ||
|
||
// add paths to require | ||
if (options.paths){ | ||
require.paths.push.apply(require.paths, options.paths); | ||
} | ||
|
||
QUnit.testStart = function(test) { | ||
// currentTest is undefined while first test is not done yet | ||
currentTest = test.name; | ||
// use last module name if no module name defined | ||
currentModule = test.module || currentModule; | ||
}; | ||
|
||
QUnit.log = function(data) { | ||
data.test = currentTest; | ||
data.module = currentModule; | ||
|
||
process.send({ | ||
event: 'assertionDone', | ||
data: data | ||
}); | ||
}; | ||
|
||
QUnit.testDone = function(test) { | ||
// use last module name if no module name defined | ||
test.module = test.module || currentModule; | ||
|
||
process.send({ | ||
event: 'testDone', | ||
data: test | ||
}); | ||
}; | ||
|
||
QUnit.done = function done(res) { | ||
// XXX don't know why, but qunit fires a lot of done callbacks, | ||
// but only the last one has correct data #wtf | ||
clearTimeout(done.timeout); | ||
done.timeout = setTimeout(function() { | ||
process.send({ | ||
event: 'done', | ||
data: res | ||
}); | ||
}, 300); | ||
}; | ||
|
||
|
||
// require deps | ||
options.deps.forEach(load); | ||
// require code | ||
load(options.code); | ||
// require tests | ||
options.tests.forEach(load); | ||
|
||
QUnit.begin(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
var util = require('util'), | ||
Table = require('cli-table'); | ||
|
||
var logs = { | ||
assertions: { | ||
data: [], | ||
table: null | ||
}, | ||
tests: { | ||
data: [], | ||
table: null | ||
}, | ||
summary: { | ||
data: [], | ||
table: null | ||
} | ||
}; | ||
|
||
exports.assertion = (function() { | ||
var table, | ||
currentModule, module, | ||
currentTest, test; | ||
|
||
table = logs.assertions.table = new Table({ | ||
head: ['Module', 'Test', 'Assertion', 'Result'], | ||
colWidths: [40, 40, 40, 8] | ||
}); | ||
|
||
return function(data) { | ||
// just easier to read the table | ||
if (data.module === currentModule) { | ||
module = ''; | ||
} else { | ||
module = currentModule = data.module; | ||
} | ||
|
||
// just easier to read the table | ||
if (data.test === currentTest) { | ||
test = ''; | ||
} else { | ||
test = currentTest = data.test; | ||
} | ||
|
||
table.push([module, test, data.message, data.result ? 'ok' : 'fail']); | ||
|
||
logs.assertions.data.push(data); | ||
}; | ||
}()); | ||
|
||
exports.test = (function() { | ||
var table, | ||
currentModule, module; | ||
|
||
table = logs.tests.table = new Table({ | ||
head: ['Module', 'Test', 'Failed', 'Passed', 'Total'], | ||
colWidths: [40, 40, 8, 8, 8] | ||
}); | ||
|
||
return function(data) { | ||
// just easier to read the table | ||
if (data.module === currentModule) { | ||
module = ''; | ||
} else { | ||
module = currentModule = data.module; | ||
} | ||
|
||
table.push([module, data.name, data.failed, data.passed, data.total]); | ||
|
||
logs.tests.data.push(data); | ||
}; | ||
}()); | ||
|
||
exports.summary = (function() { | ||
var table = logs.summary.table = new Table({ | ||
head: ['Failed', 'Passed', 'Total', 'Runtime'], | ||
colWidths: [10, 10, 10, 10] | ||
}); | ||
|
||
return function(data) { | ||
table.push([data.failed, data.passed, data.total, data.runtime]); | ||
|
||
logs.summary.data.push(data); | ||
}; | ||
}()); | ||
|
||
exports.print = function(name) { | ||
if (logs[name].data.length) { | ||
var upperName = name.charAt(0).toUpperCase() + name.substr(1); | ||
|
||
util.print('\n' + upperName + '\n' + logs[name].table.toString() + '\n'); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
var fs = require('fs'), | ||
path = require('path'), | ||
coverage = require('./coverage'), | ||
cp = require('child_process'), | ||
log = require('./log'); | ||
|
||
var options = exports.options = { | ||
assertions: false, | ||
tests: false, | ||
summary: true, | ||
coverage: true, | ||
paths: null, | ||
deps: null | ||
}; | ||
|
||
/** | ||
* Run one spawned instance with tests | ||
* @param {Object} opts | ||
* @param {Object} report | ||
* @param {Function} callback | ||
*/ | ||
function runOne(opts, callback) { | ||
var child; | ||
|
||
child = cp.fork( | ||
__dirname + '/child.js', | ||
[JSON.stringify(opts)], | ||
{customFds: [0, -1, -1]} | ||
); | ||
|
||
// forward stderr and stdout streams from the child | ||
child.stdout.pipe(process.stdout); | ||
child.stderr.pipe(process.stderr); | ||
|
||
child.on('message', function(msg) { | ||
if (msg.event === 'assertionDone') { | ||
log.assertion(msg.data); | ||
} else if (msg.event === 'testDone') { | ||
log.test(msg.data); | ||
} else if (msg.event === 'done') { | ||
log.summary(msg.data); | ||
|
||
child.kill(); | ||
|
||
if (typeof callback === 'function') { | ||
callback(); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Make an absolute path from relative | ||
* @param {String|Object} file | ||
* @return {Object} | ||
*/ | ||
function absPath(file) { | ||
if (typeof file === 'string') { | ||
file = {path: file}; | ||
} | ||
|
||
if(file.path.charAt(0) === '.') { | ||
file.path = path.join(process.cwd(), file.path); | ||
} | ||
|
||
return file; | ||
} | ||
|
||
/** | ||
* Convert path or array of paths to array of abs paths | ||
* @param {Array|String} files | ||
* @return {Array} | ||
*/ | ||
function toArray(files) { | ||
var ret = []; | ||
|
||
if (Array.isArray(files)) { | ||
files.forEach(function(file) { | ||
ret.push(absPath(file)); | ||
}); | ||
} else if (files) { | ||
ret.push(absPath(files)); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
/** | ||
* Run tests in spawned node instance async for every test. | ||
* @param {Object|Array} files | ||
* @param {Function} callback optional | ||
*/ | ||
exports.run = function(files, callback) { | ||
if (!Array.isArray(files)) { | ||
files = [files]; | ||
} | ||
|
||
var report = { | ||
files: 0, | ||
tests: 0, | ||
assertions: 0, | ||
errors: 0, | ||
success: 0, | ||
time: Date.now() | ||
}; | ||
|
||
files.forEach(function(opts) { | ||
|
||
opts = { | ||
deps: toArray(opts.deps || options.deps), | ||
code: absPath(opts.code), | ||
tests: toArray(opts.tests), | ||
paths: opts.paths || options.paths, | ||
coverage: opts.coverage || options.coverage | ||
}; | ||
|
||
function finished(cov) { | ||
if (report.files < files.length) { | ||
return; | ||
} | ||
|
||
if (options.assertions) { | ||
log.print('assertions'); | ||
} | ||
|
||
if (options.tests) { | ||
log.print('tests'); | ||
} | ||
|
||
if (options.summary) { | ||
log.print('summary'); | ||
} | ||
|
||
if (typeof callback === 'function') { | ||
callback(report); | ||
} | ||
} | ||
|
||
if (opts.coverage) { | ||
|
||
} else { | ||
runOne(opts, report, finished); | ||
} | ||
}); | ||
}; |
Oops, something went wrong.