Skip to content
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

index.js: Fallback to require(...) for unrecognized reporters #48

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ function Formatter (type, options) {
if (!(this instanceof Formatter)) {
return new Formatter(type, options)
}
if (!reporters[type]) {
var _reporter = reporters[type];
if (!_reporter) {
try {
_reporter = require(type);
} catch (err) {
console.warn(err);
}
}
if (!_reporter) {
console.error('Unknown format type: %s\n\n%s', type, avail())
type = 'silent'
}
Expand All @@ -50,12 +58,16 @@ function Formatter (type, options) {
}

var runner = this.runner = new Runner(options)
this.reporter = new reporters[type](this.runner, {})
var reporter = this.reporter = new _reporter(this.runner, {})
Writable.call(this, options)

runner.on('end', function () {
if (!runner.parser.ok)
exitCode = 1

if (reporter.done) {
reporter.done(runner.stats.failures, process.exit)
}
})
}

Expand Down
45 changes: 18 additions & 27 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ module.exports = Runner
//
// test end(test)
// Emitted immediately after the "test" event because test points are
// not async in TAP.
// not async in TAP. This event is only emitted for passes and
// failures; it is not emitted for skips or TODO tests.

var util = require('util')
var Test = require('./test.js')
Expand Down Expand Up @@ -76,6 +77,9 @@ Runner.prototype.write = function () {
if (!this.emittedStart) {
this.emittedStart = true
this.emit('start')
this.suite = new Suite('root')
this.parser.parent = this
this.emit('suite', this.suite)
}

return this.parser.write.apply(this.parser, arguments)
Expand All @@ -85,13 +89,6 @@ Runner.prototype.end = function () {
return this.parser.end.apply(this.parser, arguments)
}

Parser.prototype.fullTitle = function () {
if (!this.parent)
return this.name || ''
else
return (this.parent.fullTitle() + ' ' + (this.name || '')).trim()
}

function attachEvents (runner, parser, level) {
parser.runner = runner

Expand All @@ -103,6 +100,7 @@ function attachEvents (runner, parser, level) {
runner.emit('version', v)
})
parser.on('complete', function (res) {
runner.emit('suite end', runner.suite)
runner.emit('end')
})
parser.on('comment', function (c) {
Expand Down Expand Up @@ -256,9 +254,11 @@ function attachEvents (runner, parser, level) {
function emitSuite (parser) {
if (!parser.emittedSuite && parser.name) {
parser.emittedSuite = true
var suite = parser.suite = new Suite(parser)
if (parser.parent && parser.parent.suite)
parser.parent.suite.suites.push(suite)
var ancestor = parser
while (ancestor && !ancestor.suite)
ancestor = ancestor.parent
var suite = parser.suite = new Suite(parser.name, ancestor.suite)

if (parser.runner.stats)
parser.runner.stats.suites ++

Expand All @@ -268,28 +268,19 @@ function emitSuite (parser) {

function emitTest (parser, result) {
var runner = parser.runner
var test = new Test(result, parser)

if (parser.suite) {
parser.suite.tests.push(test)
if (!result.ok) {
for (var p = parser; p && p.suite; p = p.parent) {
p.suite.ok = false
}
}
parser.suite.ok = parser.suite.ok && result.ok
}

var test = new Test(result, parser.suite)
runner.emit('test', test)
if (result.skip || result.todo) {
if (test.pending) {
runner.emit('pending', test)
} else if (result.ok) {
} else if (test.state === 'passed') {
runner.emit('pass', test)
} else {
} else if (test.state === 'failed') {
var error = getError(result)
runner.emit('fail', test, error)
}
runner.emit('test end', test)
if (!test.pending && !result.skip) {
runner.emit('test end', test)
}
}

function getError (result) {
Expand Down
37 changes: 26 additions & 11 deletions lib/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,36 @@

module.exports = Suite

function Suite (parent) {
if (!parent.parent || !parent.parent.emittedSuite)
this.root = true
else
this.root = false

this.title = parent.name || ''
function Suite (title, parent) {
this.root = !parent
this.title = title
this.suites = []
this.tests = []
this.ok = true
this._beforeEach = []
this._beforeAll = []
this._afterEach = []
this._afterAll = []

Object.defineProperty(this, 'parent', {
value: parent,
writable: true,
configurable: true,
enumerable: false
})

if (parent) {
parent.suites.push(this)
}
}

Suite.prototype.fullTitle = function () {
if (!this.parent)
return (this.title || '').trim()
else
return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
return this.titlePath().join(' ').trim()
}

Suite.prototype.titlePath = function () {
var title = [(this.title || '').trim()]
if (this.parent && this.parent.titlePath)
return this.parent.titlePath().concat(title)
return title
}
51 changes: 39 additions & 12 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,59 @@

module.exports = Test

function Test (result, parent) {
function Test (result, suite) {
this.result = result
this._slow = 75
this.duration = result.time
this.title = result.name
this.state = result.ok ? 'pass' : 'failed'
this.pending = result.todo || result.skip || false
if (result.diag && result.diag.source) {
var source = result.diag.source
this.fn = {
toString: function () {
return 'function(){' + source + '\n}'
this.title = result.name || result.skip || ''
this.pending = result.todo || false
if (result.ok) {
this.state = result.skip ? 'skipped' : 'passed'
} else {
this.state = 'failed'
}
if (result.diag) {
if (result.diag.source) {
var source = result.diag.source
this.fn = {
toString: function () {
return 'function(){' + source + '\n}'
}
}
} else {
this.context = {
title: 'diagnostic',
value: result.diag,
}
}
}

Object.defineProperty(this, 'parent', {
value: parent,
Object.defineProperty(this, 'suite', {
value: suite,
writable: true,
configurable: true,
enumerable: false
})

if (suite) {
suite.tests.push(this)
if (!result.ok) {
for (var ancestor = suite; ancestor; ancestor = ancestor.parent) {
ancestor.ok = false
}
}
}
}

Test.prototype.fullTitle = function () {
return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
return this.titlePath().join(' ').trim()
}

Test.prototype.titlePath = function () {
var title = [(this.title || '').trim()]
if (this.suite && this.suite.titlePath)
return this.suite.titlePath().concat(title)
return title
}

Test.prototype.slow = function (ms){
Expand Down