initial commit
This commit is contained in:
464
node_modules/mocha/lib/reporters/base.js
generated
vendored
Normal file
464
node_modules/mocha/lib/reporters/base.js
generated
vendored
Normal file
@ -0,0 +1,464 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var tty = require('tty')
|
||||
, diff = require('diff')
|
||||
, ms = require('../ms')
|
||||
, utils = require('../utils')
|
||||
, supportsColor = process.env ? require('supports-color') : null;
|
||||
|
||||
/**
|
||||
* Save timer references to avoid Sinon interfering (see GH-237).
|
||||
*/
|
||||
|
||||
var Date = global.Date
|
||||
, setTimeout = global.setTimeout
|
||||
, setInterval = global.setInterval
|
||||
, clearTimeout = global.clearTimeout
|
||||
, clearInterval = global.clearInterval;
|
||||
|
||||
/**
|
||||
* Check if both stdio streams are associated with a tty.
|
||||
*/
|
||||
|
||||
var isatty = tty.isatty(1) && tty.isatty(2);
|
||||
|
||||
/**
|
||||
* Expose `Base`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Base;
|
||||
|
||||
/**
|
||||
* Enable coloring by default, except in the browser interface.
|
||||
*/
|
||||
|
||||
exports.useColors = process.env
|
||||
? (supportsColor || (process.env.MOCHA_COLORS !== undefined))
|
||||
: false;
|
||||
|
||||
/**
|
||||
* Inline diffs instead of +/-
|
||||
*/
|
||||
|
||||
exports.inlineDiffs = false;
|
||||
|
||||
/**
|
||||
* Default color map.
|
||||
*/
|
||||
|
||||
exports.colors = {
|
||||
'pass': 90
|
||||
, 'fail': 31
|
||||
, 'bright pass': 92
|
||||
, 'bright fail': 91
|
||||
, 'bright yellow': 93
|
||||
, 'pending': 36
|
||||
, 'suite': 0
|
||||
, 'error title': 0
|
||||
, 'error message': 31
|
||||
, 'error stack': 90
|
||||
, 'checkmark': 32
|
||||
, 'fast': 90
|
||||
, 'medium': 33
|
||||
, 'slow': 31
|
||||
, 'green': 32
|
||||
, 'light': 90
|
||||
, 'diff gutter': 90
|
||||
, 'diff added': 42
|
||||
, 'diff removed': 41
|
||||
};
|
||||
|
||||
/**
|
||||
* Default symbol map.
|
||||
*/
|
||||
|
||||
exports.symbols = {
|
||||
ok: '✓',
|
||||
err: '✖',
|
||||
dot: '․'
|
||||
};
|
||||
|
||||
// With node.js on Windows: use symbols available in terminal default fonts
|
||||
if ('win32' == process.platform) {
|
||||
exports.symbols.ok = '\u221A';
|
||||
exports.symbols.err = '\u00D7';
|
||||
exports.symbols.dot = '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Color `str` with the given `type`,
|
||||
* allowing colors to be disabled,
|
||||
* as well as user-defined color
|
||||
* schemes.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var color = exports.color = function(type, str) {
|
||||
if (!exports.useColors) return String(str);
|
||||
return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose term window size, with some
|
||||
* defaults for when stderr is not a tty.
|
||||
*/
|
||||
|
||||
exports.window = {
|
||||
width: isatty
|
||||
? process.stdout.getWindowSize
|
||||
? process.stdout.getWindowSize(1)[0]
|
||||
: tty.getWindowSize()[1]
|
||||
: 75
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose some basic cursor interactions
|
||||
* that are common among reporters.
|
||||
*/
|
||||
|
||||
exports.cursor = {
|
||||
hide: function(){
|
||||
isatty && process.stdout.write('\u001b[?25l');
|
||||
},
|
||||
|
||||
show: function(){
|
||||
isatty && process.stdout.write('\u001b[?25h');
|
||||
},
|
||||
|
||||
deleteLine: function(){
|
||||
isatty && process.stdout.write('\u001b[2K');
|
||||
},
|
||||
|
||||
beginningOfLine: function(){
|
||||
isatty && process.stdout.write('\u001b[0G');
|
||||
},
|
||||
|
||||
CR: function(){
|
||||
if (isatty) {
|
||||
exports.cursor.deleteLine();
|
||||
exports.cursor.beginningOfLine();
|
||||
} else {
|
||||
process.stdout.write('\r');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Outut the given `failures` as a list.
|
||||
*
|
||||
* @param {Array} failures
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.list = function(failures){
|
||||
console.log();
|
||||
failures.forEach(function(test, i){
|
||||
// format
|
||||
var fmt = color('error title', ' %s) %s:\n')
|
||||
+ color('error message', ' %s')
|
||||
+ color('error stack', '\n%s\n');
|
||||
|
||||
// msg
|
||||
var err = test.err
|
||||
, message = err.message || ''
|
||||
, stack = err.stack || message
|
||||
, index = stack.indexOf(message)
|
||||
, actual = err.actual
|
||||
, expected = err.expected
|
||||
, escape = true;
|
||||
if (index === -1) {
|
||||
msg = message;
|
||||
} else {
|
||||
index += message.length;
|
||||
msg = stack.slice(0, index);
|
||||
// remove msg from stack
|
||||
stack = stack.slice(index + 1);
|
||||
}
|
||||
|
||||
// uncaught
|
||||
if (err.uncaught) {
|
||||
msg = 'Uncaught ' + msg;
|
||||
}
|
||||
// explicitly show diff
|
||||
if (err.showDiff !== false && sameType(actual, expected)
|
||||
&& expected !== undefined) {
|
||||
|
||||
escape = false;
|
||||
err.actual = actual = utils.stringify(actual);
|
||||
err.expected = expected = utils.stringify(expected);
|
||||
|
||||
fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
|
||||
var match = message.match(/^([^:]+): expected/);
|
||||
msg = '\n ' + color('error message', match ? match[1] : msg);
|
||||
|
||||
if (exports.inlineDiffs) {
|
||||
msg += inlineDiff(err, escape);
|
||||
} else {
|
||||
msg += unifiedDiff(err, escape);
|
||||
}
|
||||
}
|
||||
|
||||
// indent stack trace
|
||||
stack = stack.replace(/^/gm, ' ');
|
||||
|
||||
console.log(fmt, (i + 1), test.fullTitle(), msg, stack);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a new `Base` reporter.
|
||||
*
|
||||
* All other reporters generally
|
||||
* inherit from this reporter, providing
|
||||
* stats such as test duration, number
|
||||
* of tests passed / failed etc.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Base(runner) {
|
||||
var self = this
|
||||
, stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
|
||||
, failures = this.failures = [];
|
||||
|
||||
if (!runner) return;
|
||||
this.runner = runner;
|
||||
|
||||
runner.stats = stats;
|
||||
|
||||
runner.on('start', function(){
|
||||
stats.start = new Date;
|
||||
});
|
||||
|
||||
runner.on('suite', function(suite){
|
||||
stats.suites = stats.suites || 0;
|
||||
suite.root || stats.suites++;
|
||||
});
|
||||
|
||||
runner.on('test end', function(test){
|
||||
stats.tests = stats.tests || 0;
|
||||
stats.tests++;
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
stats.passes = stats.passes || 0;
|
||||
|
||||
var medium = test.slow() / 2;
|
||||
test.speed = test.duration > test.slow()
|
||||
? 'slow'
|
||||
: test.duration > medium
|
||||
? 'medium'
|
||||
: 'fast';
|
||||
|
||||
stats.passes++;
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
stats.failures = stats.failures || 0;
|
||||
stats.failures++;
|
||||
test.err = err;
|
||||
failures.push(test);
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
stats.end = new Date;
|
||||
stats.duration = new Date - stats.start;
|
||||
});
|
||||
|
||||
runner.on('pending', function(){
|
||||
stats.pending++;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Output common epilogue used by many of
|
||||
* the bundled reporters.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Base.prototype.epilogue = function(){
|
||||
var stats = this.stats;
|
||||
var tests;
|
||||
var fmt;
|
||||
|
||||
console.log();
|
||||
|
||||
// passes
|
||||
fmt = color('bright pass', ' ')
|
||||
+ color('green', ' %d passing')
|
||||
+ color('light', ' (%s)');
|
||||
|
||||
console.log(fmt,
|
||||
stats.passes || 0,
|
||||
ms(stats.duration));
|
||||
|
||||
// pending
|
||||
if (stats.pending) {
|
||||
fmt = color('pending', ' ')
|
||||
+ color('pending', ' %d pending');
|
||||
|
||||
console.log(fmt, stats.pending);
|
||||
}
|
||||
|
||||
// failures
|
||||
if (stats.failures) {
|
||||
fmt = color('fail', ' %d failing');
|
||||
|
||||
console.log(fmt, stats.failures);
|
||||
|
||||
Base.list(this.failures);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log();
|
||||
};
|
||||
|
||||
/**
|
||||
* Pad the given `str` to `len`.
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {String} len
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function pad(str, len) {
|
||||
str = String(str);
|
||||
return Array(len - str.length + 1).join(' ') + str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an inline diff between 2 strings with coloured ANSI output
|
||||
*
|
||||
* @param {Error} Error with actual/expected
|
||||
* @return {String} Diff
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function inlineDiff(err, escape) {
|
||||
var msg = errorDiff(err, 'WordsWithSpace', escape);
|
||||
|
||||
// linenos
|
||||
var lines = msg.split('\n');
|
||||
if (lines.length > 4) {
|
||||
var width = String(lines.length).length;
|
||||
msg = lines.map(function(str, i){
|
||||
return pad(++i, width) + ' |' + ' ' + str;
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
// legend
|
||||
msg = '\n'
|
||||
+ color('diff removed', 'actual')
|
||||
+ ' '
|
||||
+ color('diff added', 'expected')
|
||||
+ '\n\n'
|
||||
+ msg
|
||||
+ '\n';
|
||||
|
||||
// indent
|
||||
msg = msg.replace(/^/gm, ' ');
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unified diff between 2 strings
|
||||
*
|
||||
* @param {Error} Error with actual/expected
|
||||
* @return {String} Diff
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function unifiedDiff(err, escape) {
|
||||
var indent = ' ';
|
||||
function cleanUp(line) {
|
||||
if (escape) {
|
||||
line = escapeInvisibles(line);
|
||||
}
|
||||
if (line[0] === '+') return indent + colorLines('diff added', line);
|
||||
if (line[0] === '-') return indent + colorLines('diff removed', line);
|
||||
if (line.match(/\@\@/)) return null;
|
||||
if (line.match(/\\ No newline/)) return null;
|
||||
else return indent + line;
|
||||
}
|
||||
function notBlank(line) {
|
||||
return line != null;
|
||||
}
|
||||
var msg = diff.createPatch('string', err.actual, err.expected);
|
||||
var lines = msg.split('\n').splice(4);
|
||||
return '\n '
|
||||
+ colorLines('diff added', '+ expected') + ' '
|
||||
+ colorLines('diff removed', '- actual')
|
||||
+ '\n\n'
|
||||
+ lines.map(cleanUp).filter(notBlank).join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a character diff for `err`.
|
||||
*
|
||||
* @param {Error} err
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function errorDiff(err, type, escape) {
|
||||
var actual = escape ? escapeInvisibles(err.actual) : err.actual;
|
||||
var expected = escape ? escapeInvisibles(err.expected) : err.expected;
|
||||
return diff['diff' + type](actual, expected).map(function(str){
|
||||
if (str.added) return colorLines('diff added', str.value);
|
||||
if (str.removed) return colorLines('diff removed', str.value);
|
||||
return str.value;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with all invisible characters in plain text
|
||||
*
|
||||
* @param {String} line
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
function escapeInvisibles(line) {
|
||||
return line.replace(/\t/g, '<tab>')
|
||||
.replace(/\r/g, '<CR>')
|
||||
.replace(/\n/g, '<LF>\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Color lines for `str`, using the color `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function colorLines(name, str) {
|
||||
return str.split('\n').map(function(str){
|
||||
return color(name, str);
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a / b have the same type.
|
||||
*
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function sameType(a, b) {
|
||||
a = Object.prototype.toString.call(a);
|
||||
b = Object.prototype.toString.call(b);
|
||||
return a == b;
|
||||
}
|
62
node_modules/mocha/lib/reporters/doc.js
generated
vendored
Normal file
62
node_modules/mocha/lib/reporters/doc.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Expose `Doc`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Doc;
|
||||
|
||||
/**
|
||||
* Initialize a new `Doc` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Doc(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, total = runner.total
|
||||
, indents = 2;
|
||||
|
||||
function indent() {
|
||||
return Array(indents).join(' ');
|
||||
}
|
||||
|
||||
runner.on('suite', function(suite){
|
||||
if (suite.root) return;
|
||||
++indents;
|
||||
console.log('%s<section class="suite">', indent());
|
||||
++indents;
|
||||
console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
|
||||
console.log('%s<dl>', indent());
|
||||
});
|
||||
|
||||
runner.on('suite end', function(suite){
|
||||
if (suite.root) return;
|
||||
console.log('%s</dl>', indent());
|
||||
--indents;
|
||||
console.log('%s</section>', indent());
|
||||
--indents;
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
|
||||
var code = utils.escape(utils.clean(test.fn.toString()));
|
||||
console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
console.log('%s <dt class="error">%s</dt>', indent(), utils.escape(test.title));
|
||||
var code = utils.escape(utils.clean(test.fn.toString()));
|
||||
console.log('%s <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
|
||||
console.log('%s <dd class="error">%s</dd>', indent(), utils.escape(err));
|
||||
});
|
||||
}
|
62
node_modules/mocha/lib/reporters/dot.js
generated
vendored
Normal file
62
node_modules/mocha/lib/reporters/dot.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `Dot`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Dot;
|
||||
|
||||
/**
|
||||
* Initialize a new `Dot` matrix test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Dot(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, width = Base.window.width * .75 | 0
|
||||
, n = -1;
|
||||
|
||||
runner.on('start', function(){
|
||||
process.stdout.write('\n');
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
if (++n % width == 0) process.stdout.write('\n ');
|
||||
process.stdout.write(color('pending', Base.symbols.dot));
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
if (++n % width == 0) process.stdout.write('\n ');
|
||||
if ('slow' == test.speed) {
|
||||
process.stdout.write(color('bright yellow', Base.symbols.dot));
|
||||
} else {
|
||||
process.stdout.write(color(test.speed, Base.symbols.dot));
|
||||
}
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
if (++n % width == 0) process.stdout.write('\n ');
|
||||
process.stdout.write(color('fail', Base.symbols.dot));
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
console.log();
|
||||
self.epilogue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
Dot.prototype.__proto__ = Base.prototype;
|
50
node_modules/mocha/lib/reporters/html-cov.js
generated
vendored
Normal file
50
node_modules/mocha/lib/reporters/html-cov.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var JSONCov = require('./json-cov')
|
||||
, fs = require('fs');
|
||||
|
||||
/**
|
||||
* Expose `HTMLCov`.
|
||||
*/
|
||||
|
||||
exports = module.exports = HTMLCov;
|
||||
|
||||
/**
|
||||
* Initialize a new `JsCoverage` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function HTMLCov(runner) {
|
||||
var jade = require('jade')
|
||||
, file = __dirname + '/templates/coverage.jade'
|
||||
, str = fs.readFileSync(file, 'utf8')
|
||||
, fn = jade.compile(str, { filename: file })
|
||||
, self = this;
|
||||
|
||||
JSONCov.call(this, runner, false);
|
||||
|
||||
runner.on('end', function(){
|
||||
process.stdout.write(fn({
|
||||
cov: self.cov
|
||||
, coverageClass: coverageClass
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return coverage class for `n`.
|
||||
*
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function coverageClass(n) {
|
||||
if (n >= 75) return 'high';
|
||||
if (n >= 50) return 'medium';
|
||||
if (n >= 25) return 'low';
|
||||
return 'terrible';
|
||||
}
|
287
node_modules/mocha/lib/reporters/html.js
generated
vendored
Normal file
287
node_modules/mocha/lib/reporters/html.js
generated
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, utils = require('../utils')
|
||||
, Progress = require('../browser/progress')
|
||||
, escape = utils.escape;
|
||||
|
||||
/**
|
||||
* Save timer references to avoid Sinon interfering (see GH-237).
|
||||
*/
|
||||
|
||||
var Date = global.Date
|
||||
, setTimeout = global.setTimeout
|
||||
, setInterval = global.setInterval
|
||||
, clearTimeout = global.clearTimeout
|
||||
, clearInterval = global.clearInterval;
|
||||
|
||||
/**
|
||||
* Expose `HTML`.
|
||||
*/
|
||||
|
||||
exports = module.exports = HTML;
|
||||
|
||||
/**
|
||||
* Stats template.
|
||||
*/
|
||||
|
||||
var statsTemplate = '<ul id="mocha-stats">'
|
||||
+ '<li class="progress"><canvas width="40" height="40"></canvas></li>'
|
||||
+ '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
|
||||
+ '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
|
||||
+ '<li class="duration">duration: <em>0</em>s</li>'
|
||||
+ '</ul>';
|
||||
|
||||
/**
|
||||
* Initialize a new `HTML` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function HTML(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, total = runner.total
|
||||
, stat = fragment(statsTemplate)
|
||||
, items = stat.getElementsByTagName('li')
|
||||
, passes = items[1].getElementsByTagName('em')[0]
|
||||
, passesLink = items[1].getElementsByTagName('a')[0]
|
||||
, failures = items[2].getElementsByTagName('em')[0]
|
||||
, failuresLink = items[2].getElementsByTagName('a')[0]
|
||||
, duration = items[3].getElementsByTagName('em')[0]
|
||||
, canvas = stat.getElementsByTagName('canvas')[0]
|
||||
, report = fragment('<ul id="mocha-report"></ul>')
|
||||
, stack = [report]
|
||||
, progress
|
||||
, ctx
|
||||
, root = document.getElementById('mocha');
|
||||
|
||||
if (canvas.getContext) {
|
||||
var ratio = window.devicePixelRatio || 1;
|
||||
canvas.style.width = canvas.width;
|
||||
canvas.style.height = canvas.height;
|
||||
canvas.width *= ratio;
|
||||
canvas.height *= ratio;
|
||||
ctx = canvas.getContext('2d');
|
||||
ctx.scale(ratio, ratio);
|
||||
progress = new Progress;
|
||||
}
|
||||
|
||||
if (!root) return error('#mocha div missing, add it to your document');
|
||||
|
||||
// pass toggle
|
||||
on(passesLink, 'click', function(){
|
||||
unhide();
|
||||
var name = /pass/.test(report.className) ? '' : ' pass';
|
||||
report.className = report.className.replace(/fail|pass/g, '') + name;
|
||||
if (report.className.trim()) hideSuitesWithout('test pass');
|
||||
});
|
||||
|
||||
// failure toggle
|
||||
on(failuresLink, 'click', function(){
|
||||
unhide();
|
||||
var name = /fail/.test(report.className) ? '' : ' fail';
|
||||
report.className = report.className.replace(/fail|pass/g, '') + name;
|
||||
if (report.className.trim()) hideSuitesWithout('test fail');
|
||||
});
|
||||
|
||||
root.appendChild(stat);
|
||||
root.appendChild(report);
|
||||
|
||||
if (progress) progress.size(40);
|
||||
|
||||
runner.on('suite', function(suite){
|
||||
if (suite.root) return;
|
||||
|
||||
// suite
|
||||
var url = self.suiteURL(suite);
|
||||
var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
|
||||
|
||||
// container
|
||||
stack[0].appendChild(el);
|
||||
stack.unshift(document.createElement('ul'));
|
||||
el.appendChild(stack[0]);
|
||||
});
|
||||
|
||||
runner.on('suite end', function(suite){
|
||||
if (suite.root) return;
|
||||
stack.shift();
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
if ('hook' == test.type) runner.emit('test end', test);
|
||||
});
|
||||
|
||||
runner.on('test end', function(test){
|
||||
// TODO: add to stats
|
||||
var percent = stats.tests / this.total * 100 | 0;
|
||||
if (progress) progress.update(percent).draw(ctx);
|
||||
|
||||
// update stats
|
||||
var ms = new Date - stats.start;
|
||||
text(passes, stats.passes);
|
||||
text(failures, stats.failures);
|
||||
text(duration, (ms / 1000).toFixed(2));
|
||||
|
||||
// test
|
||||
if ('passed' == test.state) {
|
||||
var url = self.testURL(test);
|
||||
var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
|
||||
} else if (test.pending) {
|
||||
var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
|
||||
} else {
|
||||
var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
|
||||
var str = test.err.stack || test.err.toString();
|
||||
|
||||
// FF / Opera do not add the message
|
||||
if (!~str.indexOf(test.err.message)) {
|
||||
str = test.err.message + '\n' + str;
|
||||
}
|
||||
|
||||
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
|
||||
// check for the result of the stringifying.
|
||||
if ('[object Error]' == str) str = test.err.message;
|
||||
|
||||
// Safari doesn't give you a stack. Let's at least provide a source line.
|
||||
if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
|
||||
str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
|
||||
}
|
||||
|
||||
el.appendChild(fragment('<pre class="error">%e</pre>', str));
|
||||
}
|
||||
|
||||
// toggle code
|
||||
// TODO: defer
|
||||
if (!test.pending) {
|
||||
var h2 = el.getElementsByTagName('h2')[0];
|
||||
|
||||
on(h2, 'click', function(){
|
||||
pre.style.display = 'none' == pre.style.display
|
||||
? 'block'
|
||||
: 'none';
|
||||
});
|
||||
|
||||
var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
|
||||
el.appendChild(pre);
|
||||
pre.style.display = 'none';
|
||||
}
|
||||
|
||||
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
|
||||
if (stack[0]) stack[0].appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a URL, preserving querystring ("search") parameters.
|
||||
* @param {string} s
|
||||
* @returns {string} your new URL
|
||||
*/
|
||||
var makeUrl = function makeUrl(s) {
|
||||
var search = window.location.search;
|
||||
|
||||
// Remove previous grep query parameter if present
|
||||
if (search) {
|
||||
search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
|
||||
}
|
||||
|
||||
return window.location.pathname + (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide suite URL
|
||||
*
|
||||
* @param {Object} [suite]
|
||||
*/
|
||||
HTML.prototype.suiteURL = function(suite){
|
||||
return makeUrl(suite.fullTitle());
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide test URL
|
||||
*
|
||||
* @param {Object} [test]
|
||||
*/
|
||||
|
||||
HTML.prototype.testURL = function(test){
|
||||
return makeUrl(test.fullTitle());
|
||||
};
|
||||
|
||||
/**
|
||||
* Display error `msg`.
|
||||
*/
|
||||
|
||||
function error(msg) {
|
||||
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a DOM fragment from `html`.
|
||||
*/
|
||||
|
||||
function fragment(html) {
|
||||
var args = arguments
|
||||
, div = document.createElement('div')
|
||||
, i = 1;
|
||||
|
||||
div.innerHTML = html.replace(/%([se])/g, function(_, type){
|
||||
switch (type) {
|
||||
case 's': return String(args[i++]);
|
||||
case 'e': return escape(args[i++]);
|
||||
}
|
||||
});
|
||||
|
||||
return div.firstChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for suites that do not have elements
|
||||
* with `classname`, and hide them.
|
||||
*/
|
||||
|
||||
function hideSuitesWithout(classname) {
|
||||
var suites = document.getElementsByClassName('suite');
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var els = suites[i].getElementsByClassName(classname);
|
||||
if (0 == els.length) suites[i].className += ' hidden';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unhide .hidden suites.
|
||||
*/
|
||||
|
||||
function unhide() {
|
||||
var els = document.getElementsByClassName('suite hidden');
|
||||
for (var i = 0; i < els.length; ++i) {
|
||||
els[i].className = els[i].className.replace('suite hidden', 'suite');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set `el` text to `str`.
|
||||
*/
|
||||
|
||||
function text(el, str) {
|
||||
if (el.textContent) {
|
||||
el.textContent = str;
|
||||
} else {
|
||||
el.innerText = str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on `event` with callback `fn`.
|
||||
*/
|
||||
|
||||
function on(el, event, fn) {
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener(event, fn, false);
|
||||
} else {
|
||||
el.attachEvent('on' + event, fn);
|
||||
}
|
||||
}
|
17
node_modules/mocha/lib/reporters/index.js
generated
vendored
Normal file
17
node_modules/mocha/lib/reporters/index.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
exports.Base = require('./base');
|
||||
exports.Dot = require('./dot');
|
||||
exports.Doc = require('./doc');
|
||||
exports.TAP = require('./tap');
|
||||
exports.JSON = require('./json');
|
||||
exports.HTML = require('./html');
|
||||
exports.List = require('./list');
|
||||
exports.Min = require('./min');
|
||||
exports.Spec = require('./spec');
|
||||
exports.Nyan = require('./nyan');
|
||||
exports.XUnit = require('./xunit');
|
||||
exports.Markdown = require('./markdown');
|
||||
exports.Progress = require('./progress');
|
||||
exports.Landing = require('./landing');
|
||||
exports.JSONCov = require('./json-cov');
|
||||
exports.HTMLCov = require('./html-cov');
|
||||
exports.JSONStream = require('./json-stream');
|
152
node_modules/mocha/lib/reporters/json-cov.js
generated
vendored
Normal file
152
node_modules/mocha/lib/reporters/json-cov.js
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base');
|
||||
|
||||
/**
|
||||
* Expose `JSONCov`.
|
||||
*/
|
||||
|
||||
exports = module.exports = JSONCov;
|
||||
|
||||
/**
|
||||
* Initialize a new `JsCoverage` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @param {Boolean} output
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function JSONCov(runner, output) {
|
||||
var self = this
|
||||
, output = 1 == arguments.length ? true : output;
|
||||
|
||||
Base.call(this, runner);
|
||||
|
||||
var tests = []
|
||||
, failures = []
|
||||
, passes = [];
|
||||
|
||||
runner.on('test end', function(test){
|
||||
tests.push(test);
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
passes.push(test);
|
||||
});
|
||||
|
||||
runner.on('fail', function(test){
|
||||
failures.push(test);
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
var cov = global._$jscoverage || {};
|
||||
var result = self.cov = map(cov);
|
||||
result.stats = self.stats;
|
||||
result.tests = tests.map(clean);
|
||||
result.failures = failures.map(clean);
|
||||
result.passes = passes.map(clean);
|
||||
if (!output) return;
|
||||
process.stdout.write(JSON.stringify(result, null, 2 ));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map jscoverage data to a JSON structure
|
||||
* suitable for reporting.
|
||||
*
|
||||
* @param {Object} cov
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function map(cov) {
|
||||
var ret = {
|
||||
instrumentation: 'node-jscoverage'
|
||||
, sloc: 0
|
||||
, hits: 0
|
||||
, misses: 0
|
||||
, coverage: 0
|
||||
, files: []
|
||||
};
|
||||
|
||||
for (var filename in cov) {
|
||||
var data = coverage(filename, cov[filename]);
|
||||
ret.files.push(data);
|
||||
ret.hits += data.hits;
|
||||
ret.misses += data.misses;
|
||||
ret.sloc += data.sloc;
|
||||
}
|
||||
|
||||
ret.files.sort(function(a, b) {
|
||||
return a.filename.localeCompare(b.filename);
|
||||
});
|
||||
|
||||
if (ret.sloc > 0) {
|
||||
ret.coverage = (ret.hits / ret.sloc) * 100;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map jscoverage data for a single source file
|
||||
* to a JSON structure suitable for reporting.
|
||||
*
|
||||
* @param {String} filename name of the source file
|
||||
* @param {Object} data jscoverage coverage data
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function coverage(filename, data) {
|
||||
var ret = {
|
||||
filename: filename,
|
||||
coverage: 0,
|
||||
hits: 0,
|
||||
misses: 0,
|
||||
sloc: 0,
|
||||
source: {}
|
||||
};
|
||||
|
||||
data.source.forEach(function(line, num){
|
||||
num++;
|
||||
|
||||
if (data[num] === 0) {
|
||||
ret.misses++;
|
||||
ret.sloc++;
|
||||
} else if (data[num] !== undefined) {
|
||||
ret.hits++;
|
||||
ret.sloc++;
|
||||
}
|
||||
|
||||
ret.source[num] = {
|
||||
source: line
|
||||
, coverage: data[num] === undefined
|
||||
? ''
|
||||
: data[num]
|
||||
};
|
||||
});
|
||||
|
||||
ret.coverage = ret.hits / ret.sloc * 100;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a plain-object representation of `test`
|
||||
* free of cyclic properties etc.
|
||||
*
|
||||
* @param {Object} test
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function clean(test) {
|
||||
return {
|
||||
title: test.title
|
||||
, fullTitle: test.fullTitle()
|
||||
, duration: test.duration
|
||||
}
|
||||
}
|
62
node_modules/mocha/lib/reporters/json-stream.js
generated
vendored
Normal file
62
node_modules/mocha/lib/reporters/json-stream.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `List`.
|
||||
*/
|
||||
|
||||
exports = module.exports = List;
|
||||
|
||||
/**
|
||||
* Initialize a new `List` test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function List(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, total = runner.total;
|
||||
|
||||
runner.on('start', function(){
|
||||
console.log(JSON.stringify(['start', { total: total }]));
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
console.log(JSON.stringify(['pass', clean(test)]));
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
test = clean(test);
|
||||
test.err = err.message;
|
||||
console.log(JSON.stringify(['fail', test]));
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
process.stdout.write(JSON.stringify(['end', self.stats]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a plain-object representation of `test`
|
||||
* free of cyclic properties etc.
|
||||
*
|
||||
* @param {Object} test
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function clean(test) {
|
||||
return {
|
||||
title: test.title
|
||||
, fullTitle: test.fullTitle()
|
||||
, duration: test.duration
|
||||
}
|
||||
}
|
92
node_modules/mocha/lib/reporters/json.js
generated
vendored
Normal file
92
node_modules/mocha/lib/reporters/json.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `JSON`.
|
||||
*/
|
||||
|
||||
exports = module.exports = JSONReporter;
|
||||
|
||||
/**
|
||||
* Initialize a new `JSON` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function JSONReporter(runner) {
|
||||
var self = this;
|
||||
Base.call(this, runner);
|
||||
|
||||
var tests = []
|
||||
, pending = []
|
||||
, failures = []
|
||||
, passes = [];
|
||||
|
||||
runner.on('test end', function(test){
|
||||
tests.push(test);
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
passes.push(test);
|
||||
});
|
||||
|
||||
runner.on('fail', function(test){
|
||||
failures.push(test);
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
pending.push(test);
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
var obj = {
|
||||
stats: self.stats,
|
||||
tests: tests.map(clean),
|
||||
pending: pending.map(clean),
|
||||
failures: failures.map(clean),
|
||||
passes: passes.map(clean)
|
||||
};
|
||||
|
||||
runner.testResults = obj;
|
||||
|
||||
process.stdout.write(JSON.stringify(obj, null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a plain-object representation of `test`
|
||||
* free of cyclic properties etc.
|
||||
*
|
||||
* @param {Object} test
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function clean(test) {
|
||||
return {
|
||||
title: test.title,
|
||||
fullTitle: test.fullTitle(),
|
||||
duration: test.duration,
|
||||
err: errorJSON(test.err || {})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform `error` into a JSON object.
|
||||
* @param {Error} err
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
function errorJSON(err) {
|
||||
var res = {};
|
||||
Object.getOwnPropertyNames(err).forEach(function(key) {
|
||||
res[key] = err[key];
|
||||
}, err);
|
||||
return res;
|
||||
}
|
96
node_modules/mocha/lib/reporters/landing.js
generated
vendored
Normal file
96
node_modules/mocha/lib/reporters/landing.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `Landing`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Landing;
|
||||
|
||||
/**
|
||||
* Airplane color.
|
||||
*/
|
||||
|
||||
Base.colors.plane = 0;
|
||||
|
||||
/**
|
||||
* Airplane crash color.
|
||||
*/
|
||||
|
||||
Base.colors['plane crash'] = 31;
|
||||
|
||||
/**
|
||||
* Runway color.
|
||||
*/
|
||||
|
||||
Base.colors.runway = 90;
|
||||
|
||||
/**
|
||||
* Initialize a new `Landing` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Landing(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, width = Base.window.width * .75 | 0
|
||||
, total = runner.total
|
||||
, stream = process.stdout
|
||||
, plane = color('plane', '✈')
|
||||
, crashed = -1
|
||||
, n = 0;
|
||||
|
||||
function runway() {
|
||||
var buf = Array(width).join('-');
|
||||
return ' ' + color('runway', buf);
|
||||
}
|
||||
|
||||
runner.on('start', function(){
|
||||
stream.write('\n\n\n ');
|
||||
cursor.hide();
|
||||
});
|
||||
|
||||
runner.on('test end', function(test){
|
||||
// check if the plane crashed
|
||||
var col = -1 == crashed
|
||||
? width * ++n / total | 0
|
||||
: crashed;
|
||||
|
||||
// show the crash
|
||||
if ('failed' == test.state) {
|
||||
plane = color('plane crash', '✈');
|
||||
crashed = col;
|
||||
}
|
||||
|
||||
// render landing strip
|
||||
stream.write('\u001b['+(width+1)+'D\u001b[2A');
|
||||
stream.write(runway());
|
||||
stream.write('\n ');
|
||||
stream.write(color('runway', Array(col).join('⋅')));
|
||||
stream.write(plane)
|
||||
stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
|
||||
stream.write(runway());
|
||||
stream.write('\u001b[0m');
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
cursor.show();
|
||||
console.log();
|
||||
self.epilogue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
Landing.prototype.__proto__ = Base.prototype;
|
63
node_modules/mocha/lib/reporters/list.js
generated
vendored
Normal file
63
node_modules/mocha/lib/reporters/list.js
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `List`.
|
||||
*/
|
||||
|
||||
exports = module.exports = List;
|
||||
|
||||
/**
|
||||
* Initialize a new `List` test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function List(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, n = 0;
|
||||
|
||||
runner.on('start', function(){
|
||||
console.log();
|
||||
});
|
||||
|
||||
runner.on('test', function(test){
|
||||
process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
var fmt = color('checkmark', ' -')
|
||||
+ color('pending', ' %s');
|
||||
console.log(fmt, test.fullTitle());
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
var fmt = color('checkmark', ' '+Base.symbols.dot)
|
||||
+ color('pass', ' %s: ')
|
||||
+ color(test.speed, '%dms');
|
||||
cursor.CR();
|
||||
console.log(fmt, test.fullTitle(), test.duration);
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
cursor.CR();
|
||||
console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
|
||||
});
|
||||
|
||||
runner.on('end', self.epilogue.bind(self));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
List.prototype.__proto__ = Base.prototype;
|
100
node_modules/mocha/lib/reporters/markdown.js
generated
vendored
Normal file
100
node_modules/mocha/lib/reporters/markdown.js
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
var SUITE_PREFIX = '$';
|
||||
|
||||
/**
|
||||
* Expose `Markdown`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Markdown;
|
||||
|
||||
/**
|
||||
* Initialize a new `Markdown` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Markdown(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, level = 0
|
||||
, buf = '';
|
||||
|
||||
function title(str) {
|
||||
return Array(level).join('#') + ' ' + str;
|
||||
}
|
||||
|
||||
function indent() {
|
||||
return Array(level).join(' ');
|
||||
}
|
||||
|
||||
function mapTOC(suite, obj) {
|
||||
var ret = obj,
|
||||
key = SUITE_PREFIX + suite.title;
|
||||
obj = obj[key] = obj[key] || { suite: suite };
|
||||
suite.suites.forEach(function(suite){
|
||||
mapTOC(suite, obj);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function stringifyTOC(obj, level) {
|
||||
++level;
|
||||
var buf = '';
|
||||
var link;
|
||||
for (var key in obj) {
|
||||
if ('suite' == key) continue;
|
||||
if (key !== SUITE_PREFIX) {
|
||||
link = ' - [' + key.substring(1) + ']';
|
||||
link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
|
||||
buf += Array(level).join(' ') + link;
|
||||
}
|
||||
buf += stringifyTOC(obj[key], level);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
function generateTOC(suite) {
|
||||
var obj = mapTOC(suite, {});
|
||||
return stringifyTOC(obj, 0);
|
||||
}
|
||||
|
||||
generateTOC(runner.suite);
|
||||
|
||||
runner.on('suite', function(suite){
|
||||
++level;
|
||||
var slug = utils.slug(suite.fullTitle());
|
||||
buf += '<a name="' + slug + '"></a>' + '\n';
|
||||
buf += title(suite.title) + '\n';
|
||||
});
|
||||
|
||||
runner.on('suite end', function(suite){
|
||||
--level;
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
var code = utils.clean(test.fn.toString());
|
||||
buf += test.title + '.\n';
|
||||
buf += '\n```js\n';
|
||||
buf += code + '\n';
|
||||
buf += '```\n\n';
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
process.stdout.write('# TOC\n');
|
||||
process.stdout.write(generateTOC(runner.suite));
|
||||
process.stdout.write(buf);
|
||||
});
|
||||
}
|
37
node_modules/mocha/lib/reporters/min.js
generated
vendored
Normal file
37
node_modules/mocha/lib/reporters/min.js
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base');
|
||||
|
||||
/**
|
||||
* Expose `Min`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Min;
|
||||
|
||||
/**
|
||||
* Initialize a new `Min` minimal test reporter (best used with --watch).
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Min(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
runner.on('start', function(){
|
||||
// clear screen
|
||||
process.stdout.write('\u001b[2J');
|
||||
// set cursor position
|
||||
process.stdout.write('\u001b[1;3H');
|
||||
});
|
||||
|
||||
runner.on('end', this.epilogue.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
Min.prototype.__proto__ = Base.prototype;
|
260
node_modules/mocha/lib/reporters/nyan.js
generated
vendored
Normal file
260
node_modules/mocha/lib/reporters/nyan.js
generated
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base');
|
||||
|
||||
/**
|
||||
* Expose `Dot`.
|
||||
*/
|
||||
|
||||
exports = module.exports = NyanCat;
|
||||
|
||||
/**
|
||||
* Initialize a new `Dot` matrix test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function NyanCat(runner) {
|
||||
Base.call(this, runner);
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, width = Base.window.width * .75 | 0
|
||||
, rainbowColors = this.rainbowColors = self.generateColors()
|
||||
, colorIndex = this.colorIndex = 0
|
||||
, numerOfLines = this.numberOfLines = 4
|
||||
, trajectories = this.trajectories = [[], [], [], []]
|
||||
, nyanCatWidth = this.nyanCatWidth = 11
|
||||
, trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
|
||||
, scoreboardWidth = this.scoreboardWidth = 5
|
||||
, tick = this.tick = 0
|
||||
, n = 0;
|
||||
|
||||
runner.on('start', function(){
|
||||
Base.cursor.hide();
|
||||
self.draw();
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
self.draw();
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
self.draw();
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
self.draw();
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
Base.cursor.show();
|
||||
for (var i = 0; i < self.numberOfLines; i++) write('\n');
|
||||
self.epilogue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the nyan cat
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.draw = function(){
|
||||
this.appendRainbow();
|
||||
this.drawScoreboard();
|
||||
this.drawRainbow();
|
||||
this.drawNyanCat();
|
||||
this.tick = !this.tick;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the "scoreboard" showing the number
|
||||
* of passes, failures and pending tests.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.drawScoreboard = function(){
|
||||
var stats = this.stats;
|
||||
|
||||
function draw(type, n) {
|
||||
write(' ');
|
||||
write(Base.color(type, n));
|
||||
write('\n');
|
||||
}
|
||||
|
||||
draw('green', stats.passes);
|
||||
draw('fail', stats.failures);
|
||||
draw('pending', stats.pending);
|
||||
write('\n');
|
||||
|
||||
this.cursorUp(this.numberOfLines);
|
||||
};
|
||||
|
||||
/**
|
||||
* Append the rainbow.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.appendRainbow = function(){
|
||||
var segment = this.tick ? '_' : '-';
|
||||
var rainbowified = this.rainbowify(segment);
|
||||
|
||||
for (var index = 0; index < this.numberOfLines; index++) {
|
||||
var trajectory = this.trajectories[index];
|
||||
if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
|
||||
trajectory.push(rainbowified);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the rainbow.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.drawRainbow = function(){
|
||||
var self = this;
|
||||
|
||||
this.trajectories.forEach(function(line, index) {
|
||||
write('\u001b[' + self.scoreboardWidth + 'C');
|
||||
write(line.join(''));
|
||||
write('\n');
|
||||
});
|
||||
|
||||
this.cursorUp(this.numberOfLines);
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the nyan cat
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.drawNyanCat = function() {
|
||||
var self = this;
|
||||
var startWidth = this.scoreboardWidth + this.trajectories[0].length;
|
||||
var dist = '\u001b[' + startWidth + 'C';
|
||||
var padding = '';
|
||||
|
||||
write(dist);
|
||||
write('_,------,');
|
||||
write('\n');
|
||||
|
||||
write(dist);
|
||||
padding = self.tick ? ' ' : ' ';
|
||||
write('_|' + padding + '/\\_/\\ ');
|
||||
write('\n');
|
||||
|
||||
write(dist);
|
||||
padding = self.tick ? '_' : '__';
|
||||
var tail = self.tick ? '~' : '^';
|
||||
var face;
|
||||
write(tail + '|' + padding + this.face() + ' ');
|
||||
write('\n');
|
||||
|
||||
write(dist);
|
||||
padding = self.tick ? ' ' : ' ';
|
||||
write(padding + '"" "" ');
|
||||
write('\n');
|
||||
|
||||
this.cursorUp(this.numberOfLines);
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw nyan cat face.
|
||||
*
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.face = function() {
|
||||
var stats = this.stats;
|
||||
if (stats.failures) {
|
||||
return '( x .x)';
|
||||
} else if (stats.pending) {
|
||||
return '( o .o)';
|
||||
} else if(stats.passes) {
|
||||
return '( ^ .^)';
|
||||
} else {
|
||||
return '( - .-)';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Move cursor up `n`.
|
||||
*
|
||||
* @param {Number} n
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.cursorUp = function(n) {
|
||||
write('\u001b[' + n + 'A');
|
||||
};
|
||||
|
||||
/**
|
||||
* Move cursor down `n`.
|
||||
*
|
||||
* @param {Number} n
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.cursorDown = function(n) {
|
||||
write('\u001b[' + n + 'B');
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate rainbow colors.
|
||||
*
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.generateColors = function(){
|
||||
var colors = [];
|
||||
|
||||
for (var i = 0; i < (6 * 7); i++) {
|
||||
var pi3 = Math.floor(Math.PI / 3);
|
||||
var n = (i * (1.0 / 6));
|
||||
var r = Math.floor(3 * Math.sin(n) + 3);
|
||||
var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
|
||||
var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
|
||||
colors.push(36 * r + 6 * g + b + 16);
|
||||
}
|
||||
|
||||
return colors;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply rainbow to the given `str`.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NyanCat.prototype.rainbowify = function(str){
|
||||
if (!Base.useColors)
|
||||
return str;
|
||||
var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
|
||||
this.colorIndex += 1;
|
||||
return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
|
||||
};
|
||||
|
||||
/**
|
||||
* Stdout helper.
|
||||
*/
|
||||
|
||||
function write(string) {
|
||||
process.stdout.write(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
NyanCat.prototype.__proto__ = Base.prototype;
|
92
node_modules/mocha/lib/reporters/progress.js
generated
vendored
Normal file
92
node_modules/mocha/lib/reporters/progress.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `Progress`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Progress;
|
||||
|
||||
/**
|
||||
* General progress bar color.
|
||||
*/
|
||||
|
||||
Base.colors.progress = 90;
|
||||
|
||||
/**
|
||||
* Initialize a new `Progress` bar test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Progress(runner, options) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, options = options || {}
|
||||
, stats = this.stats
|
||||
, width = Base.window.width * .50 | 0
|
||||
, total = runner.total
|
||||
, complete = 0
|
||||
, max = Math.max
|
||||
, lastN = -1;
|
||||
|
||||
// default chars
|
||||
options.open = options.open || '[';
|
||||
options.complete = options.complete || '▬';
|
||||
options.incomplete = options.incomplete || Base.symbols.dot;
|
||||
options.close = options.close || ']';
|
||||
options.verbose = false;
|
||||
|
||||
// tests started
|
||||
runner.on('start', function(){
|
||||
console.log();
|
||||
cursor.hide();
|
||||
});
|
||||
|
||||
// tests complete
|
||||
runner.on('test end', function(){
|
||||
complete++;
|
||||
var incomplete = total - complete
|
||||
, percent = complete / total
|
||||
, n = width * percent | 0
|
||||
, i = width - n;
|
||||
|
||||
if (lastN === n && !options.verbose) {
|
||||
// Don't re-render the line if it hasn't changed
|
||||
return;
|
||||
}
|
||||
lastN = n;
|
||||
|
||||
cursor.CR();
|
||||
process.stdout.write('\u001b[J');
|
||||
process.stdout.write(color('progress', ' ' + options.open));
|
||||
process.stdout.write(Array(n).join(options.complete));
|
||||
process.stdout.write(Array(i).join(options.incomplete));
|
||||
process.stdout.write(color('progress', options.close));
|
||||
if (options.verbose) {
|
||||
process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
|
||||
}
|
||||
});
|
||||
|
||||
// tests are complete, output some stats
|
||||
// and the failures if any
|
||||
runner.on('end', function(){
|
||||
cursor.show();
|
||||
console.log();
|
||||
self.epilogue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
Progress.prototype.__proto__ = Base.prototype;
|
82
node_modules/mocha/lib/reporters/spec.js
generated
vendored
Normal file
82
node_modules/mocha/lib/reporters/spec.js
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `Spec`.
|
||||
*/
|
||||
|
||||
exports = module.exports = Spec;
|
||||
|
||||
/**
|
||||
* Initialize a new `Spec` test reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Spec(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, indents = 0
|
||||
, n = 0;
|
||||
|
||||
function indent() {
|
||||
return Array(indents).join(' ')
|
||||
}
|
||||
|
||||
runner.on('start', function(){
|
||||
console.log();
|
||||
});
|
||||
|
||||
runner.on('suite', function(suite){
|
||||
++indents;
|
||||
console.log(color('suite', '%s%s'), indent(), suite.title);
|
||||
});
|
||||
|
||||
runner.on('suite end', function(suite){
|
||||
--indents;
|
||||
if (1 == indents) console.log();
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
var fmt = indent() + color('pending', ' - %s');
|
||||
console.log(fmt, test.title);
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
if ('fast' == test.speed) {
|
||||
var fmt = indent()
|
||||
+ color('checkmark', ' ' + Base.symbols.ok)
|
||||
+ color('pass', ' %s');
|
||||
cursor.CR();
|
||||
console.log(fmt, test.title);
|
||||
} else {
|
||||
var fmt = indent()
|
||||
+ color('checkmark', ' ' + Base.symbols.ok)
|
||||
+ color('pass', ' %s')
|
||||
+ color(test.speed, ' (%dms)');
|
||||
cursor.CR();
|
||||
console.log(fmt, test.title, test.duration);
|
||||
}
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
cursor.CR();
|
||||
console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
|
||||
});
|
||||
|
||||
runner.on('end', self.epilogue.bind(self));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
Spec.prototype.__proto__ = Base.prototype;
|
72
node_modules/mocha/lib/reporters/tap.js
generated
vendored
Normal file
72
node_modules/mocha/lib/reporters/tap.js
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, cursor = Base.cursor
|
||||
, color = Base.color;
|
||||
|
||||
/**
|
||||
* Expose `TAP`.
|
||||
*/
|
||||
|
||||
exports = module.exports = TAP;
|
||||
|
||||
/**
|
||||
* Initialize a new `TAP` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function TAP(runner) {
|
||||
Base.call(this, runner);
|
||||
|
||||
var self = this
|
||||
, stats = this.stats
|
||||
, n = 1
|
||||
, passes = 0
|
||||
, failures = 0;
|
||||
|
||||
runner.on('start', function(){
|
||||
var total = runner.grepTotal(runner.suite);
|
||||
console.log('%d..%d', 1, total);
|
||||
});
|
||||
|
||||
runner.on('test end', function(){
|
||||
++n;
|
||||
});
|
||||
|
||||
runner.on('pending', function(test){
|
||||
console.log('ok %d %s # SKIP -', n, title(test));
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
passes++;
|
||||
console.log('ok %d %s', n, title(test));
|
||||
});
|
||||
|
||||
runner.on('fail', function(test, err){
|
||||
failures++;
|
||||
console.log('not ok %d %s', n, title(test));
|
||||
if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
console.log('# tests ' + (passes + failures));
|
||||
console.log('# pass ' + passes);
|
||||
console.log('# fail ' + failures);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a TAP-safe title of `test`
|
||||
*
|
||||
* @param {Object} test
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function title(test) {
|
||||
return test.fullTitle().replace(/#/g, '');
|
||||
}
|
51
node_modules/mocha/lib/reporters/templates/coverage.jade
generated
vendored
Normal file
51
node_modules/mocha/lib/reporters/templates/coverage.jade
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title Coverage
|
||||
meta(charset='utf-8')
|
||||
include script.html
|
||||
include style.html
|
||||
body
|
||||
#coverage
|
||||
h1#overview Coverage
|
||||
include menu
|
||||
|
||||
#stats(class=coverageClass(cov.coverage))
|
||||
.percentage #{cov.coverage | 0}%
|
||||
.sloc= cov.sloc
|
||||
.hits= cov.hits
|
||||
.misses= cov.misses
|
||||
|
||||
#files
|
||||
for file in cov.files
|
||||
.file
|
||||
h2(id=file.filename)= file.filename
|
||||
#stats(class=coverageClass(file.coverage))
|
||||
.percentage #{file.coverage | 0}%
|
||||
.sloc= file.sloc
|
||||
.hits= file.hits
|
||||
.misses= file.misses
|
||||
|
||||
table#source
|
||||
thead
|
||||
tr
|
||||
th Line
|
||||
th Hits
|
||||
th Source
|
||||
tbody
|
||||
for line, number in file.source
|
||||
if line.coverage > 0
|
||||
tr.hit
|
||||
td.line= number
|
||||
td.hits= line.coverage
|
||||
td.source= line.source
|
||||
else if 0 === line.coverage
|
||||
tr.miss
|
||||
td.line= number
|
||||
td.hits 0
|
||||
td.source= line.source
|
||||
else
|
||||
tr
|
||||
td.line= number
|
||||
td.hits
|
||||
td.source= line.source || ' '
|
13
node_modules/mocha/lib/reporters/templates/menu.jade
generated
vendored
Normal file
13
node_modules/mocha/lib/reporters/templates/menu.jade
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#menu
|
||||
li
|
||||
a(href='#overview') overview
|
||||
for file in cov.files
|
||||
li
|
||||
span.cov(class=coverageClass(file.coverage)) #{file.coverage | 0}
|
||||
a(href='##{file.filename}')
|
||||
segments = file.filename.split('/')
|
||||
basename = segments.pop()
|
||||
if segments.length
|
||||
span.dirname= segments.join('/') + '/'
|
||||
span.basename= basename
|
||||
a#logo(href='http://mochajs.org/') m
|
34
node_modules/mocha/lib/reporters/templates/script.html
generated
vendored
Normal file
34
node_modules/mocha/lib/reporters/templates/script.html
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<script>
|
||||
|
||||
headings = [];
|
||||
|
||||
onload = function(){
|
||||
headings = document.querySelectorAll('h2');
|
||||
};
|
||||
|
||||
onscroll = function(e){
|
||||
var heading = find(window.scrollY);
|
||||
if (!heading) return;
|
||||
var links = document.querySelectorAll('#menu a')
|
||||
, link;
|
||||
|
||||
for (var i = 0, len = links.length; i < len; ++i) {
|
||||
link = links[i];
|
||||
link.className = link.getAttribute('href') == '#' + heading.id
|
||||
? 'active'
|
||||
: '';
|
||||
}
|
||||
};
|
||||
|
||||
function find(y) {
|
||||
var i = headings.length
|
||||
, heading;
|
||||
|
||||
while (i--) {
|
||||
heading = headings[i];
|
||||
if (y >= heading.offsetTop) {
|
||||
return heading;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
324
node_modules/mocha/lib/reporters/templates/style.html
generated
vendored
Normal file
324
node_modules/mocha/lib/reporters/templates/style.html
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
149
node_modules/mocha/lib/reporters/xunit.js
generated
vendored
Normal file
149
node_modules/mocha/lib/reporters/xunit.js
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('./base')
|
||||
, utils = require('../utils')
|
||||
, fs = require('fs')
|
||||
, escape = utils.escape;
|
||||
|
||||
/**
|
||||
* Save timer references to avoid Sinon interfering (see GH-237).
|
||||
*/
|
||||
|
||||
var Date = global.Date
|
||||
, setTimeout = global.setTimeout
|
||||
, setInterval = global.setInterval
|
||||
, clearTimeout = global.clearTimeout
|
||||
, clearInterval = global.clearInterval;
|
||||
|
||||
/**
|
||||
* Expose `XUnit`.
|
||||
*/
|
||||
|
||||
exports = module.exports = XUnit;
|
||||
|
||||
/**
|
||||
* Initialize a new `XUnit` reporter.
|
||||
*
|
||||
* @param {Runner} runner
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function XUnit(runner, options) {
|
||||
Base.call(this, runner);
|
||||
var stats = this.stats
|
||||
, tests = []
|
||||
, self = this;
|
||||
|
||||
if (options.reporterOptions && options.reporterOptions.output) {
|
||||
if (! fs.createWriteStream) {
|
||||
throw new Error('file output not supported in browser');
|
||||
}
|
||||
self.fileStream = fs.createWriteStream(options.reporterOptions.output);
|
||||
}
|
||||
|
||||
runner.on('pending', function(test){
|
||||
tests.push(test);
|
||||
});
|
||||
|
||||
runner.on('pass', function(test){
|
||||
tests.push(test);
|
||||
});
|
||||
|
||||
runner.on('fail', function(test){
|
||||
tests.push(test);
|
||||
});
|
||||
|
||||
runner.on('end', function(){
|
||||
self.write(tag('testsuite', {
|
||||
name: 'Mocha Tests'
|
||||
, tests: stats.tests
|
||||
, failures: stats.failures
|
||||
, errors: stats.failures
|
||||
, skipped: stats.tests - stats.failures - stats.passes
|
||||
, timestamp: (new Date).toUTCString()
|
||||
, time: (stats.duration / 1000) || 0
|
||||
}, false));
|
||||
|
||||
tests.forEach(function(t) { self.test(t); });
|
||||
self.write('</testsuite>');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Override done to close the stream (if it's a file).
|
||||
*/
|
||||
XUnit.prototype.done = function(failures, fn) {
|
||||
if (this.fileStream) {
|
||||
this.fileStream.end(function() {
|
||||
fn(failures);
|
||||
});
|
||||
} else {
|
||||
fn(failures);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
|
||||
XUnit.prototype.__proto__ = Base.prototype;
|
||||
|
||||
/**
|
||||
* Write out the given line
|
||||
*/
|
||||
XUnit.prototype.write = function(line) {
|
||||
if (this.fileStream) {
|
||||
this.fileStream.write(line + '\n');
|
||||
} else {
|
||||
console.log(line);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Output tag for the given `test.`
|
||||
*/
|
||||
|
||||
XUnit.prototype.test = function(test, ostream) {
|
||||
var attrs = {
|
||||
classname: test.parent.fullTitle()
|
||||
, name: test.title
|
||||
, time: (test.duration / 1000) || 0
|
||||
};
|
||||
|
||||
if ('failed' == test.state) {
|
||||
var err = test.err;
|
||||
this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
|
||||
} else if (test.pending) {
|
||||
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
|
||||
} else {
|
||||
this.write(tag('testcase', attrs, true) );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML tag helper.
|
||||
*/
|
||||
|
||||
function tag(name, attrs, close, content) {
|
||||
var end = close ? '/>' : '>'
|
||||
, pairs = []
|
||||
, tag;
|
||||
|
||||
for (var key in attrs) {
|
||||
pairs.push(key + '="' + escape(attrs[key]) + '"');
|
||||
}
|
||||
|
||||
tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
|
||||
if (content) tag += content + '</' + name + end;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return cdata escaped CDATA `str`.
|
||||
*/
|
||||
|
||||
function cdata(str) {
|
||||
return '<![CDATA[' + escape(str) + ']]>';
|
||||
}
|
Reference in New Issue
Block a user