diff --git a/lib/test.js b/lib/test.js index bfb7dc60..33c7241b 100644 --- a/lib/test.js +++ b/lib/test.js @@ -972,7 +972,7 @@ Test.prototype.doesNotMatch = function doesNotMatch(string, regexp, msg, extra) }; Test.prototype.assertion = function assertion(fn) { - callBind.apply(fn)(this, $slice(arguments, 1)); + return callBind.apply(fn)(this, $slice(arguments, 1)); }; // eslint-disable-next-line no-unused-vars diff --git a/package.json b/package.json index 3cb6e973..4e8f2b05 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "npmignore": "^0.3.1", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", + "semver": "^6.3.1", "tap": "^8.0.1", "tap-parser": "^5.4.0" }, diff --git a/test/assertion.js b/test/assertion.js index 0d3ddfc8..3bf861f7 100644 --- a/test/assertion.js +++ b/test/assertion.js @@ -3,6 +3,7 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var satisfies = require('semver').satisfies; var stripFullStack = require('./common').stripFullStack; @@ -32,17 +33,34 @@ tap.test('using a custom assertion', function (tt) { ' at Test. ($TEST/assertion.js:$LINE:$COL)', ' [... stack stripped ...]', ' ...', + typeof Promise === 'undefined' + ? '# SKIP custom assertion returns a promise' + : [].concat( + '# custom assertion returns a promise', + 'ok ' + ++count + ' promise rejected!', + 'not ok ' + ++count + ' SyntaxError: expected promise to reject; it fulfilled', + ' ---', + ' operator: error', + ' stack: |-', + ' SyntaxError: expected promise to reject; it fulfilled', + ' at $TEST/assertion.js:$LINE:$COL', + satisfies(process.version, '^8 || ^9') + ? ' at ' + : [], + ' [... stack stripped ...]', + ' ...' + ), '', '1..' + count, '# tests ' + count, - '# pass ' + (count - 1), - '# fail 1', + '# pass ' + (count - (typeof Promise === 'undefined' ? 1 : 2)), + '# fail ' + (typeof Promise === 'undefined' ? 1 : 2), '' )); })); var isAnswer = function (value, msg) { - // eslint-disable-next-line no-invalid-this + this.equal(value, 42, msg || 'value must be the answer to life, the universe, and everything'); }; @@ -54,4 +72,33 @@ tap.test('using a custom assertion', function (tt) { t.end(); }); + + var rejects = function assertRejects(fn, expected, msg, extra) { + var t = this; + /* eslint no-invalid-this: 0 */ + return new Promise(function (resolve) { resolve(fn()); }).then( + function () { + throw new SyntaxError('expected promise to reject; it fulfilled'); + }, + function (err) { + t['throws'](function () { throw err; }, expected, msg, extra); + } + ); + }; + + test('custom assertion returns a promise', { skip: typeof Promise !== 'function' }, function (t) { + return Promise.all([ + t.assertion( + rejects, + function () { return Promise.resolve(); }, + SyntaxError, + 'expected promise to reject; it fulfilled' + ), + t.assertion( + rejects, + function () { return Promise.reject(new Error('foo')); }, + 'promise rejected!' + ) + ]); + }); }); diff --git a/test/common.js b/test/common.js index 284a91e4..9fac9776 100644 --- a/test/common.js +++ b/test/common.js @@ -88,17 +88,18 @@ module.exports.stripFullStack = function (output) { 'at$1 Test.' ).replace( // Handle stack trace variation in Node v0.8 - /at(:?) (Test\.)?tap\.test\.test\.skip/g, - 'at$1 $2' - ).replace( - // Handle more stack trace variation in Node v0.8 /at(:?) Test.tap.test.([^ ]+)/g, 'at$1 Test.$2' ).replace( // Handle stack trace variation in Node v0.8 /(\[\.\.\. stack stripped \.\.\.\]\r?\n *at) \(([^)]+)\)/g, '$1 $2' - ).split(/\r?\n/g); + ).replace( + // Handle stack trace variation in Node v0.8 + /at(:?) (Test\.)?(tap\.test\.test\.skip|t) /g, + 'at$1 $2 ' + ) + .split(/\r?\n/g); }; module.exports.runProgram = function (folderName, fileName, cb) {