From 2826729b3d258a947a3d101615ccafa42f451cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20Lauri=20Bostr=C3=B6m?= Date: Sun, 3 Mar 2019 18:24:35 +0100 Subject: [PATCH 1/3] feat: Add .toLog() matcher --- README.md | 17 +++ .../toLog/__snapshots__/index.test.js.snap | 140 ++++++++++++++++++ src/matchers/toLog/index.js | 30 ++++ src/matchers/toLog/index.test.js | 73 +++++++++ src/matchers/toLog/predicate.js | 21 +++ src/matchers/toLog/predicate.test.js | 20 +++ types/index.d.ts | 9 ++ 7 files changed, 310 insertions(+) create mode 100644 src/matchers/toLog/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toLog/index.js create mode 100644 src/matchers/toLog/index.test.js create mode 100644 src/matchers/toLog/predicate.js create mode 100644 src/matchers/toLog/predicate.test.js diff --git a/README.md b/README.md index 44b8a5e9..e282b6e2 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ If you've come here to help contribute - Thanks! Take a look at the [contributin - [.toBeBoolean()](#tobeboolean) - [.toBeTrue()](#tobetrue) - [.toBeFalse()](#tobefalse) + - [Console](#console) + - [.toLog()](#tolog) - [Date](#date) - [.toBeDate()](#tobedate) - [.toBeValidDate()](#tobevaliddate) @@ -356,6 +358,21 @@ test('returns false', () => { }); ``` +### Console + +#### .toLog() + +Use `.toLog` when checking if a callback function outputs a message to the console. The specified console method is mocked during execution so nothing will be printed to the console. + +```js +expect(() => { + console.log('a message'); +}).toLog('a message'); + +expect(someFunction).toLog('some deprecation warning', 'warn') +expect(someOtherFunction).not.toLog('an error message', 'error') +``` + ### ~~Date~~ Proposal in #117 (*under development*) diff --git a/src/matchers/toLog/__snapshots__/index.test.js.snap b/src/matchers/toLog/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..30790a10 --- /dev/null +++ b/src/matchers/toLog/__snapshots__/index.test.js.snap @@ -0,0 +1,140 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toLog fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toLog(expected) + +Expected console.log not to have been called with: + \\"console-log\\" +But it was called with: + [[\\"console-log\\"]]" +`; + +exports[`.not.toLog fails when the callback function outputs the expected message 2`] = ` +"expect(received).not.toLog(expected) + +Expected console.warn not to have been called with: + \\"console-warn\\" +But it was called with: + [[\\"console-warn\\"]]" +`; + +exports[`.not.toLog fails when the callback function outputs the expected message 3`] = ` +"expect(received).not.toLog(expected) + +Expected console.error not to have been called with: + \\"console-error\\" +But it was called with: + [[\\"console-error\\"]]" +`; + +exports[`.not.toLog fails when the callback function outputs the expected message 4`] = ` +"expect(received).not.toLog(expected) + +Expected console.info not to have been called with: + \\"console-info\\" +But it was called with: + [[\\"console-info\\"]]" +`; + +exports[`.not.toLog fails when the callback function outputs the expected message 5`] = ` +"expect(received).not.toLog(expected) + +Expected console.assert not to have been called with: + \\"console-assert\\" +But it was called with: + [[\\"console-assert\\"]]" +`; + +exports[`.toLog fails when the callback function does not output any message 1`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output any message 2`] = ` +"expect(received).toLog(expected) + +Expected console.warn to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output any message 3`] = ` +"expect(received).toLog(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output any message 4`] = ` +"expect(received).toLog(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output any message 5`] = ` +"expect(received).toLog(expected) + +Expected console.assert to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output the expected message 1`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [[\\"console-log\\"]]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 2`] = ` +"expect(received).toLog(expected) + +Expected console.warn to have been called with: + \\"something\\" +But it was called with: + [[\\"console-warn\\"]]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 3`] = ` +"expect(received).toLog(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was called with: + [[\\"console-error\\"]]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 4`] = ` +"expect(received).toLog(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was called with: + [[\\"console-info\\"]]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 5`] = ` +"expect(received).toLog(expected) + +Expected console.assert to have been called with: + \\"something\\" +But it was called with: + [[\\"console-assert\\"]]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 6`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [[\\"a\\", \\"b\\", \\"c\\"], [\\"console-log\\"]]" +`; diff --git a/src/matchers/toLog/index.js b/src/matchers/toLog/index.js new file mode 100644 index 00000000..2d581713 --- /dev/null +++ b/src/matchers/toLog/index.js @@ -0,0 +1,30 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected, consoleMethod) => () => + matcherHint('.not.toLog') + + '\n\n' + + `Expected console.${consoleMethod} not to have been called with:\n` + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected, consoleMethod) => () => + matcherHint('.toLog') + + '\n\n' + + `Expected console.${consoleMethod} to have been called with:\n` + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toLog: (fn, expected, consoleMethod = 'log') => { + const { actual, pass } = predicate(fn, expected, consoleMethod); + if (pass) { + return { pass: true, message: passMessage(actual, expected, consoleMethod) }; + } + return { pass: false, message: failMessage(actual, expected, consoleMethod) }; + } +}; diff --git a/src/matchers/toLog/index.test.js b/src/matchers/toLog/index.test.js new file mode 100644 index 00000000..8b6fde93 --- /dev/null +++ b/src/matchers/toLog/index.test.js @@ -0,0 +1,73 @@ +import matcher from './'; + +expect.extend(matcher); + +const log = () => console.log('console-log'); // eslint-disable-line +const warn = () => console.warn('console-warn'); // eslint-disable-line +const error = () => console.error('console-error'); // eslint-disable-line +const info = () => console.info('console-info'); // eslint-disable-line +const assert = () => console.assert('console-assert'); // eslint-disable-line +const noop = () => {}; + +describe('.toLog', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(log).toLog('console-log'); + expect(warn).toLog('console-warn', 'warn'); + expect(error).toLog('console-error', 'error'); + expect(info).toLog('console-info', 'info'); + expect(assert).toLog('console-assert', 'assert'); + expect(() => console.log(1)).toLog(1); // eslint-disable-line + expect(() => console.log([1, 2])).toLog([1, 2]); // eslint-disable-line + expect(() => console.log({ a: 1, b: 2 })).toLog({ a: 1, b: 2 }); // eslint-disable-line + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toLog('something')).toThrowErrorMatchingSnapshot(); + expect(() => expect(noop).toLog('something', 'warn')).toThrowErrorMatchingSnapshot(); + expect(() => expect(noop).toLog('something', 'error')).toThrowErrorMatchingSnapshot(); + expect(() => expect(noop).toLog('something', 'info')).toThrowErrorMatchingSnapshot(); + expect(() => expect(noop).toLog('something', 'assert')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(log).toLog('something')).toThrowErrorMatchingSnapshot(); + expect(() => expect(warn).toLog('something', 'warn')).toThrowErrorMatchingSnapshot(); + expect(() => expect(error).toLog('something', 'error')).toThrowErrorMatchingSnapshot(); + expect(() => expect(info).toLog('something', 'info')).toThrowErrorMatchingSnapshot(); + expect(() => expect(assert).toLog('something', 'assert')).toThrowErrorMatchingSnapshot(); + expect(() => + expect(() => { + console.log('a', 'b', 'c'); // eslint-disable-line + log(); + }).toLog('something') + ).toThrowErrorMatchingSnapshot(); + }); + test('passes when the callback function outputs the expected message among others', () => { + expect(() => { + console.log('something'); // eslint-disable-line + log(); + }).toLog('console-log'); + }); +}); + +describe('.not.toLog', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toLog('something'); + expect(noop).not.toLog('something', 'warn'); + expect(noop).not.toLog('something', 'error'); + expect(noop).not.toLog('something', 'info'); + expect(noop).not.toLog('something', 'assert'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(log).not.toLog('something'); + expect(warn).not.toLog('something', 'warn'); + expect(error).not.toLog('something', 'error'); + expect(info).not.toLog('something', 'info'); + expect(assert).not.toLog('something', 'assert'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(log).not.toLog('console-log')).toThrowErrorMatchingSnapshot(); + expect(() => expect(warn).not.toLog('console-warn', 'warn')).toThrowErrorMatchingSnapshot(); + expect(() => expect(error).not.toLog('console-error', 'error')).toThrowErrorMatchingSnapshot(); + expect(() => expect(info).not.toLog('console-info', 'info')).toThrowErrorMatchingSnapshot(); + expect(() => expect(assert).not.toLog('console-assert', 'assert')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLog/predicate.js b/src/matchers/toLog/predicate.js new file mode 100644 index 00000000..45555286 --- /dev/null +++ b/src/matchers/toLog/predicate.js @@ -0,0 +1,21 @@ +import { equals } from 'expect/build/jasmine_utils'; + +export default (fn, expected, consoleMethod) => { + const spy = jest.spyOn(console, consoleMethod); + spy.mockImplementation(() => {}); + fn(); + spy.mockRestore(); + if (spy.mock.calls.length === 0) { + return { pass: false }; + } + const actual = spy.mock.calls; + let pass = false; + actual.forEach(call => { + call.forEach(arg => { + if (equals(arg, expected)) { + pass = true; + } + }); + }); + return { actual, pass }; +}; diff --git a/src/matchers/toLog/predicate.test.js b/src/matchers/toLog/predicate.test.js new file mode 100644 index 00000000..b256791b --- /dev/null +++ b/src/matchers/toLog/predicate.test.js @@ -0,0 +1,20 @@ +import predicate from './predicate'; + +const fn = () => console.log('console-log'); // eslint-disable-line + +describe('Predicate > .toLog', () => { + test('returns an object with pass status and the actual output', () => { + const expected = 'console-log'; + const consoleMethod = 'log'; + const { pass, actual } = predicate(fn, expected, consoleMethod); + expect(pass).toEqual(true); + expect(actual).toEqual([['console-log']]); + }); + it('returns an object with fail status and the actual output', () => { + const expected = 'something'; + const consoleMethod = 'log'; + const { pass, actual } = predicate(fn, expected, consoleMethod); + expect(pass).toEqual(false); + expect(actual).toEqual([['console-log']]); + }); +}); diff --git a/types/index.d.ts b/types/index.d.ts index cd4cc1f4..ec695dec 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -355,6 +355,15 @@ declare namespace jest { * @param {String | RegExp} message */ toThrowWithMessage(type: Function, message: string | RegExp): R; + + /** + * Use `.toLog` when checking if a callback function outputs a message to the console. + * The specified console method is mocked during execution so nothing will be printed to the console. + * + * @param {*} logOutput + * @param {String} [consoleMethod=log] + */ + toLog(logOutput: any, consoleMethod?: string): R; } // noinspection JSUnusedGlobalSymbols From 98d06a1ccbc9ccca9523dafa00ed6fae04635c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20Lauri=20Bostr=C3=B6m?= Date: Mon, 11 Mar 2019 16:23:17 +0100 Subject: [PATCH 2/3] refactor: Rename .toLog() -> .toConsoleLog() and refactor api --- .../__snapshots__/index.test.js.snap | 88 +++++++++++ src/matchers/toConsoleLog/index.js | 44 ++++++ src/matchers/toConsoleLog/index.test.js | 95 ++++++++++++ .../{toLog => toConsoleLog}/predicate.js | 0 .../{toLog => toConsoleLog}/predicate.test.js | 0 .../toLog/__snapshots__/index.test.js.snap | 140 ------------------ src/matchers/toLog/index.js | 30 ---- src/matchers/toLog/index.test.js | 73 --------- 8 files changed, 227 insertions(+), 243 deletions(-) create mode 100644 src/matchers/toConsoleLog/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toConsoleLog/index.js create mode 100644 src/matchers/toConsoleLog/index.test.js rename src/matchers/{toLog => toConsoleLog}/predicate.js (100%) rename src/matchers/{toLog => toConsoleLog}/predicate.test.js (100%) delete mode 100644 src/matchers/toLog/__snapshots__/index.test.js.snap delete mode 100644 src/matchers/toLog/index.js delete mode 100644 src/matchers/toLog/index.test.js diff --git a/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap b/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..472dbb69 --- /dev/null +++ b/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toConsoleError fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toConsoleError(expected) + +Expected console.error not to have been called with: + \\"console-error\\" +But it was called with: + [[\\"console-error\\"]]" +`; + +exports[`.not.toConsoleInfo fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toConsoleInfo(expected) + +Expected console.info not to have been called with: + \\"console-info\\" +But it was called with: + [[\\"console-info\\"]]" +`; + +exports[`.not.toConsoleLog fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toConsoleLog(expected) + +Expected console.log not to have been called with: + \\"console-log\\" +But it was called with: + [[\\"console-log\\"]]" +`; + +exports[`.toConsoleError fails when the callback function does not output any message 1`] = ` +"expect(received).not.toConsoleError(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toConsoleError fails when the callback function does not output the expected message 1`] = ` +"expect(received).not.toConsoleError(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was called with: + [[\\"console-error\\"]]" +`; + +exports[`.toConsoleInfo fails when the callback function does not output any message 1`] = ` +"expect(received).toConsoleInfo(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toConsoleInfo fails when the callback function does not output the expected message 1`] = ` +"expect(received).toConsoleInfo(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was called with: + [[\\"console-info\\"]]" +`; + +exports[`.toConsoleLog fails when the callback function does not output any message 1`] = ` +"expect(received).toConsoleLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toConsoleLog fails when the callback function does not output the expected message 1`] = ` +"expect(received).toConsoleLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [[\\"console-log\\"]]" +`; + +exports[`.toConsoleLog fails when the callback function does not output the expected message 2`] = ` +"expect(received).toConsoleLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [[\\"a\\", \\"b\\", \\"c\\"], [\\"console-log\\"]]" +`; diff --git a/src/matchers/toConsoleLog/index.js b/src/matchers/toConsoleLog/index.js new file mode 100644 index 00000000..8e45ce17 --- /dev/null +++ b/src/matchers/toConsoleLog/index.js @@ -0,0 +1,44 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected, hint, consoleMethod) => () => + matcherHint(hint) + + '\n\n' + + `Expected console.${consoleMethod} not to have been called with:\n` + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected, hint, consoleMethod) => () => + matcherHint(hint) + + '\n\n' + + `Expected console.${consoleMethod} to have been called with:\n` + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toConsoleLog: (fn, expected) => { + const { actual, pass } = predicate(fn, expected, 'log'); + if (pass) { + return { pass: true, message: passMessage(actual, expected, '.not.toConsoleLog', 'log') }; + } + return { pass: false, message: failMessage(actual, expected, '.toConsoleLog', 'log') }; + }, + toConsoleInfo: (fn, expected) => { + const { actual, pass } = predicate(fn, expected, 'info'); + if (pass) { + return { pass: true, message: passMessage(actual, expected, '.not.toConsoleInfo', 'info') }; + } + return { pass: false, message: failMessage(actual, expected, '.toConsoleInfo', 'info') }; + }, + toConsoleError: (fn, expected) => { + const { actual, pass } = predicate(fn, expected, 'error'); + if (pass) { + return { pass: true, message: passMessage(actual, expected, '.not.toConsoleError', 'error') }; + } + return { pass: false, message: failMessage(actual, expected, '.not.toConsoleError', 'error') }; + } +}; diff --git a/src/matchers/toConsoleLog/index.test.js b/src/matchers/toConsoleLog/index.test.js new file mode 100644 index 00000000..3d7e7faa --- /dev/null +++ b/src/matchers/toConsoleLog/index.test.js @@ -0,0 +1,95 @@ +import matcher from './'; + +expect.extend(matcher); + +const log = () => console.log('console-log'); // eslint-disable-line +const error = () => console.error('console-error'); // eslint-disable-line +const info = () => console.info('console-info'); // eslint-disable-line +const noop = () => {}; + +describe('.toConsoleLog', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(log).toConsoleLog('console-log'); + expect(() => console.log(1)).toConsoleLog(1); // eslint-disable-line + expect(() => console.log([1, 2])).toConsoleLog([1, 2]); // eslint-disable-line + expect(() => console.log({ a: 1, b: 2 })).toConsoleLog({ a: 1, b: 2 }); // eslint-disable-line + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toConsoleLog('something')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(log).toConsoleLog('something')).toThrowErrorMatchingSnapshot(); + expect(() => + expect(() => { + console.log('a', 'b', 'c'); // eslint-disable-line + log(); + }).toConsoleLog('something') + ).toThrowErrorMatchingSnapshot(); + }); + test('passes when the callback function outputs the expected message among others', () => { + expect(() => { + console.log('something'); // eslint-disable-line + log(); + }).toConsoleLog('console-log'); + }); +}); + +describe('.toConsoleInfo', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(info).toConsoleInfo('console-info', 'info'); + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toConsoleInfo('something', 'info')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(info).toConsoleInfo('something', 'info')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.toConsoleError', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(error).toConsoleError('console-error', 'error'); + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toConsoleError('something', 'error')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(error).toConsoleError('something', 'error')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toConsoleLog', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toConsoleLog('something'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(log).not.toConsoleLog('something'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(log).not.toConsoleLog('console-log')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toConsoleInfo', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toConsoleInfo('something', 'info'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(info).not.toConsoleInfo('something', 'info'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(info).not.toConsoleInfo('console-info', 'info')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toConsoleError', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toConsoleError('something', 'error'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(error).not.toConsoleError('something', 'error'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(error).not.toConsoleError('console-error', 'error')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLog/predicate.js b/src/matchers/toConsoleLog/predicate.js similarity index 100% rename from src/matchers/toLog/predicate.js rename to src/matchers/toConsoleLog/predicate.js diff --git a/src/matchers/toLog/predicate.test.js b/src/matchers/toConsoleLog/predicate.test.js similarity index 100% rename from src/matchers/toLog/predicate.test.js rename to src/matchers/toConsoleLog/predicate.test.js diff --git a/src/matchers/toLog/__snapshots__/index.test.js.snap b/src/matchers/toLog/__snapshots__/index.test.js.snap deleted file mode 100644 index 30790a10..00000000 --- a/src/matchers/toLog/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,140 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`.not.toLog fails when the callback function outputs the expected message 1`] = ` -"expect(received).not.toLog(expected) - -Expected console.log not to have been called with: - \\"console-log\\" -But it was called with: - [[\\"console-log\\"]]" -`; - -exports[`.not.toLog fails when the callback function outputs the expected message 2`] = ` -"expect(received).not.toLog(expected) - -Expected console.warn not to have been called with: - \\"console-warn\\" -But it was called with: - [[\\"console-warn\\"]]" -`; - -exports[`.not.toLog fails when the callback function outputs the expected message 3`] = ` -"expect(received).not.toLog(expected) - -Expected console.error not to have been called with: - \\"console-error\\" -But it was called with: - [[\\"console-error\\"]]" -`; - -exports[`.not.toLog fails when the callback function outputs the expected message 4`] = ` -"expect(received).not.toLog(expected) - -Expected console.info not to have been called with: - \\"console-info\\" -But it was called with: - [[\\"console-info\\"]]" -`; - -exports[`.not.toLog fails when the callback function outputs the expected message 5`] = ` -"expect(received).not.toLog(expected) - -Expected console.assert not to have been called with: - \\"console-assert\\" -But it was called with: - [[\\"console-assert\\"]]" -`; - -exports[`.toLog fails when the callback function does not output any message 1`] = ` -"expect(received).toLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toLog fails when the callback function does not output any message 2`] = ` -"expect(received).toLog(expected) - -Expected console.warn to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toLog fails when the callback function does not output any message 3`] = ` -"expect(received).toLog(expected) - -Expected console.error to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toLog fails when the callback function does not output any message 4`] = ` -"expect(received).toLog(expected) - -Expected console.info to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toLog fails when the callback function does not output any message 5`] = ` -"expect(received).toLog(expected) - -Expected console.assert to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toLog fails when the callback function does not output the expected message 1`] = ` -"expect(received).toLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was called with: - [[\\"console-log\\"]]" -`; - -exports[`.toLog fails when the callback function does not output the expected message 2`] = ` -"expect(received).toLog(expected) - -Expected console.warn to have been called with: - \\"something\\" -But it was called with: - [[\\"console-warn\\"]]" -`; - -exports[`.toLog fails when the callback function does not output the expected message 3`] = ` -"expect(received).toLog(expected) - -Expected console.error to have been called with: - \\"something\\" -But it was called with: - [[\\"console-error\\"]]" -`; - -exports[`.toLog fails when the callback function does not output the expected message 4`] = ` -"expect(received).toLog(expected) - -Expected console.info to have been called with: - \\"something\\" -But it was called with: - [[\\"console-info\\"]]" -`; - -exports[`.toLog fails when the callback function does not output the expected message 5`] = ` -"expect(received).toLog(expected) - -Expected console.assert to have been called with: - \\"something\\" -But it was called with: - [[\\"console-assert\\"]]" -`; - -exports[`.toLog fails when the callback function does not output the expected message 6`] = ` -"expect(received).toLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was called with: - [[\\"a\\", \\"b\\", \\"c\\"], [\\"console-log\\"]]" -`; diff --git a/src/matchers/toLog/index.js b/src/matchers/toLog/index.js deleted file mode 100644 index 2d581713..00000000 --- a/src/matchers/toLog/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; - -import predicate from './predicate'; - -const calledWith = actual => - actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; - -const passMessage = (actual, expected, consoleMethod) => () => - matcherHint('.not.toLog') + - '\n\n' + - `Expected console.${consoleMethod} not to have been called with:\n` + - ` ${printExpected(expected)}\n` + - calledWith(actual); - -const failMessage = (actual, expected, consoleMethod) => () => - matcherHint('.toLog') + - '\n\n' + - `Expected console.${consoleMethod} to have been called with:\n` + - ` ${printExpected(expected)}\n` + - calledWith(actual); - -export default { - toLog: (fn, expected, consoleMethod = 'log') => { - const { actual, pass } = predicate(fn, expected, consoleMethod); - if (pass) { - return { pass: true, message: passMessage(actual, expected, consoleMethod) }; - } - return { pass: false, message: failMessage(actual, expected, consoleMethod) }; - } -}; diff --git a/src/matchers/toLog/index.test.js b/src/matchers/toLog/index.test.js deleted file mode 100644 index 8b6fde93..00000000 --- a/src/matchers/toLog/index.test.js +++ /dev/null @@ -1,73 +0,0 @@ -import matcher from './'; - -expect.extend(matcher); - -const log = () => console.log('console-log'); // eslint-disable-line -const warn = () => console.warn('console-warn'); // eslint-disable-line -const error = () => console.error('console-error'); // eslint-disable-line -const info = () => console.info('console-info'); // eslint-disable-line -const assert = () => console.assert('console-assert'); // eslint-disable-line -const noop = () => {}; - -describe('.toLog', () => { - test('passes when the callback function outputs the expected message to the console', () => { - expect(log).toLog('console-log'); - expect(warn).toLog('console-warn', 'warn'); - expect(error).toLog('console-error', 'error'); - expect(info).toLog('console-info', 'info'); - expect(assert).toLog('console-assert', 'assert'); - expect(() => console.log(1)).toLog(1); // eslint-disable-line - expect(() => console.log([1, 2])).toLog([1, 2]); // eslint-disable-line - expect(() => console.log({ a: 1, b: 2 })).toLog({ a: 1, b: 2 }); // eslint-disable-line - }); - test('fails when the callback function does not output any message', () => { - expect(() => expect(noop).toLog('something')).toThrowErrorMatchingSnapshot(); - expect(() => expect(noop).toLog('something', 'warn')).toThrowErrorMatchingSnapshot(); - expect(() => expect(noop).toLog('something', 'error')).toThrowErrorMatchingSnapshot(); - expect(() => expect(noop).toLog('something', 'info')).toThrowErrorMatchingSnapshot(); - expect(() => expect(noop).toLog('something', 'assert')).toThrowErrorMatchingSnapshot(); - }); - test('fails when the callback function does not output the expected message', () => { - expect(() => expect(log).toLog('something')).toThrowErrorMatchingSnapshot(); - expect(() => expect(warn).toLog('something', 'warn')).toThrowErrorMatchingSnapshot(); - expect(() => expect(error).toLog('something', 'error')).toThrowErrorMatchingSnapshot(); - expect(() => expect(info).toLog('something', 'info')).toThrowErrorMatchingSnapshot(); - expect(() => expect(assert).toLog('something', 'assert')).toThrowErrorMatchingSnapshot(); - expect(() => - expect(() => { - console.log('a', 'b', 'c'); // eslint-disable-line - log(); - }).toLog('something') - ).toThrowErrorMatchingSnapshot(); - }); - test('passes when the callback function outputs the expected message among others', () => { - expect(() => { - console.log('something'); // eslint-disable-line - log(); - }).toLog('console-log'); - }); -}); - -describe('.not.toLog', () => { - test('passes when the callback function does not output anything', () => { - expect(noop).not.toLog('something'); - expect(noop).not.toLog('something', 'warn'); - expect(noop).not.toLog('something', 'error'); - expect(noop).not.toLog('something', 'info'); - expect(noop).not.toLog('something', 'assert'); - }); - test('passes when the callback function does not output the expected message', () => { - expect(log).not.toLog('something'); - expect(warn).not.toLog('something', 'warn'); - expect(error).not.toLog('something', 'error'); - expect(info).not.toLog('something', 'info'); - expect(assert).not.toLog('something', 'assert'); - }); - test('fails when the callback function outputs the expected message', () => { - expect(() => expect(log).not.toLog('console-log')).toThrowErrorMatchingSnapshot(); - expect(() => expect(warn).not.toLog('console-warn', 'warn')).toThrowErrorMatchingSnapshot(); - expect(() => expect(error).not.toLog('console-error', 'error')).toThrowErrorMatchingSnapshot(); - expect(() => expect(info).not.toLog('console-info', 'info')).toThrowErrorMatchingSnapshot(); - expect(() => expect(assert).not.toLog('console-assert', 'assert')).toThrowErrorMatchingSnapshot(); - }); -}); From 048a0ad58d198e1d9784162fcfe3a82d31d6321e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20Lauri=20Bostr=C3=B6m?= Date: Thu, 21 Mar 2019 00:37:15 +0100 Subject: [PATCH 3/3] refactor: Seperate matchers and clean up API --- .../__snapshots__/index.test.js.snap | 88 ----------------- src/matchers/toConsoleLog/index.js | 44 --------- src/matchers/toConsoleLog/index.test.js | 95 ------------------- src/matchers/toConsoleLog/predicate.js | 21 ---- .../toLog/__snapshots__/index.test.js.snap | 36 +++++++ src/matchers/toLog/index.js | 30 ++++++ src/matchers/toLog/index.test.js | 45 +++++++++ src/matchers/toLog/predicate.js | 17 ++++ .../{toConsoleLog => toLog}/predicate.test.js | 10 +- .../__snapshots__/index.test.js.snap | 27 ++++++ src/matchers/toLogError/index.js | 30 ++++++ src/matchers/toLogError/index.test.js | 30 ++++++ src/matchers/toLogError/predicate.js | 17 ++++ src/matchers/toLogError/predicate.test.js | 18 ++++ .../__snapshots__/index.test.js.snap | 27 ++++++ src/matchers/toLogInfo/index.js | 30 ++++++ src/matchers/toLogInfo/index.test.js | 30 ++++++ src/matchers/toLogInfo/predicate.js | 17 ++++ src/matchers/toLogInfo/predicate.test.js | 18 ++++ .../__snapshots__/index.test.js.snap | 27 ++++++ src/matchers/toLogWarning/index.js | 30 ++++++ src/matchers/toLogWarning/index.test.js | 30 ++++++ src/matchers/toLogWarning/predicate.js | 17 ++++ src/matchers/toLogWarning/predicate.test.js | 18 ++++ 24 files changed, 498 insertions(+), 254 deletions(-) delete mode 100644 src/matchers/toConsoleLog/__snapshots__/index.test.js.snap delete mode 100644 src/matchers/toConsoleLog/index.js delete mode 100644 src/matchers/toConsoleLog/index.test.js delete mode 100644 src/matchers/toConsoleLog/predicate.js create mode 100644 src/matchers/toLog/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toLog/index.js create mode 100644 src/matchers/toLog/index.test.js create mode 100644 src/matchers/toLog/predicate.js rename src/matchers/{toConsoleLog => toLog}/predicate.test.js (59%) create mode 100644 src/matchers/toLogError/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toLogError/index.js create mode 100644 src/matchers/toLogError/index.test.js create mode 100644 src/matchers/toLogError/predicate.js create mode 100644 src/matchers/toLogError/predicate.test.js create mode 100644 src/matchers/toLogInfo/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toLogInfo/index.js create mode 100644 src/matchers/toLogInfo/index.test.js create mode 100644 src/matchers/toLogInfo/predicate.js create mode 100644 src/matchers/toLogInfo/predicate.test.js create mode 100644 src/matchers/toLogWarning/__snapshots__/index.test.js.snap create mode 100644 src/matchers/toLogWarning/index.js create mode 100644 src/matchers/toLogWarning/index.test.js create mode 100644 src/matchers/toLogWarning/predicate.js create mode 100644 src/matchers/toLogWarning/predicate.test.js diff --git a/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap b/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap deleted file mode 100644 index 472dbb69..00000000 --- a/src/matchers/toConsoleLog/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,88 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`.not.toConsoleError fails when the callback function outputs the expected message 1`] = ` -"expect(received).not.toConsoleError(expected) - -Expected console.error not to have been called with: - \\"console-error\\" -But it was called with: - [[\\"console-error\\"]]" -`; - -exports[`.not.toConsoleInfo fails when the callback function outputs the expected message 1`] = ` -"expect(received).not.toConsoleInfo(expected) - -Expected console.info not to have been called with: - \\"console-info\\" -But it was called with: - [[\\"console-info\\"]]" -`; - -exports[`.not.toConsoleLog fails when the callback function outputs the expected message 1`] = ` -"expect(received).not.toConsoleLog(expected) - -Expected console.log not to have been called with: - \\"console-log\\" -But it was called with: - [[\\"console-log\\"]]" -`; - -exports[`.toConsoleError fails when the callback function does not output any message 1`] = ` -"expect(received).not.toConsoleError(expected) - -Expected console.error to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toConsoleError fails when the callback function does not output the expected message 1`] = ` -"expect(received).not.toConsoleError(expected) - -Expected console.error to have been called with: - \\"something\\" -But it was called with: - [[\\"console-error\\"]]" -`; - -exports[`.toConsoleInfo fails when the callback function does not output any message 1`] = ` -"expect(received).toConsoleInfo(expected) - -Expected console.info to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toConsoleInfo fails when the callback function does not output the expected message 1`] = ` -"expect(received).toConsoleInfo(expected) - -Expected console.info to have been called with: - \\"something\\" -But it was called with: - [[\\"console-info\\"]]" -`; - -exports[`.toConsoleLog fails when the callback function does not output any message 1`] = ` -"expect(received).toConsoleLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was not called" -`; - -exports[`.toConsoleLog fails when the callback function does not output the expected message 1`] = ` -"expect(received).toConsoleLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was called with: - [[\\"console-log\\"]]" -`; - -exports[`.toConsoleLog fails when the callback function does not output the expected message 2`] = ` -"expect(received).toConsoleLog(expected) - -Expected console.log to have been called with: - \\"something\\" -But it was called with: - [[\\"a\\", \\"b\\", \\"c\\"], [\\"console-log\\"]]" -`; diff --git a/src/matchers/toConsoleLog/index.js b/src/matchers/toConsoleLog/index.js deleted file mode 100644 index 8e45ce17..00000000 --- a/src/matchers/toConsoleLog/index.js +++ /dev/null @@ -1,44 +0,0 @@ -import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; - -import predicate from './predicate'; - -const calledWith = actual => - actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; - -const passMessage = (actual, expected, hint, consoleMethod) => () => - matcherHint(hint) + - '\n\n' + - `Expected console.${consoleMethod} not to have been called with:\n` + - ` ${printExpected(expected)}\n` + - calledWith(actual); - -const failMessage = (actual, expected, hint, consoleMethod) => () => - matcherHint(hint) + - '\n\n' + - `Expected console.${consoleMethod} to have been called with:\n` + - ` ${printExpected(expected)}\n` + - calledWith(actual); - -export default { - toConsoleLog: (fn, expected) => { - const { actual, pass } = predicate(fn, expected, 'log'); - if (pass) { - return { pass: true, message: passMessage(actual, expected, '.not.toConsoleLog', 'log') }; - } - return { pass: false, message: failMessage(actual, expected, '.toConsoleLog', 'log') }; - }, - toConsoleInfo: (fn, expected) => { - const { actual, pass } = predicate(fn, expected, 'info'); - if (pass) { - return { pass: true, message: passMessage(actual, expected, '.not.toConsoleInfo', 'info') }; - } - return { pass: false, message: failMessage(actual, expected, '.toConsoleInfo', 'info') }; - }, - toConsoleError: (fn, expected) => { - const { actual, pass } = predicate(fn, expected, 'error'); - if (pass) { - return { pass: true, message: passMessage(actual, expected, '.not.toConsoleError', 'error') }; - } - return { pass: false, message: failMessage(actual, expected, '.not.toConsoleError', 'error') }; - } -}; diff --git a/src/matchers/toConsoleLog/index.test.js b/src/matchers/toConsoleLog/index.test.js deleted file mode 100644 index 3d7e7faa..00000000 --- a/src/matchers/toConsoleLog/index.test.js +++ /dev/null @@ -1,95 +0,0 @@ -import matcher from './'; - -expect.extend(matcher); - -const log = () => console.log('console-log'); // eslint-disable-line -const error = () => console.error('console-error'); // eslint-disable-line -const info = () => console.info('console-info'); // eslint-disable-line -const noop = () => {}; - -describe('.toConsoleLog', () => { - test('passes when the callback function outputs the expected message to the console', () => { - expect(log).toConsoleLog('console-log'); - expect(() => console.log(1)).toConsoleLog(1); // eslint-disable-line - expect(() => console.log([1, 2])).toConsoleLog([1, 2]); // eslint-disable-line - expect(() => console.log({ a: 1, b: 2 })).toConsoleLog({ a: 1, b: 2 }); // eslint-disable-line - }); - test('fails when the callback function does not output any message', () => { - expect(() => expect(noop).toConsoleLog('something')).toThrowErrorMatchingSnapshot(); - }); - test('fails when the callback function does not output the expected message', () => { - expect(() => expect(log).toConsoleLog('something')).toThrowErrorMatchingSnapshot(); - expect(() => - expect(() => { - console.log('a', 'b', 'c'); // eslint-disable-line - log(); - }).toConsoleLog('something') - ).toThrowErrorMatchingSnapshot(); - }); - test('passes when the callback function outputs the expected message among others', () => { - expect(() => { - console.log('something'); // eslint-disable-line - log(); - }).toConsoleLog('console-log'); - }); -}); - -describe('.toConsoleInfo', () => { - test('passes when the callback function outputs the expected message to the console', () => { - expect(info).toConsoleInfo('console-info', 'info'); - }); - test('fails when the callback function does not output any message', () => { - expect(() => expect(noop).toConsoleInfo('something', 'info')).toThrowErrorMatchingSnapshot(); - }); - test('fails when the callback function does not output the expected message', () => { - expect(() => expect(info).toConsoleInfo('something', 'info')).toThrowErrorMatchingSnapshot(); - }); -}); - -describe('.toConsoleError', () => { - test('passes when the callback function outputs the expected message to the console', () => { - expect(error).toConsoleError('console-error', 'error'); - }); - test('fails when the callback function does not output any message', () => { - expect(() => expect(noop).toConsoleError('something', 'error')).toThrowErrorMatchingSnapshot(); - }); - test('fails when the callback function does not output the expected message', () => { - expect(() => expect(error).toConsoleError('something', 'error')).toThrowErrorMatchingSnapshot(); - }); -}); - -describe('.not.toConsoleLog', () => { - test('passes when the callback function does not output anything', () => { - expect(noop).not.toConsoleLog('something'); - }); - test('passes when the callback function does not output the expected message', () => { - expect(log).not.toConsoleLog('something'); - }); - test('fails when the callback function outputs the expected message', () => { - expect(() => expect(log).not.toConsoleLog('console-log')).toThrowErrorMatchingSnapshot(); - }); -}); - -describe('.not.toConsoleInfo', () => { - test('passes when the callback function does not output anything', () => { - expect(noop).not.toConsoleInfo('something', 'info'); - }); - test('passes when the callback function does not output the expected message', () => { - expect(info).not.toConsoleInfo('something', 'info'); - }); - test('fails when the callback function outputs the expected message', () => { - expect(() => expect(info).not.toConsoleInfo('console-info', 'info')).toThrowErrorMatchingSnapshot(); - }); -}); - -describe('.not.toConsoleError', () => { - test('passes when the callback function does not output anything', () => { - expect(noop).not.toConsoleError('something', 'error'); - }); - test('passes when the callback function does not output the expected message', () => { - expect(error).not.toConsoleError('something', 'error'); - }); - test('fails when the callback function outputs the expected message', () => { - expect(() => expect(error).not.toConsoleError('console-error', 'error')).toThrowErrorMatchingSnapshot(); - }); -}); diff --git a/src/matchers/toConsoleLog/predicate.js b/src/matchers/toConsoleLog/predicate.js deleted file mode 100644 index 45555286..00000000 --- a/src/matchers/toConsoleLog/predicate.js +++ /dev/null @@ -1,21 +0,0 @@ -import { equals } from 'expect/build/jasmine_utils'; - -export default (fn, expected, consoleMethod) => { - const spy = jest.spyOn(console, consoleMethod); - spy.mockImplementation(() => {}); - fn(); - spy.mockRestore(); - if (spy.mock.calls.length === 0) { - return { pass: false }; - } - const actual = spy.mock.calls; - let pass = false; - actual.forEach(call => { - call.forEach(arg => { - if (equals(arg, expected)) { - pass = true; - } - }); - }); - return { actual, pass }; -}; diff --git a/src/matchers/toLog/__snapshots__/index.test.js.snap b/src/matchers/toLog/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..8e5615f5 --- /dev/null +++ b/src/matchers/toLog/__snapshots__/index.test.js.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toLog fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toLog(expected) + +Expected console.log not to have been called with: + \\"console-log\\" +But it was called with: + [\\"console-log\\"]" +`; + +exports[`.toLog fails when the callback function does not output any message 1`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLog fails when the callback function does not output the expected message 1`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [\\"console-log\\"]" +`; + +exports[`.toLog fails when the callback function does not output the expected message 2`] = ` +"expect(received).toLog(expected) + +Expected console.log to have been called with: + \\"something\\" +But it was called with: + [\\"a\\", \\"b\\", \\"c\\", \\"console-log\\"]" +`; diff --git a/src/matchers/toLog/index.js b/src/matchers/toLog/index.js new file mode 100644 index 00000000..e4a2981f --- /dev/null +++ b/src/matchers/toLog/index.js @@ -0,0 +1,30 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected) => () => + matcherHint('.not.toLog') + + '\n\n' + + 'Expected console.log not to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected) => () => + matcherHint('.toLog') + + '\n\n' + + 'Expected console.log to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toLog: (fn, expected) => { + const { actual, pass } = predicate(fn, expected); + if (pass) { + return { pass: true, message: passMessage(actual, expected) }; + } + return { pass: false, message: failMessage(actual, expected) }; + } +}; diff --git a/src/matchers/toLog/index.test.js b/src/matchers/toLog/index.test.js new file mode 100644 index 00000000..b35bf388 --- /dev/null +++ b/src/matchers/toLog/index.test.js @@ -0,0 +1,45 @@ +import matcher from './'; + +expect.extend(matcher); + +const log = () => console.log('console-log'); // eslint-disable-line +const noop = () => {}; + +describe('.toLog', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(log).toLog('console-log'); + expect(() => console.log(1)).toLog(1); // eslint-disable-line + expect(() => console.log([1, 2])).toLog([1, 2]); // eslint-disable-line + expect(() => console.log({ a: 1, b: 2 })).toLog({ a: 1, b: 2 }); // eslint-disable-line + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toLog('something')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(log).toLog('something')).toThrowErrorMatchingSnapshot(); + expect(() => + expect(() => { + console.log('a', 'b', 'c'); // eslint-disable-line + log(); + }).toLog('something') + ).toThrowErrorMatchingSnapshot(); + }); + test('passes when the callback function outputs the expected message among others', () => { + expect(() => { + console.log('something'); // eslint-disable-line + log(); + }).toLog('console-log'); + }); +}); + +describe('.not.toLog', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toLog('something'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(log).not.toLog('something'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(log).not.toLog('console-log')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLog/predicate.js b/src/matchers/toLog/predicate.js new file mode 100644 index 00000000..23540907 --- /dev/null +++ b/src/matchers/toLog/predicate.js @@ -0,0 +1,17 @@ +import { equals } from 'expect/build/jasmine_utils'; + +export default (fn, expected) => { + const log = console.log; // eslint-disable-line no-console + const actual = []; + console.log = (...args) => actual.push(...args); // eslint-disable-line no-console + try { + fn(); + } finally { + console.log = log; // eslint-disable-line no-console + } + if (actual.length < 1) { + return { pass: false }; + } + const pass = actual.some(message => equals(message, expected)); + return { actual, pass }; +}; diff --git a/src/matchers/toConsoleLog/predicate.test.js b/src/matchers/toLog/predicate.test.js similarity index 59% rename from src/matchers/toConsoleLog/predicate.test.js rename to src/matchers/toLog/predicate.test.js index b256791b..1d4d5906 100644 --- a/src/matchers/toConsoleLog/predicate.test.js +++ b/src/matchers/toLog/predicate.test.js @@ -5,16 +5,14 @@ const fn = () => console.log('console-log'); // eslint-disable-line describe('Predicate > .toLog', () => { test('returns an object with pass status and the actual output', () => { const expected = 'console-log'; - const consoleMethod = 'log'; - const { pass, actual } = predicate(fn, expected, consoleMethod); + const { pass, actual } = predicate(fn, expected); expect(pass).toEqual(true); - expect(actual).toEqual([['console-log']]); + expect(actual).toEqual(['console-log']); }); it('returns an object with fail status and the actual output', () => { const expected = 'something'; - const consoleMethod = 'log'; - const { pass, actual } = predicate(fn, expected, consoleMethod); + const { pass, actual } = predicate(fn, expected); expect(pass).toEqual(false); - expect(actual).toEqual([['console-log']]); + expect(actual).toEqual(['console-log']); }); }); diff --git a/src/matchers/toLogError/__snapshots__/index.test.js.snap b/src/matchers/toLogError/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..29334123 --- /dev/null +++ b/src/matchers/toLogError/__snapshots__/index.test.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toLogError fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toLogError(expected) + +Expected console.error not to have been called with: + \\"console-error\\" +But it was called with: + [\\"console-error\\"]" +`; + +exports[`.toLogError fails when the callback function does not output any message 1`] = ` +"expect(received).toLogError(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLogError fails when the callback function does not output the expected message 1`] = ` +"expect(received).toLogError(expected) + +Expected console.error to have been called with: + \\"something\\" +But it was called with: + [\\"console-error\\"]" +`; diff --git a/src/matchers/toLogError/index.js b/src/matchers/toLogError/index.js new file mode 100644 index 00000000..0d9287be --- /dev/null +++ b/src/matchers/toLogError/index.js @@ -0,0 +1,30 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected) => () => + matcherHint('.not.toLogError') + + '\n\n' + + 'Expected console.error not to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected) => () => + matcherHint('.toLogError') + + '\n\n' + + 'Expected console.error to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toLogError: (fn, expected) => { + const { actual, pass } = predicate(fn, expected); + if (pass) { + return { pass: true, message: passMessage(actual, expected) }; + } + return { pass: false, message: failMessage(actual, expected) }; + } +}; diff --git a/src/matchers/toLogError/index.test.js b/src/matchers/toLogError/index.test.js new file mode 100644 index 00000000..2244dd3f --- /dev/null +++ b/src/matchers/toLogError/index.test.js @@ -0,0 +1,30 @@ +import matcher from './'; + +expect.extend(matcher); + +const error = () => console.error('console-error'); // eslint-disable-line +const noop = () => {}; + +describe('.toLogError', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(error).toLogError('console-error'); + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toLogError('something')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(error).toLogError('something')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toLogError', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toLogError('something'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(error).not.toLogError('something'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(error).not.toLogError('console-error')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLogError/predicate.js b/src/matchers/toLogError/predicate.js new file mode 100644 index 00000000..70901c0b --- /dev/null +++ b/src/matchers/toLogError/predicate.js @@ -0,0 +1,17 @@ +import { equals } from 'expect/build/jasmine_utils'; + +export default (fn, expected) => { + const error = console.error; // eslint-disable-line no-console + const actual = []; + console.error = (...args) => actual.push(...args); // eslint-disable-line no-console + try { + fn(); + } finally { + console.error = error; // eslint-disable-line no-console + } + if (actual.length < 1) { + return { pass: false }; + } + const pass = actual.some(message => equals(message, expected)); + return { actual, pass }; +}; diff --git a/src/matchers/toLogError/predicate.test.js b/src/matchers/toLogError/predicate.test.js new file mode 100644 index 00000000..e867f2ce --- /dev/null +++ b/src/matchers/toLogError/predicate.test.js @@ -0,0 +1,18 @@ +import predicate from './predicate'; + +const fn = () => console.error('console-error'); // eslint-disable-line + +describe('Predicate > .toLogError', () => { + test('returns an object with pass status and the actual output', () => { + const expected = 'console-error'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(true); + expect(actual).toEqual(['console-error']); + }); + it('returns an object with fail status and the actual output', () => { + const expected = 'something'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(false); + expect(actual).toEqual(['console-error']); + }); +}); diff --git a/src/matchers/toLogInfo/__snapshots__/index.test.js.snap b/src/matchers/toLogInfo/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..3fce9c9b --- /dev/null +++ b/src/matchers/toLogInfo/__snapshots__/index.test.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toLogInfo fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toLogInfo(expected) + +Expected console.info not to have been called with: + \\"console-info\\" +But it was called with: + [\\"console-info\\"]" +`; + +exports[`.toLogInfo fails when the callback function does not output any message 1`] = ` +"expect(received).toLogInfo(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLogInfo fails when the callback function does not output the expected message 1`] = ` +"expect(received).toLogInfo(expected) + +Expected console.info to have been called with: + \\"something\\" +But it was called with: + [\\"console-info\\"]" +`; diff --git a/src/matchers/toLogInfo/index.js b/src/matchers/toLogInfo/index.js new file mode 100644 index 00000000..a7b08557 --- /dev/null +++ b/src/matchers/toLogInfo/index.js @@ -0,0 +1,30 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected) => () => + matcherHint('.not.toLogInfo') + + '\n\n' + + 'Expected console.info not to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected) => () => + matcherHint('.toLogInfo') + + '\n\n' + + 'Expected console.info to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toLogInfo: (fn, expected) => { + const { actual, pass } = predicate(fn, expected); + if (pass) { + return { pass: true, message: passMessage(actual, expected) }; + } + return { pass: false, message: failMessage(actual, expected) }; + } +}; diff --git a/src/matchers/toLogInfo/index.test.js b/src/matchers/toLogInfo/index.test.js new file mode 100644 index 00000000..865542df --- /dev/null +++ b/src/matchers/toLogInfo/index.test.js @@ -0,0 +1,30 @@ +import matcher from './'; + +expect.extend(matcher); + +const info = () => console.info('console-info'); // eslint-disable-line +const noop = () => {}; + +describe('.toLogInfo', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(info).toLogInfo('console-info'); + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toLogInfo('something')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(info).toLogInfo('something')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toLogInfo', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toLogInfo('something'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(info).not.toLogInfo('something'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(info).not.toLogInfo('console-info')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLogInfo/predicate.js b/src/matchers/toLogInfo/predicate.js new file mode 100644 index 00000000..1856f86f --- /dev/null +++ b/src/matchers/toLogInfo/predicate.js @@ -0,0 +1,17 @@ +import { equals } from 'expect/build/jasmine_utils'; + +export default (fn, expected) => { + const info = console.info; // eslint-disable-line no-console + const actual = []; + console.info = (...args) => actual.push(...args); // eslint-disable-line no-console + try { + fn(); + } finally { + console.info = info; // eslint-disable-line no-console + } + if (actual.length < 1) { + return { pass: false }; + } + const pass = actual.some(message => equals(message, expected)); + return { actual, pass }; +}; diff --git a/src/matchers/toLogInfo/predicate.test.js b/src/matchers/toLogInfo/predicate.test.js new file mode 100644 index 00000000..807cdafd --- /dev/null +++ b/src/matchers/toLogInfo/predicate.test.js @@ -0,0 +1,18 @@ +import predicate from './predicate'; + +const fn = () => console.info('console-info'); // eslint-disable-line + +describe('Predicate > .toLogInfo', () => { + test('returns an object with pass status and the actual output', () => { + const expected = 'console-info'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(true); + expect(actual).toEqual(['console-info']); + }); + it('returns an object with fail status and the actual output', () => { + const expected = 'something'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(false); + expect(actual).toEqual(['console-info']); + }); +}); diff --git a/src/matchers/toLogWarning/__snapshots__/index.test.js.snap b/src/matchers/toLogWarning/__snapshots__/index.test.js.snap new file mode 100644 index 00000000..a752247e --- /dev/null +++ b/src/matchers/toLogWarning/__snapshots__/index.test.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toLogWarning fails when the callback function outputs the expected message 1`] = ` +"expect(received).not.toLogWarning(expected) + +Expected console.warn not to have been called with: + \\"console-warning\\" +But it was called with: + [\\"console-warning\\"]" +`; + +exports[`.toLogWarning fails when the callback function does not output any message 1`] = ` +"expect(received).toLogWarning(expected) + +Expected console.warn to have been called with: + \\"something\\" +But it was not called" +`; + +exports[`.toLogWarning fails when the callback function does not output the expected message 1`] = ` +"expect(received).toLogWarning(expected) + +Expected console.warn to have been called with: + \\"something\\" +But it was called with: + [\\"console-warning\\"]" +`; diff --git a/src/matchers/toLogWarning/index.js b/src/matchers/toLogWarning/index.js new file mode 100644 index 00000000..5b551f1e --- /dev/null +++ b/src/matchers/toLogWarning/index.js @@ -0,0 +1,30 @@ +import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; + +import predicate from './predicate'; + +const calledWith = actual => + actual ? 'But it was called with:\n' + ` ${printReceived(actual)}` : 'But it was not called'; + +const passMessage = (actual, expected) => () => + matcherHint('.not.toLogWarning') + + '\n\n' + + 'Expected console.warn not to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +const failMessage = (actual, expected) => () => + matcherHint('.toLogWarning') + + '\n\n' + + 'Expected console.warn to have been called with:\n' + + ` ${printExpected(expected)}\n` + + calledWith(actual); + +export default { + toLogWarning: (fn, expected) => { + const { actual, pass } = predicate(fn, expected); + if (pass) { + return { pass: true, message: passMessage(actual, expected) }; + } + return { pass: false, message: failMessage(actual, expected) }; + } +}; diff --git a/src/matchers/toLogWarning/index.test.js b/src/matchers/toLogWarning/index.test.js new file mode 100644 index 00000000..44245a02 --- /dev/null +++ b/src/matchers/toLogWarning/index.test.js @@ -0,0 +1,30 @@ +import matcher from './'; + +expect.extend(matcher); + +const warn = () => console.warn('console-warning'); // eslint-disable-line +const noop = () => {}; + +describe('.toLogWarning', () => { + test('passes when the callback function outputs the expected message to the console', () => { + expect(warn).toLogWarning('console-warning'); + }); + test('fails when the callback function does not output any message', () => { + expect(() => expect(noop).toLogWarning('something')).toThrowErrorMatchingSnapshot(); + }); + test('fails when the callback function does not output the expected message', () => { + expect(() => expect(warn).toLogWarning('something')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toLogWarning', () => { + test('passes when the callback function does not output anything', () => { + expect(noop).not.toLogWarning('something'); + }); + test('passes when the callback function does not output the expected message', () => { + expect(warn).not.toLogWarning('something'); + }); + test('fails when the callback function outputs the expected message', () => { + expect(() => expect(warn).not.toLogWarning('console-warning')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/matchers/toLogWarning/predicate.js b/src/matchers/toLogWarning/predicate.js new file mode 100644 index 00000000..cefc8663 --- /dev/null +++ b/src/matchers/toLogWarning/predicate.js @@ -0,0 +1,17 @@ +import { equals } from 'expect/build/jasmine_utils'; + +export default (fn, expected) => { + const warn = console.warn; // eslint-disable-line no-console + const actual = []; + console.warn = (...args) => actual.push(...args); // eslint-disable-line no-console + try { + fn(); + } finally { + console.warn = warn; // eslint-disable-line no-console + } + if (actual.length < 1) { + return { pass: false }; + } + const pass = actual.some(message => equals(message, expected)); + return { actual, pass }; +}; diff --git a/src/matchers/toLogWarning/predicate.test.js b/src/matchers/toLogWarning/predicate.test.js new file mode 100644 index 00000000..6e7bebcb --- /dev/null +++ b/src/matchers/toLogWarning/predicate.test.js @@ -0,0 +1,18 @@ +import predicate from './predicate'; + +const fn = () => console.warn('console-warn'); // eslint-disable-line + +describe('Predicate > .toLogWarning', () => { + test('returns an object with pass status and the actual output', () => { + const expected = 'console-warn'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(true); + expect(actual).toEqual(['console-warn']); + }); + it('returns an object with fail status and the actual output', () => { + const expected = 'something'; + const { pass, actual } = predicate(fn, expected); + expect(pass).toEqual(false); + expect(actual).toEqual(['console-warn']); + }); +});