From 80231ee2e540c558994852ce915886e8b57310e9 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Tue, 18 Dec 2018 17:18:51 -0500 Subject: [PATCH] expect: Improve report when assertion fails, part 4 (#7241) * expect: Improve report when assertion fails, part 4 * Added snapshot test for toHaveLength expected length * Fix prettier lint error * Made improvements requested by thymikee * Make improvements suggested by SimenB * Update CHANGELOG.md * Save the change to resolve the other merge conflict * Deleted assertion_counts.test.js.snap * Replace cannot with must not * Fix prettier lint error --- CHANGELOG.md | 3 +- .../assertionCounts.test.js.snap | 10 + .../__snapshots__/matchers.test.js.snap | 455 ++++++++------- .../__snapshots__/spyMatchers.test.js.snap | 532 ++++++++++-------- .../toThrowMatchers.test.js.snap | 34 +- .../src/__tests__/assertionCounts.test.js | 4 +- .../expect/src/__tests__/matchers.test.js | 6 + packages/expect/src/index.js | 18 +- packages/expect/src/matchers.js | 137 +++-- packages/expect/src/spyMatchers.js | 9 +- packages/expect/src/toThrowMatchers.js | 26 +- .../__snapshots__/index.test.js.snap | 36 ++ .../src/__tests__/index.test.js | 14 +- packages/jest-matcher-utils/src/index.js | 51 +- 14 files changed, 793 insertions(+), 542 deletions(-) create mode 100644 packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index b68d3035d094..9bbac89d0cb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,8 @@ - `[jest-haste-map]` Add `getCacheFilePath` to get the path to the cache file for a `HasteMap` instance ([#7217](https://github.com/facebook/jest/pull/7217)) - `[jest-runtime]` Remove `cacheDirectory` from `ignorePattern` for `HasteMap` if not necessary ([#7166](https://github.com/facebook/jest/pull/7166)) - `[jest-validate]` Add syntax to validate multiple permitted types ([#7207](https://github.com/facebook/jest/pull/7207)) -- `[jest-config]` Accept an array as as well as a string for `testRegex` ([#7209](https://github.com/facebook/jest/pull/7209)) +- `[jest-config]` Accept an array as as well as a string for `testRegex`([#7209]https://github.com/facebook/jest/pull/7209)) +- `[expect/jest-matcher-utils]` Improve report when assertion fails, part 4 ([#7241](https://github.com/facebook/jest/pull/7241)) - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) - `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313), [#7349](https://github.com/facebook/jest/pull/7349), [#7350](https://github.com/facebook/jest/pull/7350)) diff --git a/packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap b/packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap new file mode 100644 index 000000000000..c7474a6ec766 --- /dev/null +++ b/packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.hasAssertions() throws if expected is not undefined 1`] = ` +"expect(received)[.not].hasAssertions() + +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 2" +`; diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index ad52eb43b2e1..f1503dbd4ff4 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -10,63 +10,71 @@ Expected received Promise to reject, instead it resolved to value exports[`.rejects fails non-promise value "a" 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - string: \\"a\\"" +Matcher error: received value must be a Promise + +Received has type: string +Received has value: \\"a\\"" `; exports[`.rejects fails non-promise value [1] 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - array: [1]" +Matcher error: received value must be a Promise + +Received has type: array +Received has value: [1]" `; exports[`.rejects fails non-promise value [Function anonymous] 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - function: [Function anonymous]" +Matcher error: received value must be a Promise + +Received has type: function +Received has value: [Function anonymous]" `; exports[`.rejects fails non-promise value {"a": 1} 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - object: {\\"a\\": 1}" +Matcher error: received value must be a Promise + +Received has type: object +Received has value: {\\"a\\": 1}" `; exports[`.rejects fails non-promise value 4 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - number: 4" +Matcher error: received value must be a Promise + +Received has type: number +Received has value: 4" `; exports[`.rejects fails non-promise value null 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: null" +Matcher error: received value must be a Promise + +Received has value: null" `; exports[`.rejects fails non-promise value true 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: - boolean: true" +Matcher error: received value must be a Promise + +Received has type: boolean +Received has value: true" `; exports[`.rejects fails non-promise value undefined 1`] = ` "expect(received).rejects.toBeDefined() -received value must be a Promise. -Received: undefined" +Matcher error: received value must be a Promise + +Received has value: undefined" `; exports[`.resolves fails for promise that rejects 1`] = ` @@ -79,125 +87,141 @@ Expected received Promise to resolve, instead it rejected to value exports[`.resolves fails non-promise value "a" 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - string: \\"a\\"" +Matcher error: received value must be a Promise + +Received has type: string +Received has value: \\"a\\"" `; exports[`.resolves fails non-promise value "a" synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - string: \\"a\\"" +Matcher error: received value must be a Promise + +Received has type: string +Received has value: \\"a\\"" `; exports[`.resolves fails non-promise value [1] 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - array: [1]" +Matcher error: received value must be a Promise + +Received has type: array +Received has value: [1]" `; exports[`.resolves fails non-promise value [1] synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - array: [1]" +Matcher error: received value must be a Promise + +Received has type: array +Received has value: [1]" `; exports[`.resolves fails non-promise value [Function anonymous] 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - function: [Function anonymous]" +Matcher error: received value must be a Promise + +Received has type: function +Received has value: [Function anonymous]" `; exports[`.resolves fails non-promise value [Function anonymous] synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - function: [Function anonymous]" +Matcher error: received value must be a Promise + +Received has type: function +Received has value: [Function anonymous]" `; exports[`.resolves fails non-promise value {"a": 1} 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - object: {\\"a\\": 1}" +Matcher error: received value must be a Promise + +Received has type: object +Received has value: {\\"a\\": 1}" `; exports[`.resolves fails non-promise value {"a": 1} synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - object: {\\"a\\": 1}" +Matcher error: received value must be a Promise + +Received has type: object +Received has value: {\\"a\\": 1}" `; exports[`.resolves fails non-promise value 4 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - number: 4" +Matcher error: received value must be a Promise + +Received has type: number +Received has value: 4" `; exports[`.resolves fails non-promise value 4 synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - number: 4" +Matcher error: received value must be a Promise + +Received has type: number +Received has value: 4" `; exports[`.resolves fails non-promise value null 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: null" +Matcher error: received value must be a Promise + +Received has value: null" `; exports[`.resolves fails non-promise value null synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: null" +Matcher error: received value must be a Promise + +Received has value: null" `; exports[`.resolves fails non-promise value true 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - boolean: true" +Matcher error: received value must be a Promise + +Received has type: boolean +Received has value: true" `; exports[`.resolves fails non-promise value true synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: - boolean: true" +Matcher error: received value must be a Promise + +Received has type: boolean +Received has value: true" `; exports[`.resolves fails non-promise value undefined 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: undefined" +Matcher error: received value must be a Promise + +Received has value: undefined" `; exports[`.resolves fails non-promise value undefined synchronously 1`] = ` "expect(received).resolves.toBeDefined() -received value must be a Promise. -Received: undefined" +Matcher error: received value must be a Promise + +Received has value: undefined" `; exports[`.toBe() does not crash on circular references 1`] = ` @@ -1164,10 +1188,12 @@ Received value: Map {}" `; exports[`.toBeInstanceOf() throws if constructor is not a function 1`] = ` -"expect(value).toBeInstanceOf(constructor) +"expect(received).toBeInstanceOf(expected) + +Matcher error: expected value must be a function -Expected constructor to be a function. Instead got: - \\"number\\"" +Expected has type: number +Expected has value: 4" `; exports[`.toBeNaN() {pass: true} expect(NaN).toBeNaN() 1`] = ` @@ -1497,15 +1523,17 @@ Received: undefined" exports[`.toBeTruthy(), .toBeFalsy() does not accept arguments 1`] = ` "expect(received)[.not].toBeTruthy() -Matcher does not accept any arguments. -Got: null" +Matcher error: expected value must be omitted or undefined + +Expected has value: null" `; exports[`.toBeTruthy(), .toBeFalsy() does not accept arguments 2`] = ` "expect(received)[.not].toBeFalsy() -Matcher does not accept any arguments. -Got: null" +Matcher error: expected value must be omitted or undefined + +Expected has value: null" `; exports[`.toContain(), .toContainEqual() '"11112111"' contains '"2"' 1`] = ` @@ -1728,17 +1756,19 @@ Not to contain a value equal to: `; exports[`.toContain(), .toContainEqual() error cases 1`] = ` -"expect(collection)[.not].toContainEqual(value) +"expect(received).toContain(expected) -Expected collection to be an array-like structure. -Received: null" +Matcher error: received value must not be null nor undefined + +Received has value: null" `; exports[`.toContain(), .toContainEqual() error cases for toContainEqual 1`] = ` -"expect(collection)[.not].toContainEqual(value) +"expect(received).toContainEqual(expected) -Expected collection to be an array-like structure. -Received: null" +Matcher error: received value must not be null nor undefined + +Received has value: null" `; exports[`.toEqual() {pass: false} expect("Alice").not.toEqual({"asymmetricMatch": [Function asymmetricMatch]}) 1`] = ` @@ -2890,63 +2920,79 @@ received.length: `; exports[`.toHaveLength error cases 1`] = ` -"expect(received)[.not].toHaveLength(length) +"expect(received).toHaveLength(expected) -Expected value to have a 'length' property that is a number. Received: - {\\"a\\": 9} -received.length: - undefined" +Matcher error: received value must have a length property whose value must be a number + +Received has type: object +Received has value: {\\"a\\": 9}" `; exports[`.toHaveLength error cases 2`] = ` -"expect(received)[.not].toHaveLength(length) +"expect(received).toHaveLength(expected) -Expected value to have a 'length' property that is a number. Received: - 0 -" +Matcher error: received value must have a length property whose value must be a number + +Received has type: number +Received has value: 0" `; exports[`.toHaveLength error cases 3`] = ` -"expect(received)[.not].toHaveLength(length) +"expect(received).toHaveLength(expected) -Expected value to have a 'length' property that is a number. Received: - undefined -" +Matcher error: received value must have a length property whose value must be a number + +Received has value: undefined" +`; + +exports[`.toHaveLength matcher error expected length 1`] = ` +"expect(received).toHaveLength(expected) + +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"3\\"" `; exports[`.toHaveProperty() {error} expect({"a": {"b": {}}}).toHaveProperty('1') 1`] = ` -"expect(object)[.not].toHaveProperty(path) +"expect(received).toHaveProperty(path) -Expected path to be a string or an array. Received: - number: 1" +Matcher error: expected path must be a string or array + +Expected has type: number +Expected has value: 1" `; exports[`.toHaveProperty() {error} expect({"a": {"b": {}}}).toHaveProperty('null') 1`] = ` -"expect(object)[.not].toHaveProperty(path) +"expect(received).toHaveProperty(path) + +Matcher error: expected path must be a string or array -Expected path to be a string or an array. Received: - null: null" +Expected has value: null" `; exports[`.toHaveProperty() {error} expect({"a": {"b": {}}}).toHaveProperty('undefined') 1`] = ` -"expect(object)[.not].toHaveProperty(path) +"expect(received).toHaveProperty(path) -Expected path to be a string or an array. Received: - undefined: undefined" +Matcher error: expected path must be a string or array + +Expected has value: undefined" `; exports[`.toHaveProperty() {error} expect(null).toHaveProperty('a.b') 1`] = ` -"expect(object)[.not].toHaveProperty(path) +"expect(received).toHaveProperty(path) + +Matcher error: received value must not be null nor undefined -Expected object to be an object. Received: - null: null" +Received has value: null" `; exports[`.toHaveProperty() {error} expect(undefined).toHaveProperty('a') 1`] = ` -"expect(object)[.not].toHaveProperty(path) +"expect(received).toHaveProperty(path) -Expected object to be an object. Received: - undefined: undefined" +Matcher error: received value must not be null nor undefined + +Received has value: undefined" `; exports[`.toHaveProperty() {pass: false} expect("abc").toHaveProperty('a.b.c') 1`] = ` @@ -3400,105 +3446,118 @@ Received: `; exports[`.toMatch() throws if non String actual value passed: [/foo/i, "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - regexp: /foo/i" +Matcher error: received value must be a string + +Received has type: regexp +Received has value: /foo/i" `; exports[`.toMatch() throws if non String actual value passed: [[], "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - array: []" +Matcher error: received value must be a string + +Received has type: array +Received has value: []" `; exports[`.toMatch() throws if non String actual value passed: [[Function anonymous], "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - function: [Function anonymous]" +Matcher error: received value must be a string + +Received has type: function +Received has value: [Function anonymous]" `; exports[`.toMatch() throws if non String actual value passed: [{}, "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - object: {}" +Matcher error: received value must be a string + +Received has type: object +Received has value: {}" `; exports[`.toMatch() throws if non String actual value passed: [1, "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - number: 1" +Matcher error: received value must be a string + +Received has type: number +Received has value: 1" `; exports[`.toMatch() throws if non String actual value passed: [true, "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: - boolean: true" +Matcher error: received value must be a string + +Received has type: boolean +Received has value: true" `; exports[`.toMatch() throws if non String actual value passed: [undefined, "foo"] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -string value must be a string. -Received: undefined" +Matcher error: received value must be a string + +Received has value: undefined" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", []] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) + +Matcher error: expected value must be a string or regular expression -expected value must be a string or a regular expression. -Expected: - array: []" +Expected has type: array +Expected has value: []" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", [Function anonymous]] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) + +Matcher error: expected value must be a string or regular expression -expected value must be a string or a regular expression. -Expected: - function: [Function anonymous]" +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", {}] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) + +Matcher error: expected value must be a string or regular expression -expected value must be a string or a regular expression. -Expected: - object: {}" +Expected has type: object +Expected has value: {}" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", 1] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -expected value must be a string or a regular expression. -Expected: - number: 1" +Matcher error: expected value must be a string or regular expression + +Expected has type: number +Expected has value: 1" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", true] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -expected value must be a string or a regular expression. -Expected: - boolean: true" +Matcher error: expected value must be a string or regular expression + +Expected has type: boolean +Expected has value: true" `; exports[`.toMatch() throws if non String/RegExp expected value passed: ["foo", undefined] 1`] = ` -"expect(string)[.not].toMatch(expected) +"expect(received).toMatch(expected) -expected value must be a string or a regular expression. -Expected: undefined" +Matcher error: expected value must be a string or regular expression + +Expected has value: undefined" `; exports[`.toMatch() throws: [bar, /foo/] 1`] = ` @@ -4210,77 +4269,87 @@ Received: `; exports[`toMatchObject() throws expect("44").toMatchObject({}) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) -received value must be an object. -Received: - string: \\"44\\"" +Matcher error: received value must be a non-null object + +Received has type: string +Received has value: \\"44\\"" `; exports[`toMatchObject() throws expect({}).toMatchObject("some string") 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) + +Matcher error: expected value must be a non-null object -expected value must be an object. -Expected: - string: \\"some string\\"" +Expected has type: string +Expected has value: \\"some string\\"" `; exports[`toMatchObject() throws expect({}).toMatchObject(4) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) + +Matcher error: expected value must be a non-null object -expected value must be an object. -Expected: - number: 4" +Expected has type: number +Expected has value: 4" `; exports[`toMatchObject() throws expect({}).toMatchObject(null) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) + +Matcher error: expected value must be a non-null object -expected value must be an object. -Expected: null" +Expected has value: null" `; exports[`toMatchObject() throws expect({}).toMatchObject(true) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) + +Matcher error: expected value must be a non-null object -expected value must be an object. -Expected: - boolean: true" +Expected has type: boolean +Expected has value: true" `; exports[`toMatchObject() throws expect({}).toMatchObject(undefined) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) + +Matcher error: expected value must be a non-null object -expected value must be an object. -Expected: undefined" +Expected has value: undefined" `; exports[`toMatchObject() throws expect(4).toMatchObject({}) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) -received value must be an object. -Received: - number: 4" +Matcher error: received value must be a non-null object + +Received has type: number +Received has value: 4" `; exports[`toMatchObject() throws expect(null).toMatchObject({}) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) -received value must be an object. -Received: null" +Matcher error: received value must be a non-null object + +Received has value: null" `; exports[`toMatchObject() throws expect(true).toMatchObject({}) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) -received value must be an object. -Received: - boolean: true" +Matcher error: received value must be a non-null object + +Received has type: boolean +Received has value: true" `; exports[`toMatchObject() throws expect(undefined).toMatchObject({}) 1`] = ` -"expect(object)[.not].toMatchObject(expected) +"expect(received).toMatchObject(expected) -received value must be an object. -Received: undefined" +Matcher error: received value must be a non-null object + +Received has value: undefined" `; diff --git a/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap index 220a4e47e8de..6a64d8650306 100644 --- a/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap @@ -10,9 +10,10 @@ Expected mock function \\"named-mock\\" to not have been last called with: exports[`lastCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].lastCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`lastCalledWith works when not called 1`] = ` @@ -160,9 +161,10 @@ But the last call has not returned yet" exports[`lastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].lastReturnedWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`lastReturnedWith works when not called 1`] = ` @@ -293,9 +295,10 @@ Expected mock function first call to not have been called with: exports[`nthCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].nthCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`nthCalledWith works when not called 1`] = ` @@ -490,9 +493,10 @@ But the first call returned exactly: exports[`nthReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].nthReturnedWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`nthReturnedWith works when not called 1`] = ` @@ -596,9 +600,10 @@ But the first call returned exactly: exports[`toBeCalled .not fails with any argument passed 1`] = ` "expect(received)[.not].toBeCalled() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toBeCalled .not passes when called 1`] = ` @@ -610,9 +615,10 @@ Expected mock function to have been called, but it was not called." exports[`toBeCalled fails with any argument passed 1`] = ` "expect(received)[.not].toBeCalled() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toBeCalled includes the custom mock name in the error message 1`] = ` @@ -632,57 +638,64 @@ Expected mock function not to be called but it was called with: exports[`toBeCalled works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toBeCalled() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toBeCalledTimes .not only accepts a number argument 1`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toBeCalledTimes .not only accepts a number argument 2`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toBeCalledTimes .not only accepts a number argument 3`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toBeCalledTimes .not only accepts a number argument 4`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toBeCalledTimes .not only accepts a number argument 5`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toBeCalledTimes .not only accepts a number argument 6`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toBeCalledTimes .not passes if function called less than expected times 1`] = ` @@ -706,49 +719,55 @@ Expected mock function \\"named-mock\\" to have been called two times, exports[`toBeCalledTimes only accepts a number argument 1`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toBeCalledTimes only accepts a number argument 2`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toBeCalledTimes only accepts a number argument 3`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toBeCalledTimes only accepts a number argument 4`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toBeCalledTimes only accepts a number argument 5`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toBeCalledTimes only accepts a number argument 6`] = ` "expect(received)[.not].toBeCalledTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toBeCalledTimes passes if function called equal to expected times 1`] = ` @@ -760,9 +779,10 @@ Expected mock function not to be called two times, but it was called e exports[`toBeCalledTimes works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toBeCalledTimes() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toBeCalledWith includes the custom mock name in the error message 1`] = ` @@ -775,9 +795,10 @@ Expected mock function \\"named-mock\\" not to have been called with: exports[`toBeCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toBeCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toBeCalledWith works when not called 1`] = ` @@ -901,9 +922,10 @@ Expected mock function to have been called with: exports[`toHaveBeenCalled .not fails with any argument passed 1`] = ` "expect(received)[.not].toHaveBeenCalled() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toHaveBeenCalled .not passes when called 1`] = ` @@ -915,9 +937,10 @@ Expected mock function to have been called, but it was not called." exports[`toHaveBeenCalled fails with any argument passed 1`] = ` "expect(received)[.not].toHaveBeenCalled() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toHaveBeenCalled includes the custom mock name in the error message 1`] = ` @@ -937,57 +960,64 @@ Expected mock function not to be called but it was called with: exports[`toHaveBeenCalled works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenCalled() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 1`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 2`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 3`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 4`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 5`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toHaveBeenCalledTimes .not only accepts a number argument 6`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toHaveBeenCalledTimes .not passes if function called less than expected times 1`] = ` @@ -1011,49 +1041,55 @@ Expected mock function \\"named-mock\\" to have been called two times, exports[`toHaveBeenCalledTimes only accepts a number argument 1`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toHaveBeenCalledTimes only accepts a number argument 2`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toHaveBeenCalledTimes only accepts a number argument 3`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toHaveBeenCalledTimes only accepts a number argument 4`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toHaveBeenCalledTimes only accepts a number argument 5`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toHaveBeenCalledTimes only accepts a number argument 6`] = ` "expect(received)[.not].toHaveBeenCalledTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toHaveBeenCalledTimes passes if function called equal to expected times 1`] = ` @@ -1065,9 +1101,10 @@ Expected mock function not to be called two times, but it was called e exports[`toHaveBeenCalledTimes works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenCalledTimes() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveBeenCalledWith includes the custom mock name in the error message 1`] = ` @@ -1080,9 +1117,10 @@ Expected mock function \\"named-mock\\" not to have been called with: exports[`toHaveBeenCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveBeenCalledWith works when not called 1`] = ` @@ -1213,9 +1251,10 @@ Expected mock function \\"named-mock\\" to not have been last called with: exports[`toHaveBeenLastCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenLastCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveBeenLastCalledWith works when not called 1`] = ` @@ -1358,9 +1397,10 @@ Expected mock function first call to not have been called with: exports[`toHaveBeenNthCalledWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveBeenNthCalledWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveBeenNthCalledWith works when not called 1`] = ` @@ -1499,9 +1539,10 @@ But the last call has not returned yet" exports[`toHaveLastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveLastReturnedWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveLastReturnedWith works when not called 1`] = ` @@ -1693,9 +1734,10 @@ But the first call returned exactly: exports[`toHaveNthReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveNthReturnedWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveNthReturnedWith works when not called 1`] = ` @@ -1799,9 +1841,10 @@ But the first call returned exactly: exports[`toHaveReturned .not fails with any argument passed 1`] = ` "expect(received)[.not].toHaveReturned() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toHaveReturned .not passes when a call throws undefined 1`] = ` @@ -1825,9 +1868,10 @@ Expected mock function to have returned." exports[`toHaveReturned fails with any argument passed 1`] = ` "expect(received)[.not].toHaveReturned() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toHaveReturned includes the custom mock name in the error message 1`] = ` @@ -1869,57 +1913,64 @@ Expected mock function not to have returned, but it returned: exports[`toHaveReturned works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveReturned() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveReturnedTimes .not only accepts a number argument 1`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toHaveReturnedTimes .not only accepts a number argument 2`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toHaveReturnedTimes .not only accepts a number argument 3`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toHaveReturnedTimes .not only accepts a number argument 4`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toHaveReturnedTimes .not only accepts a number argument 5`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toHaveReturnedTimes .not only accepts a number argument 6`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toHaveReturnedTimes .not passes if function called less than expected times 1`] = ` @@ -1967,49 +2018,55 @@ Expected mock function not to have returned two times, but it returned exports[`toHaveReturnedTimes only accepts a number argument 1`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toHaveReturnedTimes only accepts a number argument 2`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toHaveReturnedTimes only accepts a number argument 3`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toHaveReturnedTimes only accepts a number argument 4`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toHaveReturnedTimes only accepts a number argument 5`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toHaveReturnedTimes only accepts a number argument 6`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toHaveReturnedTimes passes if function returned equal to expected times 1`] = ` @@ -2021,9 +2078,10 @@ Expected mock function not to have returned two times, but it returned exports[`toHaveReturnedTimes works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveReturnedTimes() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveReturnedWith a call that throws is not considered to have returned 1`] = ` @@ -2061,9 +2119,10 @@ But it did not return." exports[`toHaveReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveReturnedWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toHaveReturnedWith works when not called 1`] = ` @@ -2177,9 +2236,10 @@ But it returned exactly: exports[`toReturn .not fails with any argument passed 1`] = ` "expect(received)[.not].toReturn() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toReturn .not passes when a call throws undefined 1`] = ` @@ -2203,9 +2263,10 @@ Expected mock function to have returned." exports[`toReturn fails with any argument passed 1`] = ` "expect(received)[.not].toReturn() -Matcher does not accept any arguments. -Got: - number: 555" +Matcher error: expected value must be omitted or undefined + +Expected has type: number +Expected has value: 555" `; exports[`toReturn includes the custom mock name in the error message 1`] = ` @@ -2247,57 +2308,64 @@ Expected mock function not to have returned, but it returned: exports[`toReturn works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toReturn() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toReturnTimes .not only accepts a number argument 1`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toReturnTimes .not only accepts a number argument 2`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toReturnTimes .not only accepts a number argument 3`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toReturnTimes .not only accepts a number argument 4`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toReturnTimes .not only accepts a number argument 5`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toReturnTimes .not only accepts a number argument 6`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toReturnTimes .not passes if function called less than expected times 1`] = ` @@ -2345,49 +2413,55 @@ Expected mock function not to have returned two times, but it returned exports[`toReturnTimes only accepts a number argument 1`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - object: {}" +Matcher error: expected value must be a number + +Expected has type: object +Expected has value: {}" `; exports[`toReturnTimes only accepts a number argument 2`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - array: []" +Matcher error: expected value must be a number + +Expected has type: array +Expected has value: []" `; exports[`toReturnTimes only accepts a number argument 3`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - boolean: true" +Matcher error: expected value must be a number + +Expected has type: boolean +Expected has value: true" `; exports[`toReturnTimes only accepts a number argument 4`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - string: \\"a\\"" +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"a\\"" `; exports[`toReturnTimes only accepts a number argument 5`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - map: Map {}" +Matcher error: expected value must be a number + +Expected has type: map +Expected has value: Map {}" `; exports[`toReturnTimes only accepts a number argument 6`] = ` "expect(received)[.not].toReturnTimes(expected) -Expected value must be a number. -Got: - function: [Function anonymous]" +Matcher error: expected value must be a number + +Expected has type: function +Expected has value: [Function anonymous]" `; exports[`toReturnTimes passes if function returned equal to expected times 1`] = ` @@ -2399,9 +2473,10 @@ Expected mock function not to have returned two times, but it returned exports[`toReturnTimes works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toReturnTimes() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toReturnWith a call that throws is not considered to have returned 1`] = ` @@ -2439,9 +2514,10 @@ But it did not return." exports[`toReturnWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toReturnWith() -jest.fn() value must be a mock function or spy. -Received: - function: [Function fn]" +Matcher error: received value must be a mock or spy function + +Received has type: function +Received has value: [Function fn]" `; exports[`toReturnWith works when not called 1`] = ` diff --git a/packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap index af577d3e0811..8ce9e200485f 100644 --- a/packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap @@ -29,18 +29,21 @@ Instead, it threw: `; exports[`.toThrow() invalid actual 1`] = ` -"expect(function).toThrow(undefined) +"expect(received)[.not].toThrow(expected) -Received value must be a function, but instead \\"string\\" was found" +Matcher error: received value must be a function + +Received has type: string +Received has value: \\"a string\\"" `; exports[`.toThrow() invalid arguments 1`] = ` -"expect(function).not.toThrow(number) +"expect(received)[.not].toThrow(expected) + +Matcher error: expected value must be a string or regular expression or Error -Unexpected argument passed. -Expected: \\"string\\", \\"Error (type)\\" or \\"regexp\\". -Got: - string: \\"111\\"" +Expected has type: number +Expected has value: 111" `; exports[`.toThrow() promise/async throws if Error-like object is returned did not throw at all 1`] = ` @@ -154,18 +157,21 @@ Instead, it threw: `; exports[`.toThrowError() invalid actual 1`] = ` -"expect(function).toThrowError(undefined) +"expect(received)[.not].toThrowError(expected) -Received value must be a function, but instead \\"string\\" was found" +Matcher error: received value must be a function + +Received has type: string +Received has value: \\"a string\\"" `; exports[`.toThrowError() invalid arguments 1`] = ` -"expect(function).not.toThrowError(number) +"expect(received)[.not].toThrowError(expected) + +Matcher error: expected value must be a string or regular expression or Error -Unexpected argument passed. -Expected: \\"string\\", \\"Error (type)\\" or \\"regexp\\". -Got: - string: \\"111\\"" +Expected has type: number +Expected has value: 111" `; exports[`.toThrowError() promise/async throws if Error-like object is returned did not throw at all 1`] = ` diff --git a/packages/expect/src/__tests__/assertionCounts.test.js b/packages/expect/src/__tests__/assertionCounts.test.js index 6b59e8ae134d..52a595615e34 100644 --- a/packages/expect/src/__tests__/assertionCounts.test.js +++ b/packages/expect/src/__tests__/assertionCounts.test.js @@ -34,10 +34,10 @@ describe('.hasAssertions()', () => { jestExpect('a').toBe('a'); }); - it('throws if passed parameters', () => { + it('throws if expected is not undefined', () => { jestExpect(() => { jestExpect.hasAssertions(2); - }).toThrow(/does not accept any arguments/); + }).toThrowErrorMatchingSnapshot(); }); it('hasAssertions not leaking to global state', () => {}); diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 6fa7323a1198..f0995f708718 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -1020,6 +1020,12 @@ describe('.toHaveLength', () => { jestExpect(undefined).toHaveLength(1), ).toThrowErrorMatchingSnapshot(); }); + + test('matcher error expected length', () => { + expect(() => + jestExpect('abc').toHaveLength('3'), + ).toThrowErrorMatchingSnapshot(); + }); }); describe('.toHaveProperty()', () => { diff --git a/packages/expect/src/index.js b/packages/expect/src/index.js index 4c0aef0d3e92..759a2231f1b7 100644 --- a/packages/expect/src/index.js +++ b/packages/expect/src/index.js @@ -145,16 +145,15 @@ const makeResolveMatcher = ( const matcherStatement = `.resolves.${isNot ? 'not.' : ''}${matcherName}`; if (!isPromise(actual)) { throw new JestAssertionError( - matcherUtils.matcherHint(matcherStatement, 'received', '') + - '\n\n' + - `${matcherUtils.RECEIVED_COLOR( - 'received', - )} value must be a Promise.\n` + + matcherUtils.matcherErrorMessage( + matcherUtils.matcherHint(matcherStatement, undefined, ''), + `${matcherUtils.RECEIVED_COLOR('received')} value must be a Promise`, matcherUtils.printWithType( 'Received', actual, matcherUtils.printReceived, ), + ), ); } @@ -187,16 +186,15 @@ const makeRejectMatcher = ( const matcherStatement = `.rejects.${isNot ? 'not.' : ''}${matcherName}`; if (!isPromise(actual)) { throw new JestAssertionError( - matcherUtils.matcherHint(matcherStatement, 'received', '') + - '\n\n' + - `${matcherUtils.RECEIVED_COLOR( - 'received', - )} value must be a Promise.\n` + + matcherUtils.matcherErrorMessage( + matcherUtils.matcherHint(matcherStatement, undefined, ''), + `${matcherUtils.RECEIVED_COLOR('received')} value must be a Promise`, matcherUtils.printWithType( 'Received', actual, matcherUtils.printReceived, ), + ), ); } diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index a7f987a9a85c..1222b664bc3e 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -19,6 +19,7 @@ import { SUGGEST_TO_CONTAIN_EQUAL, ensureNoExpected, ensureNumbers, + matcherErrorMessage, matcherHint, printReceived, printExpected, @@ -162,12 +163,13 @@ const matchers: MatchersObject = { if (constType !== 'function') { throw new Error( - matcherHint('.toBeInstanceOf', 'value', 'constructor', { - isNot: this.isNot, - }) + - `\n\n` + - `Expected constructor to be a function. Instead got:\n` + - ` ${printExpected(constType)}`, + matcherErrorMessage( + matcherHint('.toBeInstanceOf', undefined, undefined, { + isNot: this.isNot, + }), + `${EXPECTED_COLOR('expected')} value must be a function`, + printWithType('Expected', constructor, printExpected), + ), ); } const pass = received instanceof constructor; @@ -288,12 +290,15 @@ const matchers: MatchersObject = { converted = Array.from(collection); } catch (e) { throw new Error( - matcherHint('[.not].toContainEqual', 'collection', 'value') + - '\n\n' + - `Expected ${RECEIVED_COLOR( - 'collection', - )} to be an array-like structure.\n` + + matcherErrorMessage( + matcherHint('.toContain', undefined, undefined, { + isNot: this.isNot, + }), + `${RECEIVED_COLOR( + 'received', + )} value must not be null nor undefined`, printWithType('Received', collection, printReceived), + ), ); } } @@ -340,12 +345,15 @@ const matchers: MatchersObject = { converted = Array.from(collection); } catch (e) { throw new Error( - matcherHint('[.not].toContainEqual', 'collection', 'value') + - '\n\n' + - `Expected ${RECEIVED_COLOR( - 'collection', - )} to be an array-like structure.\n` + + matcherErrorMessage( + matcherHint('.toContainEqual', undefined, undefined, { + isNot: this.isNot, + }), + `${RECEIVED_COLOR( + 'received', + )} value must not be null nor undefined`, printWithType('Received', collection, printReceived), + ), ); } } @@ -410,14 +418,27 @@ const matchers: MatchersObject = { (!received || typeof received.length !== 'number') ) { throw new Error( - matcherHint('[.not].toHaveLength', 'received', 'length') + - '\n\n' + - `Expected value to have a 'length' property that is a number. ` + - `Received:\n` + - ` ${printReceived(received)}\n` + - (received - ? `received.length:\n ${printReceived(received.length)}` - : ''), + matcherErrorMessage( + matcherHint('.toHaveLength', undefined, undefined, { + isNot: this.isNot, + }), + `${RECEIVED_COLOR( + 'received', + )} value must have a length property whose value must be a number`, + printWithType('Received', received, printReceived), + ), + ); + } + + if (typeof length !== 'number') { + throw new Error( + matcherErrorMessage( + matcherHint('.toHaveLength', undefined, undefined, { + isNot: this.isNot, + }), + `${EXPECTED_COLOR('expected')} value must be a number`, + printWithType('Expected', length, printExpected), + ), ); } @@ -449,14 +470,16 @@ const matchers: MatchersObject = { const valuePassed = arguments.length === 3; const secondArgument = valuePassed ? 'value' : null; - if (!object && typeof object !== 'string' && typeof object !== 'number') { + if (object === null || object === undefined) { throw new Error( - matcherHint('[.not].toHaveProperty', 'object', 'path', { - secondArgument, - }) + - '\n\n' + - `Expected ${RECEIVED_COLOR('object')} to be an object. Received:\n` + - ` ${getType(object)}: ${printReceived(object)}`, + matcherErrorMessage( + matcherHint('.toHaveProperty', undefined, 'path', { + isNot: this.isNot, + secondArgument, + }), + `${RECEIVED_COLOR('received')} value must not be null nor undefined`, + printWithType('Received', object, printReceived), + ), ); } @@ -464,14 +487,14 @@ const matchers: MatchersObject = { if (keyPathType !== 'string' && keyPathType !== 'array') { throw new Error( - matcherHint('[.not].toHaveProperty', 'object', 'path', { - secondArgument, - }) + - '\n\n' + - `Expected ${EXPECTED_COLOR( - 'path', - )} to be a string or an array. Received:\n` + - ` ${keyPathType}: ${printReceived(keyPath)}`, + matcherErrorMessage( + matcherHint('.toHaveProperty', undefined, 'path', { + isNot: this.isNot, + secondArgument, + }), + `${EXPECTED_COLOR('expected')} path must be a string or array`, + printWithType('Expected', keyPath, printExpected), + ), ); } @@ -533,10 +556,13 @@ const matchers: MatchersObject = { toMatch(received: string, expected: string | RegExp) { if (typeof received !== 'string') { throw new Error( - matcherHint('[.not].toMatch', 'string', 'expected') + - '\n\n' + - `${RECEIVED_COLOR('string')} value must be a string.\n` + + matcherErrorMessage( + matcherHint('.toMatch', undefined, undefined, { + isNot: this.isNot, + }), + `${RECEIVED_COLOR('received')} value must be a string`, printWithType('Received', received, printReceived), + ), ); } @@ -545,12 +571,15 @@ const matchers: MatchersObject = { !(typeof expected === 'string') ) { throw new Error( - matcherHint('[.not].toMatch', 'string', 'expected') + - '\n\n' + + matcherErrorMessage( + matcherHint('.toMatch', undefined, undefined, { + isNot: this.isNot, + }), `${EXPECTED_COLOR( 'expected', - )} value must be a string or a regular expression.\n` + + )} value must be a string or regular expression`, printWithType('Expected', expected, printExpected), + ), ); } @@ -577,19 +606,25 @@ const matchers: MatchersObject = { toMatchObject(receivedObject: Object, expectedObject: Object) { if (typeof receivedObject !== 'object' || receivedObject === null) { throw new Error( - matcherHint('[.not].toMatchObject', 'object', 'expected') + - '\n\n' + - `${RECEIVED_COLOR('received')} value must be an object.\n` + + matcherErrorMessage( + matcherHint('.toMatchObject', undefined, undefined, { + isNot: this.isNot, + }), + `${RECEIVED_COLOR('received')} value must be a non-null object`, printWithType('Received', receivedObject, printReceived), + ), ); } if (typeof expectedObject !== 'object' || expectedObject === null) { throw new Error( - matcherHint('[.not].toMatchObject', 'object', 'expected') + - '\n\n' + - `${EXPECTED_COLOR('expected')} value must be an object.\n` + + matcherErrorMessage( + matcherHint('.toMatchObject', undefined, undefined, { + isNot: this.isNot, + }), + `${EXPECTED_COLOR('expected')} value must be a non-null object`, printWithType('Expected', expectedObject, printExpected), + ), ); } diff --git a/packages/expect/src/spyMatchers.js b/packages/expect/src/spyMatchers.js index 39c5abb36dea..c12e0b47b50c 100644 --- a/packages/expect/src/spyMatchers.js +++ b/packages/expect/src/spyMatchers.js @@ -16,6 +16,7 @@ import { ensureExpectedIsNumber, ensureNoExpected, EXPECTED_COLOR, + matcherErrorMessage, matcherHint, pluralize, printExpected, @@ -470,11 +471,11 @@ const ensureMock = (mockOrSpy, matcherName) => { mockOrSpy._isMockFunction !== true) ) { throw new Error( - matcherHint('[.not]' + matcherName, 'jest.fn()', '') + - '\n\n' + - `${RECEIVED_COLOR('jest.fn()')} value must be a mock function ` + - `or spy.\n` + + matcherErrorMessage( + matcherHint('[.not]' + matcherName, 'jest.fn()', ''), + `${RECEIVED_COLOR('received')} value must be a mock or spy function`, printWithType('Received', mockOrSpy, printReceived), + ), ); } }; diff --git a/packages/expect/src/toThrowMatchers.js b/packages/expect/src/toThrowMatchers.js index 48f69b46d630..7d62ca4c0105 100644 --- a/packages/expect/src/toThrowMatchers.js +++ b/packages/expect/src/toThrowMatchers.js @@ -13,10 +13,13 @@ import getType from 'jest-get-type'; import {escapeStrForRegex} from 'jest-regex-util'; import {formatStackTrace, separateMessageFromStack} from 'jest-message-util'; import { + EXPECTED_COLOR, RECEIVED_COLOR, highlightTrailingWhitespace, + matcherErrorMessage, matcherHint, printExpected, + printReceived, printWithType, } from 'jest-matcher-utils'; import {equals} from './jasmineUtils'; @@ -35,10 +38,11 @@ export const createMatcher = (matcherName: string, fromPromise?: boolean) => ( if (typeof actual !== 'function') { if (!fromPromise) { throw new Error( - matcherHint(matcherName, 'function', getType(value)) + - '\n\n' + - 'Received value must be a function, but instead ' + - `"${getType(actual)}" was found`, + matcherErrorMessage( + matcherHint('[.not]' + matcherName, undefined, undefined), + `${RECEIVED_COLOR('received')} value must be a function`, + printWithType('Received', actual, printReceived), + ), ); } } else { @@ -83,13 +87,13 @@ export const createMatcher = (matcherName: string, fromPromise?: boolean) => ( }; } else { throw new Error( - matcherHint('.not' + matcherName, 'function', getType(value)) + - '\n\n' + - 'Unexpected argument passed.\nExpected: ' + - `${printExpected('string')}, ${printExpected( - 'Error (type)', - )} or ${printExpected('regexp')}.\n` + - printWithType('Got', String(expected), printExpected), + matcherErrorMessage( + matcherHint('[.not]' + matcherName, undefined, undefined), + `${EXPECTED_COLOR( + 'expected', + )} value must be a string or regular expression or Error`, + printWithType('Expected', expected, printExpected), + ), ); } }; diff --git a/packages/jest-matcher-utils/src/__tests__/__snapshots__/index.test.js.snap b/packages/jest-matcher-utils/src/__tests__/__snapshots__/index.test.js.snap index 7a8565648a34..fb80b64d1896 100644 --- a/packages/jest-matcher-utils/src/__tests__/__snapshots__/index.test.js.snap +++ b/packages/jest-matcher-utils/src/__tests__/__snapshots__/index.test.js.snap @@ -1,5 +1,41 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`.ensureNoExpected() throws error when expected is not undefined 1`] = ` +"expect(received)[.not]This() + +Matcher error: expected value must be omitted or undefined + +Expected has type: object +Expected has value: {\\"a\\": 1}" +`; + +exports[`.ensureNoExpected() throws error when expected is not undefined with matcherName 1`] = ` +"expect(received)[.not].toBeDefined() + +Matcher error: expected value must be omitted or undefined + +Expected has type: object +Expected has value: {\\"a\\": 1}" +`; + +exports[`.ensureNumbers() throws error when expected is not a number 1`] = ` +"expect(received)[.not]This matcher(expected) + +Matcher error: expected value must be a number + +Expected has type: string +Expected has value: \\"not_a_number\\"" +`; + +exports[`.ensureNumbers() throws error when received is not a number 1`] = ` +"expect(received)[.not]This matcher(expected) + +Matcher error: received value must be a number + +Received has type: string +Received has value: \\"not_a_number\\"" +`; + exports[`.stringify() reduces maxDepth if stringifying very large objects 1`] = `"{\\"a\\": 1, \\"b\\": [Object]}"`; exports[`.stringify() reduces maxDepth if stringifying very large objects 2`] = `"{\\"a\\": 1, \\"b\\": {\\"0\\": \\"test\\", \\"1\\": \\"test\\", \\"2\\": \\"test\\", \\"3\\": \\"test\\", \\"4\\": \\"test\\", \\"5\\": \\"test\\", \\"6\\": \\"test\\", \\"7\\": \\"test\\", \\"8\\": \\"test\\", \\"9\\": \\"test\\"}}"`; diff --git a/packages/jest-matcher-utils/src/__tests__/index.test.js b/packages/jest-matcher-utils/src/__tests__/index.test.js index 95cb4682ff09..11843c3aceb8 100644 --- a/packages/jest-matcher-utils/src/__tests__/index.test.js +++ b/packages/jest-matcher-utils/src/__tests__/index.test.js @@ -95,13 +95,13 @@ describe('.ensureNumbers()', () => { test('throws error when expected is not a number', () => { expect(() => { ensureNumbers(1, 'not_a_number'); - }).toThrow('Expected value must be a number'); + }).toThrowErrorMatchingSnapshot(); }); - test('throws error when actual is not a number', () => { + test('throws error when received is not a number', () => { expect(() => { ensureNumbers('not_a_number', 3); - }).toThrow('Received value must be a number'); + }).toThrowErrorMatchingSnapshot(); }); }); @@ -112,16 +112,16 @@ describe('.ensureNoExpected()', () => { }).not.toThrow(); }); - test('throws error when is not undefined', () => { + test('throws error when expected is not undefined', () => { expect(() => { ensureNoExpected({a: 1}); - }).toThrow('Matcher does not accept any arguments'); + }).toThrowErrorMatchingSnapshot(); }); - test('throws error when is not undefined with matcherName', () => { + test('throws error when expected is not undefined with matcherName', () => { expect(() => { ensureNoExpected({a: 1}, '.toBeDefined'); - }).toThrow('Matcher does not accept any arguments'); + }).toThrowErrorMatchingSnapshot(); }); }); diff --git a/packages/jest-matcher-utils/src/index.js b/packages/jest-matcher-utils/src/index.js index 232b0e33cba9..03f0e6369826 100644 --- a/packages/jest-matcher-utils/src/index.js +++ b/packages/jest-matcher-utils/src/index.js @@ -89,27 +89,28 @@ export const printExpected = (value: any) => EXPECTED_COLOR(highlightTrailingWhitespace(stringify(value))); export const printWithType = ( - name: string, - received: any, - print: (value: any) => string, + name: string, // 'Expected' or 'Received' + value: any, + print: (value: any) => string, // printExpected or printReceived ) => { - const type = getType(received); - return ( - name + - ':' + - (type !== 'null' && type !== 'undefined' ? '\n ' + type + ': ' : ' ') + - print(received) - ); + const type = getType(value); + const hasType = + type !== 'null' && type !== 'undefined' + ? `${name} has type: ${type}\n` + : ''; + const hasValue = `${name} has value: ${print(value)}`; + return hasType + hasValue; }; export const ensureNoExpected = (expected: any, matcherName: string) => { matcherName || (matcherName = 'This'); if (typeof expected !== 'undefined') { throw new Error( - matcherHint('[.not]' + matcherName, undefined, '') + - '\n\n' + - 'Matcher does not accept any arguments.\n' + - printWithType('Got', expected, printExpected), + matcherErrorMessage( + matcherHint('[.not]' + matcherName, undefined, ''), + `${EXPECTED_COLOR('expected')} value must be omitted or undefined`, + printWithType('Expected', expected, printExpected), + ), ); } }; @@ -118,10 +119,11 @@ export const ensureActualIsNumber = (actual: any, matcherName: string) => { matcherName || (matcherName = 'This matcher'); if (typeof actual !== 'number') { throw new Error( - matcherHint('[.not]' + matcherName) + - '\n\n' + - `Received value must be a number.\n` + + matcherErrorMessage( + matcherHint('[.not]' + matcherName), + `${RECEIVED_COLOR('received')} value must be a number`, printWithType('Received', actual, printReceived), + ), ); } }; @@ -130,10 +132,11 @@ export const ensureExpectedIsNumber = (expected: any, matcherName: string) => { matcherName || (matcherName = 'This matcher'); if (typeof expected !== 'number') { throw new Error( - matcherHint('[.not]' + matcherName) + - '\n\n' + - `Expected value must be a number.\n` + - printWithType('Got', expected, printExpected), + matcherErrorMessage( + matcherHint('[.not]' + matcherName), + `${EXPECTED_COLOR('expected')} value must be a number`, + printWithType('Expected', expected, printExpected), + ), ); } }; @@ -150,6 +153,12 @@ export const ensureNumbers = ( export const pluralize = (word: string, count: number) => (NUMBERS[count] || count) + ' ' + word + (count === 1 ? '' : 's'); +export const matcherErrorMessage = ( + hint: string, // assertion returned from call to matcherHint + generic: string, // condition which correct value must fulfill + specific: string, // incorrect value returned from call to printWithType +) => `${hint}\n\n${chalk.bold('Matcher error')}: ${generic}\n\n${specific}`; + export const matcherHint = ( matcherName: string, received: string = 'received',