diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa3700e6255..3036b211ea18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,8 @@ ([#5879](https://github.com/facebook/jest/pull/5879)) * `[jest-cli]` Improve snapshot summaries ([#6181](https://github.com/facebook/jest/pull/6181)) +* `[expect]` Include custom mock names in error messages + ([#6199](https://github.com/facebook/jest/pull/6199)) ### Fixes diff --git a/packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap index 6499d917ff93..a1cedf0b33f2 100644 --- a/packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap @@ -1,5 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`lastCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.lastCalledWith(expected) + +Expected mock function \\"named-mock\\" to not have been last called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`lastCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].lastCalledWith() @@ -118,6 +125,14 @@ Expected mock function to have been last called with: Did not expect argument 2 but it was called with undefined." `; +exports[`lastReturnedWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).lastReturnedWith(expected) + +Expected mock function \\"named-mock\\" to have last returned: + \\"foo\\" +But it did not return" +`; + exports[`lastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].lastReturnedWith() @@ -206,6 +221,13 @@ But it last returned: \\"foo\\"" `; +exports[`nthCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.nthCalledWith(expected) + +Expected mock function \\"named-mock\\" first call to not have been called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`nthCalledWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`nthCalledWith should reject nth value smaller than 1 1`] = `"nth value 0 must be a positive integer greater than 0"`; @@ -333,6 +355,14 @@ Expected mock function first call to have been called with: Did not expect argument 2 but it was called with undefined." `; +exports[`nthReturnedWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).nthReturnedWith(expected) + +Expected mock function \\"named-mock\\" first call to have returned with: + \\"foo\\" +But it did not return" +`; + exports[`nthReturnedWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`nthReturnedWith should reject nth value smaller than 1 1`] = `"nth value 0 must be a positive integer greater than 0"`; @@ -474,6 +504,13 @@ Got: number: 555" `; +exports[`toBeCalled includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toBeCalled() + +Expected mock function \\"named-mock\\" not to be called but it was called with: + []" +`; + exports[`toBeCalled passes when called 1`] = ` "expect(jest.fn()).not.toBeCalled() @@ -549,6 +586,12 @@ exports[`toBeCalledTimes .not passes if function called more than expected times Expected mock function to have been called two times, but it was called three times." `; +exports[`toBeCalledTimes includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toBeCalledTimes(2) + +Expected mock function \\"named-mock\\" to have been called two times, but it was called one time." +`; + exports[`toBeCalledTimes only accepts a number argument 1`] = ` "expect(received)[.not].toBeCalledTimes(expected) @@ -611,6 +654,13 @@ Received: function: [Function fn]" `; +exports[`toBeCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toBeCalledWith(expected) + +Expected mock function \\"named-mock\\" not to have been called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`toBeCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toBeCalledWith() @@ -759,6 +809,13 @@ Got: number: 555" `; +exports[`toHaveBeenCalled includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toHaveBeenCalled() + +Expected mock function \\"named-mock\\" not to be called but it was called with: + []" +`; + exports[`toHaveBeenCalled passes when called 1`] = ` "expect(jest.fn()).not.toHaveBeenCalled() @@ -834,6 +891,12 @@ exports[`toHaveBeenCalledTimes .not passes if function called more than expected Expected mock function to have been called two times, but it was called three times." `; +exports[`toHaveBeenCalledTimes includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toHaveBeenCalledTimes(2) + +Expected mock function \\"named-mock\\" to have been called two times, but it was called one time." +`; + exports[`toHaveBeenCalledTimes only accepts a number argument 1`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) @@ -896,6 +959,13 @@ Received: function: [Function fn]" `; +exports[`toHaveBeenCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toHaveBeenCalledWith(expected) + +Expected mock function \\"named-mock\\" not to have been called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`toHaveBeenCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenCalledWith() @@ -1022,6 +1092,13 @@ Expected mock function to have been called with: Did not expect argument 2 but it was called with undefined." `; +exports[`toHaveBeenLastCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toHaveBeenLastCalledWith(expected) + +Expected mock function \\"named-mock\\" to not have been last called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`toHaveBeenLastCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenLastCalledWith() @@ -1140,6 +1217,13 @@ Expected mock function to have been last called with: Did not expect argument 2 but it was called with undefined." `; +exports[`toHaveBeenNthCalledWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toHaveBeenNthCalledWith(expected) + +Expected mock function \\"named-mock\\" first call to not have been called with: + [\\"foo\\", \\"bar\\"]" +`; + exports[`toHaveBeenNthCalledWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`toHaveBeenNthCalledWith should reject nth value smaller than 1 1`] = `"nth value 0 must be a positive integer greater than 0"`; @@ -1267,6 +1351,14 @@ Expected mock function first call to have been called with: Did not expect argument 2 but it was called with undefined." `; +exports[`toHaveLastReturnedWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toHaveLastReturnedWith(expected) + +Expected mock function \\"named-mock\\" to have last returned: + \\"foo\\" +But it did not return" +`; + exports[`toHaveLastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveLastReturnedWith() @@ -1355,6 +1447,14 @@ But it last returned: \\"foo\\"" `; +exports[`toHaveNthReturnedWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toHaveNthReturnedWith(expected) + +Expected mock function \\"named-mock\\" first call to have returned with: + \\"foo\\" +But it did not return" +`; + exports[`toHaveNthReturnedWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`toHaveNthReturnedWith should reject nth value smaller than 1 1`] = `"nth value 0 must be a positive integer greater than 0"`; @@ -1496,6 +1596,13 @@ Got: number: 555" `; +exports[`toHaveReturned includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toHaveReturned() + +Expected mock function \\"named-mock\\" not to have returned, but it returned: + 42" +`; + exports[`toHaveReturned passes when returned 1`] = ` "expect(jest.fn()).not.toHaveReturned() @@ -1571,6 +1678,12 @@ exports[`toHaveReturnedTimes .not passes if function returned more than expected Expected mock function to have returned two times, but it returned three times." `; +exports[`toHaveReturnedTimes includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toHaveReturnedTimes(1) + +Expected mock function \\"named-mock\\" to have returned one time, but it returned two times." +`; + exports[`toHaveReturnedTimes only accepts a number argument 1`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) @@ -1633,6 +1746,14 @@ Received: function: [Function fn]" `; +exports[`toHaveReturnedWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toHaveReturnedWith(expected) + +Expected mock function \\"named-mock\\" to have returned: + \\"foo\\" +But it did not return." +`; + exports[`toHaveReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveReturnedWith() @@ -1762,6 +1883,13 @@ Got: number: 555" `; +exports[`toReturn includes the custom mock name in the error message 1`] = ` +"expect(named-mock).not.toReturn() + +Expected mock function \\"named-mock\\" not to have returned, but it returned: + 42" +`; + exports[`toReturn passes when returned 1`] = ` "expect(jest.fn()).not.toReturn() @@ -1837,6 +1965,12 @@ exports[`toReturnTimes .not passes if function returned more than expected times Expected mock function to have returned two times, but it returned three times." `; +exports[`toReturnTimes includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toReturnTimes(1) + +Expected mock function \\"named-mock\\" to have returned one time, but it returned two times." +`; + exports[`toReturnTimes only accepts a number argument 1`] = ` "expect(received)[.not].toReturnTimes(expected) @@ -1899,6 +2033,14 @@ Received: function: [Function fn]" `; +exports[`toReturnWith includes the custom mock name in the error message 1`] = ` +"expect(named-mock).toReturnWith(expected) + +Expected mock function \\"named-mock\\" to have returned: + \\"foo\\" +But it did not return." +`; + exports[`toReturnWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toReturnWith() diff --git a/packages/expect/src/__tests__/spy_matchers.test.js b/packages/expect/src/__tests__/spy_matchers.test.js index 0230d5115a24..4df07681b37e 100644 --- a/packages/expect/src/__tests__/spy_matchers.test.js +++ b/packages/expect/src/__tests__/spy_matchers.test.js @@ -45,6 +45,14 @@ const jestExpect = require('../'); jestExpect(fn).not[called](555), ).toThrowErrorMatchingSnapshot(); }); + + test(`includes the custom mock name in the error message`, () => { + const fn = jest.fn().mockName('named-mock'); + + fn(); + jestExpect(fn)[called](); + expect(() => jestExpect(fn).not[called]()).toThrowErrorMatchingSnapshot(); + }); }); }); @@ -118,6 +126,15 @@ const jestExpect = require('../'); jestExpect(fn)[calledTimes](2), ).toThrowErrorMatchingSnapshot(); }); + + test('includes the custom mock name in the error message', () => { + const fn = jest.fn().mockName('named-mock'); + fn(); + + expect(() => + jestExpect(fn)[calledTimes](2), + ).toThrowErrorMatchingSnapshot(); + }); }); }); @@ -340,6 +357,17 @@ const jestExpect = require('../'); }).toThrowErrorMatchingSnapshot(); }); } + + test(`includes the custom mock name in the error message`, () => { + const fn = jest.fn().mockName('named-mock'); + fn('foo', 'bar'); + + caller(jestExpect(fn)[calledWith], 'foo', 'bar'); + + expect(() => + caller(jestExpect(fn).not[calledWith], 'foo', 'bar'), + ).toThrowErrorMatchingSnapshot(); + }); }); }); @@ -383,6 +411,15 @@ const jestExpect = require('../'); jestExpect(fn).not[returned](555), ).toThrowErrorMatchingSnapshot(); }); + + test(`includes the custom mock name in the error message`, () => { + const fn = jest.fn(() => 42).mockName('named-mock'); + fn(); + jestExpect(fn)[returned](); + expect(() => + jestExpect(fn).not[returned](), + ).toThrowErrorMatchingSnapshot(); + }); }); }); @@ -456,6 +493,18 @@ const jestExpect = require('../'); jestExpect(fn)[returnedTimes](2), ).toThrowErrorMatchingSnapshot(); }); + + test('includes the custom mock name in the error message', () => { + const fn = jest.fn(() => 42).mockName('named-mock'); + fn(); + fn(); + + jestExpect(fn)[returnedTimes](2); + + expect(() => + jestExpect(fn)[returnedTimes](1), + ).toThrowErrorMatchingSnapshot(); + }); }); }); @@ -674,5 +723,14 @@ const jestExpect = require('../'); }).toThrowErrorMatchingSnapshot(); }); } + + test(`includes the custom mock name in the error message`, () => { + const fn = jest.fn().mockName('named-mock'); + caller(jestExpect(fn).not[returnedWith], 'foo'); + + expect(() => + caller(jestExpect(fn)[returnedWith], 'foo'), + ).toThrowErrorMatchingSnapshot(); + }); }); }); diff --git a/packages/expect/src/spy_matchers.js b/packages/expect/src/spy_matchers.js index 3a430b7aaa39..82d567f15937 100644 --- a/packages/expect/src/spy_matchers.js +++ b/packages/expect/src/spy_matchers.js @@ -34,6 +34,10 @@ const createToBeCalledMatcher = matcherName => (received, expected) => { const receivedIsSpy = isSpy(received); const type = receivedIsSpy ? 'spy' : 'mock function'; const receivedName = receivedIsSpy ? 'spy' : received.getMockName(); + const identifier = + receivedIsSpy || receivedName === 'jest.fn()' + ? type + : `${type} "${receivedName}"`; const count = receivedIsSpy ? received.calls.count() : received.mock.calls.length; @@ -45,12 +49,12 @@ const createToBeCalledMatcher = matcherName => (received, expected) => { ? () => matcherHint('.not' + matcherName, receivedName, '') + '\n\n' + - `Expected ${type} not to be called ` + + `Expected ${identifier} not to be called ` + formatReceivedCalls(calls, CALL_PRINT_LIMIT, {sameSentence: true}) : () => matcherHint(matcherName, receivedName, '') + '\n\n' + - `Expected ${type} to have been called, but it was not called.`; + `Expected ${identifier} to have been called, but it was not called.`; return {message, pass}; }; @@ -59,6 +63,12 @@ const createToReturnMatcher = matcherName => (received, expected) => { ensureNoExpected(expected, matcherName); ensureMock(received, matcherName); + const receivedName = received.getMockName(); + const identifier = + receivedName === 'jest.fn()' + ? 'mock function' + : `mock function "${receivedName}"`; + const returnValues = received.mock.returnValues; const count = returnValues.length; const pass = count > 0; @@ -67,12 +77,12 @@ const createToReturnMatcher = matcherName => (received, expected) => { ? () => matcherHint('.not' + matcherName, received.getMockName(), '') + '\n\n' + - `Expected mock function not to have returned, but it returned:\n` + + `Expected ${identifier} not to have returned, but it returned:\n` + ` ${getPrintedReturnValues(returnValues, RETURN_PRINT_LIMIT)}` : () => matcherHint(matcherName, received.getMockName(), '') + '\n\n' + - `Expected mock function to have returned.`; + `Expected ${identifier} to have returned.`; return {message, pass}; }; @@ -87,6 +97,10 @@ const createToBeCalledTimesMatcher = (matcherName: string) => ( const receivedIsSpy = isSpy(received); const type = receivedIsSpy ? 'spy' : 'mock function'; const receivedName = receivedIsSpy ? 'spy' : received.getMockName(); + const identifier = + receivedIsSpy || receivedName === 'jest.fn()' + ? type + : `${type} "${receivedName}"`; const count = receivedIsSpy ? received.calls.count() : received.mock.calls.length; @@ -95,13 +109,13 @@ const createToBeCalledTimesMatcher = (matcherName: string) => ( ? () => matcherHint('.not' + matcherName, receivedName, String(expected)) + `\n\n` + - `Expected ${type} not to be called ` + + `Expected ${identifier} not to be called ` + `${EXPECTED_COLOR(pluralize('time', expected))}, but it was` + ` called exactly ${RECEIVED_COLOR(pluralize('time', count))}.` : () => matcherHint(matcherName, receivedName, String(expected)) + '\n\n' + - `Expected ${type} to have been called ` + + `Expected ${identifier} to have been called ` + `${EXPECTED_COLOR(pluralize('time', expected))},` + ` but it was called ${RECEIVED_COLOR(pluralize('time', count))}.`; @@ -115,6 +129,12 @@ const createToReturnTimesMatcher = (matcherName: string) => ( ensureExpectedIsNumber(expected, matcherName); ensureMock(received, matcherName); + const receivedName = received.getMockName(); + const identifier = + receivedName === 'jest.fn()' + ? 'mock function' + : `mock function "${receivedName}"`; + const count = received.mock.returnValues.length; const pass = count === expected; @@ -126,13 +146,13 @@ const createToReturnTimesMatcher = (matcherName: string) => ( String(expected), ) + `\n\n` + - `Expected mock function not to have returned ` + + `Expected ${identifier} not to have returned ` + `${EXPECTED_COLOR(pluralize('time', expected))}, but it` + ` returned exactly ${RECEIVED_COLOR(pluralize('time', count))}.` : () => matcherHint(matcherName, received.getMockName(), String(expected)) + '\n\n' + - `Expected mock function to have returned ` + + `Expected ${identifier} to have returned ` + `${EXPECTED_COLOR(pluralize('time', expected))},` + ` but it returned ${RECEIVED_COLOR(pluralize('time', count))}.`; @@ -148,6 +168,11 @@ const createToBeCalledWithMatcher = matcherName => ( const receivedIsSpy = isSpy(received); const type = receivedIsSpy ? 'spy' : 'mock function'; const receivedName = receivedIsSpy ? 'spy' : received.getMockName(); + const identifier = + receivedIsSpy || receivedName === 'jest.fn()' + ? type + : `${type} "${receivedName}"`; + const calls = receivedIsSpy ? received.calls.all().map(x => x.args) : received.mock.calls; @@ -161,12 +186,12 @@ const createToBeCalledWithMatcher = matcherName => ( ? () => matcherHint('.not' + matcherName, receivedName) + '\n\n' + - `Expected ${type} not to have been called with:\n` + + `Expected ${identifier} not to have been called with:\n` + ` ${printExpected(expected)}` : () => matcherHint(matcherName, receivedName) + '\n\n' + - `Expected ${type} to have been called with:\n` + + `Expected ${identifier} to have been called with:\n` + formatMismatchedCalls(fail, expected, CALL_PRINT_LIMIT); return {message, pass}; @@ -178,6 +203,12 @@ const createToReturnWithMatcher = matcherName => ( ) => { ensureMock(received, matcherName); + const receivedName = received.getMockName(); + const identifier = + receivedName === 'jest.fn()' + ? 'mock function' + : `mock function "${receivedName}"`; + const returnValues = received.mock.returnValues; const [match] = partition(returnValues, value => equals(expected, value, [iterableEquality]), @@ -188,14 +219,14 @@ const createToReturnWithMatcher = matcherName => ( ? () => matcherHint('.not' + matcherName, received.getMockName()) + '\n\n' + - `Expected mock function not to have returned:\n` + + `Expected ${identifier} not to have returned:\n` + ` ${printExpected(expected)}\n` + `But it returned exactly:\n` + ` ${printReceived(expected)}` : () => matcherHint(matcherName, received.getMockName()) + '\n\n' + - `Expected mock function to have returned:\n` + + `Expected ${identifier} to have returned:\n` + formatMismatchedReturnValues( returnValues, expected, @@ -214,6 +245,10 @@ const createLastCalledWithMatcher = matcherName => ( const receivedIsSpy = isSpy(received); const type = receivedIsSpy ? 'spy' : 'mock function'; const receivedName = receivedIsSpy ? 'spy' : received.getMockName(); + const identifier = + receivedIsSpy || receivedName === 'jest.fn()' + ? type + : `${type} "${receivedName}"`; const calls = receivedIsSpy ? received.calls.all().map(x => x.args) : received.mock.calls; @@ -223,12 +258,12 @@ const createLastCalledWithMatcher = matcherName => ( ? () => matcherHint('.not' + matcherName, receivedName) + '\n\n' + - `Expected ${type} to not have been last called with:\n` + + `Expected ${identifier} to not have been last called with:\n` + ` ${printExpected(expected)}` : () => matcherHint(matcherName, receivedName) + '\n\n' + - `Expected ${type} to have been last called with:\n` + + `Expected ${identifier} to have been last called with:\n` + formatMismatchedCalls(calls, expected, LAST_CALL_PRINT_LIMIT); return {message, pass}; @@ -240,6 +275,12 @@ const createLastReturnedMatcher = matcherName => ( ) => { ensureMock(received, matcherName); + const receivedName = received.getMockName(); + const identifier = + receivedName === 'jest.fn()' + ? 'mock function' + : `mock function "${receivedName}"`; + const returnValues = received.mock.returnValues; const lastReturnValue = returnValues[returnValues.length - 1]; const pass = equals(lastReturnValue, expected, [iterableEquality]); @@ -248,14 +289,14 @@ const createLastReturnedMatcher = matcherName => ( ? () => matcherHint('.not' + matcherName, received.getMockName()) + '\n\n' + - 'Expected mock function to not have last returned:\n' + + `Expected ${identifier} to not have last returned:\n` + ` ${printExpected(expected)}\n` + `But it last returned exactly:\n` + ` ${printReceived(lastReturnValue)}` : () => matcherHint(matcherName, received.getMockName()) + '\n\n' + - 'Expected mock function to have last returned:\n' + + `Expected ${identifier} to have last returned:\n` + ` ${printExpected(expected)}\n` + (returnValues.length > 0 ? `But it last returned:\n ${printReceived(lastReturnValue)}` @@ -284,6 +325,10 @@ const createNthCalledWithMatcher = (matcherName: string) => ( } const receivedName = receivedIsSpy ? 'spy' : received.getMockName(); + const identifier = + receivedIsSpy || receivedName === 'jest.fn()' + ? type + : `${type} "${receivedName}"`; const calls = receivedIsSpy ? received.calls.all().map(x => x.args) : received.mock.calls; @@ -293,14 +338,14 @@ const createNthCalledWithMatcher = (matcherName: string) => ( ? () => matcherHint('.not' + matcherName, receivedName) + '\n\n' + - `Expected ${type} ${nthToString( + `Expected ${identifier} ${nthToString( nth, )} call to not have been called with:\n` + ` ${printExpected(expected)}` : () => matcherHint(matcherName, receivedName) + '\n\n' + - `Expected ${type} ${nthToString( + `Expected ${identifier} ${nthToString( nth, )} call to have been called with:\n` + formatMismatchedCalls(calls, expected, LAST_CALL_PRINT_LIMIT); @@ -324,6 +369,12 @@ const createNthReturnedWithMatcher = (matcherName: string) => ( return {message, pass}; } + const receivedName = received.getMockName(); + const identifier = + receivedName === 'jest.fn()' + ? 'mock function' + : `mock function "${receivedName}"`; + const returnValues = received.mock.returnValues; const nthValue = returnValues[nth - 1]; const pass = equals(nthValue, expected, [iterableEquality]); @@ -332,14 +383,14 @@ const createNthReturnedWithMatcher = (matcherName: string) => ( ? () => matcherHint('.not' + matcherName, received.getMockName()) + '\n\n' + - `Expected mock function ${nthString} call to not have returned with:\n` + + `Expected ${identifier} ${nthString} call to not have returned with:\n` + ` ${printExpected(expected)}\n` + `But the ${nthString} call returned exactly:\n` + ` ${printReceived(nthValue)}` : () => matcherHint(matcherName, received.getMockName()) + '\n\n' + - `Expected mock function ${nthString} call to have returned with:\n` + + `Expected ${identifier} ${nthString} call to have returned with:\n` + ` ${printExpected(expected)}\n` + (returnValues.length > 0 ? `But the ${nthString} call returned with:\n ${printReceived(