Skip to content

Commit 81d6b94

Browse files
author
Travis Jeffery
committed
Merge pull request #1218 from jut-io/xunit-output-file
reporter-specific options and support for the xunit reporter to output to a file (#2)
2 parents 8b88b3b + 82bba0c commit 81d6b94

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

bin/_mocha

+15-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ program
6565
.option('-c, --colors', 'force enabling of colors')
6666
.option('-C, --no-colors', 'force disabling of colors')
6767
.option('-G, --growl', 'enable growl notification support')
68+
.option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
6869
.option('-R, --reporter <name>', 'specify the reporter to use', 'spec')
6970
.option('-S, --sort', "sort test files")
7071
.option('-b, --bail', "bail after first test failure")
@@ -196,9 +197,22 @@ program.parse(process.argv);
196197

197198
Error.stackTraceLimit = Infinity; // TODO: config
198199

200+
// reporter options
201+
202+
var reporterOptions = {};
203+
if (program.reporterOptions !== undefined) {
204+
program.reporterOptions.split(",").forEach(function(opt) {
205+
var L = opt.split("=");
206+
if (L.length != 2) {
207+
throw new Error("invalid reporter option '" + opt + "'");
208+
}
209+
reporterOptions[L[0]] = L[1];
210+
});
211+
}
212+
199213
// reporter
200214

201-
mocha.reporter(program.reporter);
215+
mocha.reporter(program.reporter, reporterOptions);
202216

203217
// interface
204218

lib/mocha.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function Mocha(options) {
8080
this.suite = new exports.Suite('', new exports.Context);
8181
this.ui(options.ui);
8282
this.bail(options.bail);
83-
this.reporter(options.reporter);
83+
this.reporter(options.reporter, options.reporterOptions);
8484
if (null != options.timeout) this.timeout(options.timeout);
8585
this.useColors(options.useColors)
8686
if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);
@@ -131,10 +131,10 @@ Mocha.prototype.addFile = function(file){
131131
* Set reporter to `reporter`, defaults to "spec".
132132
*
133133
* @param {String|Function} reporter name or constructor
134+
* @param {Object} reporterOptions optional options
134135
* @api public
135136
*/
136-
137-
Mocha.prototype.reporter = function(reporter){
137+
Mocha.prototype.reporter = function(reporter, reporterOptions){
138138
if ('function' == typeof reporter) {
139139
this._reporter = reporter;
140140
} else {
@@ -149,6 +149,7 @@ Mocha.prototype.reporter = function(reporter){
149149
if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
150150
this._reporter = _reporter;
151151
}
152+
this.options.reporterOptions = reporterOptions;
152153
return this;
153154
};
154155

@@ -405,5 +406,14 @@ Mocha.prototype.run = function(fn){
405406
exports.reporters.Base.useColors = options.useColors;
406407
}
407408
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
408-
return runner.run(fn);
409+
410+
function done(failures) {
411+
if (reporter.done) {
412+
reporter.done(failures, fn);
413+
} else {
414+
fn(failures);
415+
}
416+
}
417+
418+
return runner.run(done);
409419
};

lib/reporters/xunit.js

+41-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
var Base = require('./base')
66
, utils = require('../utils')
7+
, fs = require('fs')
78
, escape = utils.escape;
89

910
/**
@@ -29,12 +30,19 @@ exports = module.exports = XUnit;
2930
* @api public
3031
*/
3132

32-
function XUnit(runner) {
33+
function XUnit(runner, options) {
3334
Base.call(this, runner);
3435
var stats = this.stats
3536
, tests = []
3637
, self = this;
3738

39+
if (options.reporterOptions && options.reporterOptions.output) {
40+
if (! fs.createWriteStream) {
41+
throw new Error('file output not supported in browser');
42+
}
43+
self.fileStream = fs.createWriteStream(options.reporterOptions.output);
44+
}
45+
3846
runner.on('pending', function(test){
3947
tests.push(test);
4048
});
@@ -48,7 +56,7 @@ function XUnit(runner) {
4856
});
4957

5058
runner.on('end', function(){
51-
console.log(tag('testsuite', {
59+
self.write(tag('testsuite', {
5260
name: 'Mocha Tests'
5361
, tests: stats.tests
5462
, failures: stats.failures
@@ -58,22 +66,46 @@ function XUnit(runner) {
5866
, time: (stats.duration / 1000) || 0
5967
}, false));
6068

61-
tests.forEach(test);
62-
console.log('</testsuite>');
69+
tests.forEach(function(t) { self.test(t); });
70+
self.write('</testsuite>');
6371
});
6472
}
6573

74+
/**
75+
* Override done to close the stream (if it's a file).
76+
*/
77+
XUnit.prototype.done = function(failures, fn) {
78+
if (this.fileStream) {
79+
this.fileStream.end(function() {
80+
fn(failures);
81+
});
82+
} else {
83+
fn(failures);
84+
}
85+
};
86+
6687
/**
6788
* Inherit from `Base.prototype`.
6889
*/
6990

7091
XUnit.prototype.__proto__ = Base.prototype;
7192

93+
/**
94+
* Write out the given line
95+
*/
96+
XUnit.prototype.write = function(line) {
97+
if (this.fileStream) {
98+
this.fileStream.write(line + '\n');
99+
} else {
100+
console.log(line);
101+
}
102+
};
103+
72104
/**
73105
* Output tag for the given `test.`
74106
*/
75107

76-
function test(test) {
108+
XUnit.prototype.test = function(test, ostream) {
77109
var attrs = {
78110
classname: test.parent.fullTitle()
79111
, name: test.title
@@ -82,13 +114,13 @@ function test(test) {
82114

83115
if ('failed' == test.state) {
84116
var err = test.err;
85-
console.log(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
117+
this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
86118
} else if (test.pending) {
87-
console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
119+
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
88120
} else {
89-
console.log(tag('testcase', attrs, true) );
121+
this.write(tag('testcase', attrs, true) );
90122
}
91-
}
123+
};
92124

93125
/**
94126
* HTML tag helper.

0 commit comments

Comments
 (0)