diff --git a/api.js b/api.js index 797fe2dfe..71a78e9ee 100644 --- a/api.js +++ b/api.js @@ -9,6 +9,7 @@ var figures = require('figures'); var globby = require('globby'); var chalk = require('chalk'); var fork = require('./lib/fork'); +var formatter = require('./lib/enhance-assert').formatter(); function Api(files, options) { if (!(this instanceof Api)) { @@ -76,6 +77,13 @@ Api.prototype._handleTest = function (test) { var isError = test.error.message; if (isError) { + if (test.error.powerAssertContext) { + var message = formatter(test.error.powerAssertContext); + if (test.error.originalMessage) { + message = test.error.originalMessage + ' ' + message; + } + test.error.message = message; + } this.errors.push(test); } else { test.error = null; diff --git a/lib/assert.js b/lib/assert.js index 2ea331eec..f89373ee1 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -120,5 +120,3 @@ x.regexTest = function (regex, contents, msg) { x.ifError = x.error = function (err, msg) { test(!err, create(err, 'Error', '!==', msg, x.ifError)); }; - -require('./enhance-assert')(x); diff --git a/lib/enhance-assert.js b/lib/enhance-assert.js index 11999474c..6518c9ecc 100644 --- a/lib/enhance-assert.js +++ b/lib/enhance-assert.js @@ -1,4 +1,5 @@ module.exports = enhanceAssert; +module.exports.formatter = formatter; module.exports.PATTERNS = [ 't.ok(value, [message])', @@ -12,23 +13,40 @@ module.exports.PATTERNS = [ 't.regexTest(regex, contents, [message])' ]; -function enhanceAssert(assert) { - var empower = require('empower'); - var powerAssertFormatter = require('power-assert-formatter'); - var powerAssertRenderers = require('power-assert-renderers'); +module.exports.NON_ENHANCED_PATTERNS = [ + 't.pass([message])', + 't.fail([message])', + 't.throws(fn, [message])', + 't.doesNotThrow(fn, [message])', + 't.ifError(error, [message])' +]; - empower(assert, - powerAssertFormatter({ - renderers: [ - powerAssertRenderers.AssertionRenderer, - powerAssertRenderers.SuccinctRenderer - ] - }), +function enhanceAssert(opts) { + var empower = require('empower-core'); + var enhanced = empower( + opts.assert, { - destructive: true, - modifyMessageOnRethrow: true, - saveContextOnRethrow: false, - patterns: module.exports.PATTERNS + destructive: false, + onError: opts.onError, + onSuccess: opts.onSuccess, + patterns: module.exports.PATTERNS, + wrapOnlyPatterns: module.exports.NON_ENHANCED_PATTERNS } ); + + enhanced.AssertionError = opts.assert.AssertionError; + + return enhanced; +} + +function formatter() { + var powerAssertFormatter = require('power-assert-formatter'); + var powerAssertRenderers = require('power-assert-renderers'); + + return powerAssertFormatter({ + renderers: [ + powerAssertRenderers.AssertionRenderer, + powerAssertRenderers.SuccinctRenderer + ] + }); } diff --git a/lib/test.js b/lib/test.js index 02cbd1533..0cb9aea8b 100644 --- a/lib/test.js +++ b/lib/test.js @@ -8,6 +8,7 @@ var observableToPromise = require('observable-to-promise'); var isPromise = require('is-promise'); var isObservable = require('is-observable'); var assert = require('./assert'); +var enhanceAssert = require('./enhance-assert'); var globals = require('./globals'); function Test(title, fn) { @@ -61,11 +62,6 @@ Test.prototype._setAssertError = function (err) { this.assertError = err; }; -// Workaround for power-assert -// `t` must be capturable for decorated assert output -Test.prototype._capt = assert._capt; -Test.prototype._expr = assert._expr; - Test.prototype.plan = function (count) { if (typeof count !== 'number') { throw new TypeError('Expected a number'); @@ -208,9 +204,7 @@ Test.prototype._publicApi = function () { [ 'assertCount', 'title', - 'end', - '_capt', - '_expr' + 'end' ] .forEach(function (name) { Object.defineProperty(api, name, { @@ -239,31 +233,46 @@ Test.prototype._publicApi = function () { self._assert(); } + function onAssertionEvent(event) { + if (event.assertionThrew) { + event.error.powerAssertContext = event.powerAssertContext; + event.error.originalMessage = event.originalMessage; + self._setAssertError(event.error); + self._assert(); + return null; + } + + var fn = observableToPromise(event.returnValue); + + if (isPromise(fn)) { + return Promise.resolve(fn) + .catch(function (err) { + err.originalMessage = event.originalMessage; + self._setAssertError(err); + }) + .finally(function () { + self._assert(); + }); + } + + self._assert(); + return null; + } + + var enhanced = enhanceAssert({ + assert: assert, + onSuccess: onAssertionEvent, + onError: onAssertionEvent + }); + // Patched assert methods: increase assert count and store errors. Object.keys(assert).forEach(function (el) { api.skip[el] = skipFn; - api[el] = function () { - try { - var fn = assert[el].apply(assert, arguments); - - fn = observableToPromise(fn); - - if (isPromise(fn)) { - return Promise.resolve(fn) - .catch(function (err) { - self._setAssertError(err); - }) - .finally(function () { - self._assert(); - }); - } - } catch (err) { - self._setAssertError(err); - } - - self._assert(); - }; + api[el] = enhanced[el].bind(enhanced); }); + api._capt = enhanced._capt.bind(enhanced); + api._expr = enhanced._expr.bind(enhanced); + return api; }; diff --git a/package.json b/package.json index 04c8b884a..5e9225245 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "debug": "^2.2.0", "deeper": "^2.1.0", "empower": "^1.1.0", + "empower-core": "^0.2.0", "figures": "^1.4.0", "fn-name": "^2.0.0", "globby": "^4.0.0", diff --git a/test/api.js b/test/api.js index f1733ef7f..c854d07ed 100644 --- a/test/api.js +++ b/test/api.js @@ -270,3 +270,24 @@ test('Node.js-style --require CLI argument', function (t) { t.is(api.passCount, 1); }); }); + +test('power-assert support', function (t) { + t.plan(3); + + var api = new Api([path.join(__dirname, 'fixture/power-assert.js')]); + + api.run() + .then(function () { + t.ok(api.errors[0].error.powerAssertContext); + + t.match( + api.errors[0].error.message, + /t\.ok\(a === 'bar'\)\s*\n\s+\|\s*\n\s+"foo"/m + ); + + t.match( + api.errors[1].error.message, + /with message\s+t\.ok\(a === 'foo', 'with message'\)\s*\n\s+\|\s*\n\s+"bar"/m + ); + }); +}); diff --git a/test/fixture/power-assert.js b/test/fixture/power-assert.js index 5f09cf642..d0cc3ade6 100644 --- a/test/fixture/power-assert.js +++ b/test/fixture/power-assert.js @@ -1,7 +1,13 @@ import test from '../../'; -test(t => { +test.serial(t => { const a = 'foo'; t.ok(a === 'bar'); }); + +test.serial(t => { + const a = 'bar'; + + t.ok(a === 'foo', 'with message'); +});