From ada86aab7a4fa5f9b75127de0ce9b061ccced547 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Fri, 13 Apr 2018 21:42:21 -0700 Subject: [PATCH] add custom assertions Signed-off-by: Christopher Hiller --- .wallaby.js | 2 +- test/assertions.js | 257 +++++++++++++++++++++++++++++++++++++++++++++ test/setup.js | 4 +- 3 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 test/assertions.js diff --git a/.wallaby.js b/.wallaby.js index 5296c52d62..5b85d21486 100644 --- a/.wallaby.js +++ b/.wallaby.js @@ -3,7 +3,7 @@ module.exports = () => { return { files: [ - 'index.js', 'lib/**/*.js', 'test/setup.js', + 'index.js', 'lib/**/*.js', 'test/setup.js', 'test/assertions.js', { pattern: 'test/node-unit/**/*.fixture.js', instrument: false diff --git a/test/assertions.js b/test/assertions.js new file mode 100644 index 0000000000..a187d8a5be --- /dev/null +++ b/test/assertions.js @@ -0,0 +1,257 @@ +'use strict'; + +exports.mixinMochaAssertions = function (expect) { + return expect + .addType({ + name: 'JSONResult', + base: 'object', + identify: function (v) { + return ( + Object.prototype.toString.call(v) === '[object Object]' && + Object.prototype.toString.call(v.stats) === '[object Object]' && + Array.isArray(v.failures) && + typeof v.code === 'number' + ); + } + }) + .addType({ + name: 'RawResult', + base: 'object', + identify: function (v) { + return ( + Object.prototype.toString.call(v) === '[object Object]' && + typeof v.passing === 'number' && + typeof v.failing === 'number' && + typeof v.pending === 'number' && + typeof v.output === 'string' && + typeof v.code === 'number' + ); + } + }) + .addAssertion(' [not] to have passed', function ( + expect, + result + ) { + expect(result, 'to satisfy', { + code: expect.it('[not] to be', 0), + stats: { + failures: expect.it('[not] to be', 0) + }, + failures: expect.it('[not] to be empty') + }); + }) + .addAssertion(' [not] to have passed', function (expect, result) { + expect(result.code, '[not] to have completed with code', 0); + }) + .addAssertion( + ' [not] to have completed with [exit] code ', + function (expect, result, code) { + expect(result.code, '[not] to be', code); + } + ) + .addAssertion( + ' [not] to have passed (with|having) count ', + function (expect, result, count) { + expect(result, '[not] to pass').and('[not] to satisfy', { + stats: {passes: expect.it('to be', count)} + }); + } + ) + .addAssertion( + ' [not] to have failed (with|having) count ', + function (expect, result, count) { + expect(result, '[not] to have failed').and('[not] to satisfy', { + stats: {failures: expect.it('to be', count)} + }); + } + ) + .addAssertion(' [not] to have failed', function ( + expect, + result + ) { + expect(result, '[not] to satisfy', { + code: expect.it('to be greater than', 0), + stats: { + failures: expect.it('to be greater than', 0) + }, + failures: expect.it('to be non-empty') + }); + }) + .addAssertion(' [not] to have test count ', function ( + expect, + result, + count + ) { + expect(result.stats.tests, '[not] to be', count); + }) + .addAssertion( + ' [not] to have failed [test] count ', + function (expect, result, count) { + expect(result.stats.failures, '[not] to be', count); + } + ) + .addAssertion( + ' [not] to have passed [test] count ', + function (expect, result, count) { + expect(result.stats.passes, '[not] to be', count); + } + ) + .addAssertion( + ' [not] to have pending [test] count ', + function (expect, result, count) { + expect(result.stats.pending, '[not] to be', count); + } + ) + .addAssertion( + ' [not] to have run (test|tests) ', + function (expect, result, titles) { + Array.prototype.slice.call(arguments, 2).forEach(function (title) { + expect( + result, + '[not] to have a value satisfying', + expect.it('to have an item satisfying', {title: title}) + ); + }); + } + ) + .addAssertion( + ' [not] to have failed (test|tests) ', + function (expect, result, titles) { + Array.prototype.slice.call(arguments, 2).forEach(function (title) { + expect(result.failures, '[not] to have an item satisfying', { + title: title + }); + }); + } + ) + .addAssertion( + ' [not] to have failed with error ', + function (expect, result, err) { + expect(result, '[not] to have failed').and('[not] to satisfy', { + failures: expect.it('to have an item satisfying', { + err: expect.it('to satisfy', err).or('to satisfy', {message: err}) + }) + }); + } + ) + .addAssertion( + ' [not] to have passed (test|tests) ', + function (expect, result, titles) { + Array.prototype.slice.call(arguments, 2).forEach(function (title) { + expect(result.passes, '[not] to have an item satisfying', { + title: title + }); + }); + } + ) + .addAssertion( + ' [not] to have test order ', + function (expect, result, state, titles) { + expect( + result[state].slice(0, titles.length), + '[not] to satisfy', + titles.map(function (title) { + return typeof title === 'string' ? {title: title} : title; + }) + ); + } + ) + .addAssertion( + ' [not] to have passed test order ', + function (expect, result, titles) { + expect(result, '[not] to have test order', 'passes', titles); + } + ) + .addAssertion( + ' [not] to have passed test order ', + function (expect, result, titles) { + expect( + result, + '[not] to have test order', + 'passes', + Array.prototype.slice.call(arguments, 2) + ); + } + ) + .addAssertion( + ' [not] to have failed test order ', + function (expect, result, titles) { + expect(result, '[not] to have test order', 'failures', titles); + } + ) + .addAssertion( + ' [not] to have failed test order ', + function (expect, result, titles) { + expect( + result, + '[not] to have test order', + 'failures', + Array.prototype.slice.call(arguments, 2) + ); + } + ) + .addAssertion( + ' [not] to have pending test order ', + function (expect, result, titles) { + expect(result, '[not] to have test order', 'pending', titles); + } + ) + .addAssertion( + ' [not] to have pending test order ', + function (expect, result, titles) { + expect( + result, + '[not] to have test order', + 'pending', + Array.prototype.slice.call(arguments, 2) + ); + } + ) + .addAssertion(' [not] to have pending tests', function ( + expect, + result + ) { + expect(result.stats.pending, '[not] to be greater than', 0); + }) + .addAssertion(' [not] to have passed tests', function ( + expect, + result + ) { + expect(result.stats.passes, '[not] to be greater than', 0); + }) + .addAssertion(' [not] to have failed tests', function ( + expect, + result + ) { + expect(result.stats.failed, '[not] to be greater than', 0); + }) + .addAssertion(' [not] to have tests', function (expect, result) { + expect(result.stats.tests, '[not] to be greater than', 0); + }) + .addAssertion(' [not] to have retried test ', function ( + expect, + result, + title + ) { + expect(result.tests, '[not] to have an item satisfying', { + title: title, + currentRetry: expect.it('to be positive') + }); + }) + .addAssertion( + ' [not] to have retried test ', + function (expect, result, title, count) { + expect(result.tests, '[not] to have an item satisfying', { + title: title, + currentRetry: count + }); + } + ) + .addAssertion(' [not] to contain output ', function ( + expect, + result, + output + ) { + expect(result.output, '[not] to satisfy', output); + }); +}; diff --git a/test/setup.js b/test/setup.js index 1ecf15b508..990ff7af7a 100644 --- a/test/setup.js +++ b/test/setup.js @@ -1,6 +1,8 @@ 'use strict'; const unexpected = require('unexpected'); -global.expect = unexpected.clone(); +global.expect = require('./assertions').mixinMochaAssertions( + unexpected.clone() +); global.assert = require('assert');