diff --git a/packages/jest-console/CHANGELOG.md b/packages/jest-console/CHANGELOG.md index caa7f460f6f2b4..f5aa959e2542e7 100644 --- a/packages/jest-console/CHANGELOG.md +++ b/packages/jest-console/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- Improved error messages and codes printed on the console ([#53743](https://github.com/WordPress/gutenberg/pull/53743)). + ## 7.11.0 (2023-08-16) ## 7.10.0 (2023-08-10) diff --git a/packages/jest-console/src/matchers.js b/packages/jest-console/src/matchers.js index 078ef47fb1da55..9793164f532b32 100644 --- a/packages/jest-console/src/matchers.js +++ b/packages/jest-console/src/matchers.js @@ -8,58 +8,66 @@ import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; */ import supportedMatchers from './supported-matchers'; +const createErrorMessage = ( spyInfo ) => { + const { spy, pass, calls, matcherName, methodName, expected } = spyInfo; + const hint = pass ? `.not${ matcherName }` : matcherName; + const message = pass + ? `Expected mock function not to be called but it was called with:\n${ calls.map( + printReceived + ) }` + : `Expected mock function to be called${ + expected ? ` with:\n${ printExpected( expected ) }\n` : '.' + }\nbut it was called with:\n${ calls.map( printReceived ) }`; + + return () => + `${ matcherHint( hint, spy.getMockName() ) }` + + '\n\n' + + message + + '\n\n' + + `console.${ methodName }() should not be used unless explicitly expected\n` + + 'See https://www.npmjs.com/package/@wordpress/jest-console for details.'; +}; + +const createSpyInfo = ( spy, matcherName, methodName, expected ) => { + const calls = spy.mock.calls; + + const pass = expected + ? JSON.stringify( calls ).includes( JSON.stringify( expected ) ) + : calls.length > 0; + + const message = createErrorMessage( { + spy, + pass, + calls, + matcherName, + methodName, + expected, + } ); + + return { + pass, + message, + }; +}; + const createToHaveBeenCalledMatcher = ( matcherName, methodName ) => ( received ) => { const spy = received[ methodName ]; - const calls = spy.mock.calls; - const pass = calls.length > 0; - const message = pass - ? () => - matcherHint( `.not${ matcherName }`, spy.getMockName() ) + - '\n\n' + - 'Expected mock function not to be called but it was called with:\n' + - calls.map( printReceived ) - : () => - matcherHint( matcherName, spy.getMockName() ) + - '\n\n' + - 'Expected mock function to be called.'; + const spyInfo = createSpyInfo( spy, matcherName, methodName ); spy.assertionsNumber += 1; - return { - message, - pass, - }; + return spyInfo; }; const createToHaveBeenCalledWith = ( matcherName, methodName ) => function ( received, ...expected ) { const spy = received[ methodName ]; - const calls = spy.mock.calls; - const pass = calls.some( ( objects ) => - this.equals( objects, expected ) - ); - const message = pass - ? () => - matcherHint( `.not${ matcherName }`, spy.getMockName() ) + - '\n\n' + - 'Expected mock function not to be called with:\n' + - printExpected( expected ) - : () => - matcherHint( matcherName, spy.getMockName() ) + - '\n\n' + - 'Expected mock function to be called with:\n' + - printExpected( expected ) + - '\n' + - 'but it was called with:\n' + - calls.map( printReceived ); + const spyInfo = createSpyInfo( spy, matcherName, methodName, expected ); spy.assertionsNumber += 1; - return { - message, - pass, - }; + return spyInfo; }; expect.extend(