-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement support for multiple reporters #1681
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,11 @@ | ||
TJ Holowaychuk <tj@vision-media.ca> | ||
TJ Holowaychuk <tj@vision-media.ca> | ||
Travis Jeffery <tj@travisjeffery.com> <travisjeffery@gmail.com> | ||
Travis Jeffery <tj@travisjeffery.com> Dr. Travis Jeffery <tj@travisjeffery.com> | ||
Christopher Hiller <boneskull@boneskull.com> Christopher Hiller <chiller@badwing.com> | ||
David da Silva Contín <dasilvacontin@gmail.com> David da Silva <daviddasilvacontin@me.com> | ||
David da Silva Contín <dasilvacontin@gmail.com> David da Silva <dasilvacontin@gmail.com> | ||
Ariel Mashraki <ariel@mashraki.co.il> Ariel Mashraki <ariel@codeoasis.com> | ||
Ariel Mashraki <ariel@mashraki.co.il> Ariel Mashraki <ariel.mashraki@ironsrc.com> | ||
Forbes Lindesay <forbes@lindesay.co.uk> Forbes Lindesay <fpfl2@cam.ac.uk> | ||
Ben Bradley <ben@bradleyit.com> Ben Bradley <[ben.bradley@cigna.com|mailto:ben.bradley@cigna.com]> | ||
Glen Mailer <glenjamin@gmail.com> Glen Mailer <glen.mailer@bskyb.com> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,32 +131,63 @@ Mocha.prototype.addFile = function(file){ | |
}; | ||
|
||
/** | ||
* Set reporter to `reporter`, defaults to "spec". | ||
* Set reporters to `reporters`, defaults to "spec". | ||
* | ||
* @param {String|Function} reporter name or constructor | ||
* @param {Object} reporterOptions optional options | ||
* @param {String|Function|Array of strings|Array of functions} reporter name as string, | ||
* reporter constructor, or array of constructors or reporter names as strings. | ||
* @param {Object} reporterOptions optional options TODO FIXME | ||
* @api public | ||
*/ | ||
Mocha.prototype.reporter = function(reporter, reporterOptions){ | ||
if ('function' == typeof reporter) { | ||
this._reporter = reporter; | ||
} else { | ||
reporter = reporter || 'spec'; | ||
var _reporter; | ||
try { _reporter = require('./reporters/' + reporter); } catch (err) {} | ||
if (!_reporter) try { _reporter = require(reporter); } catch (err) { | ||
err.message.indexOf('Cannot find module') !== -1 | ||
? console.warn('"' + reporter + '" reporter not found') | ||
: console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack); | ||
|
||
Mocha.prototype.reporter = function(reporters, reporterOptions){ | ||
// if no reporter is given as input, default to spec reporter | ||
reporters = reporters || ['spec']; | ||
reporterOptions = reporterOptions || {}; | ||
|
||
// If reporters argument is not a list, turn it into a list of reporter names | ||
// or constructors that we'll iterate on right after to initialize them | ||
if (!Array.isArray(reporters)) { | ||
if (('string' == typeof reporters) || | ||
('function' == typeof reporters)) { | ||
reporters = [reporters]; | ||
} | ||
if (!_reporter && reporter === 'teamcity') | ||
console.warn('The Teamcity reporter was moved to a package named ' + | ||
'mocha-teamcity-reporter ' + | ||
'(https://npmjs.org/package/mocha-teamcity-reporter).'); | ||
if (!_reporter) throw new Error('invalid reporter "' + reporter + '"'); | ||
this._reporter = _reporter; | ||
} | ||
this.options.reporterOptions = reporterOptions; | ||
|
||
// Load each reporter | ||
this._reporters = reporters.map(function (reporterConfig) { | ||
if ('function' == typeof reporterConfig) { | ||
return { | ||
fn: reporterConfig, | ||
options: reporterOptions | ||
}; | ||
} else { | ||
var reporterName | ||
, path; | ||
|
||
reporterName = reporterConfig.split(':'); | ||
if (reporterName.length > 1) { | ||
path = reporterName[1]; | ||
reporterName = reporterName[0]; | ||
} | ||
try { _reporter = require('./reporters/' + reporterName); } catch (err) {}; | ||
if (!_reporter) try { _reporter = require(reporterName); } catch (err) { | ||
err.message.indexOf('Cannot find module') !== -1 | ||
? console.warn('"' + reporterName + '" reporter not found') | ||
: console.warn('"' + reporterName + '" reporter blew up with error:\n' + err.stack); | ||
} | ||
if (!_reporter && reporterName === 'teamcity') | ||
console.warn('The Teamcity reporter was moved to a package named ' + | ||
'mocha-teamcity-reporter ' + | ||
'(https://npmjs.org/package/mocha-teamcity-reporter).'); | ||
if (!_reporter) throw new Error('invalid reporter "' + reporterName + '"'); | ||
return { | ||
fn: _reporter, | ||
path: path, | ||
options: reporterOptions[reporterName] || reporterOptions._default || {} | ||
}; | ||
} | ||
}, this); | ||
|
||
return this; | ||
}; | ||
|
||
|
@@ -424,23 +455,45 @@ Mocha.prototype.run = function(fn){ | |
var options = this.options; | ||
options.files = this.files; | ||
var runner = new exports.Runner(suite, options.delay); | ||
var reporter = new this._reporter(runner, options); | ||
// For each loaded reporter constructor, create | ||
// an instance and initialize it with the runner | ||
var reporters = this._reporters.map(function (reporterConfig) { | ||
var _reporter = reporterConfig.fn | ||
, path = reporterConfig.path; | ||
|
||
options.reporterOptions = reporterConfig.options; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kind of gross (changing the value of Open to alternative suggestions. |
||
return new _reporter(runner, options, path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In following commits you will be passing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
}); | ||
runner.ignoreLeaks = false !== options.ignoreLeaks; | ||
runner.fullStackTrace = options.fullStackTrace; | ||
runner.asyncOnly = options.asyncOnly; | ||
if (options.grep) runner.grep(options.grep, options.invert); | ||
if (options.globals) runner.globals(options.globals); | ||
if (options.growl) this._growl(runner, reporter); | ||
|
||
// Use only the first reporter for growl, since we don't want to | ||
// send several notifications for the same test suite | ||
if (options.growl) this._growl(runner, reporters[0]); | ||
|
||
if (options.useColors !== undefined) { | ||
exports.reporters.Base.useColors = options.useColors; | ||
} | ||
|
||
exports.reporters.Base.inlineDiffs = options.useInlineDiffs; | ||
|
||
function done(failures) { | ||
function runnerDone(failures) { | ||
var remain = reporters.length | ||
, reporterDone = function(failures) { | ||
if (--remain === 0) fn && fn(failures); | ||
}; | ||
|
||
reporters.forEach(function (reporter) { | ||
if (reporter.done) { | ||
reporter.done(failures, fn); | ||
} else fn && fn(failures); | ||
reporter.done(failures, reporterDone); | ||
} else { | ||
reporterDone(failures); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know it's not because of your code, just discussing it, but I don't see clear why the reporter could/can modify the failures object that will be passed to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Never mind that; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fyi, @benvinegar is closing the streams at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd refactor this using a new function that contains There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed |
||
}); | ||
} | ||
|
||
return runner.run(done); | ||
return runner.run(runnerDone); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dasilvacontin – Is there an existing test for bin/_mocha that I've missed? If not, how would you recommend I test these changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benvinegar You could add an integration test: https://github.com/mochajs/mocha/tree/master/test/integration The helpers allow you to invoke the mocha binary (and hence _mocha as well) https://github.com/mochajs/mocha/blob/master/test/integration/helpers.js#L25
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danielstjules I notice those files are on master, but not on v3.0.0.
Should I merge v3.0.0 up w/ master (or someone else)? Should I be targeting master instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely missed what branch this was targeting. I haven't been involved with the 3.0.0 branch, so I'm gonna defer this to @boneskull :) He'll be able to answer that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, master commits should be in v3.0.0.
Why target v3.0.0? Is this PR breaking backwards compatibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, the new syntax for
--reporter-options
has been added. Sorry, I missed that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it's not breaking. (?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somebody in the last PR asked me to. I will close and switch it back (sigh).