diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index a539fdf2462e..40ab85b5d621 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -201,9 +201,9 @@ Received: undefined" `; exports[`.toBe() does not crash on circular references 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: {} Received: {\\"circular\\": [Circular]} @@ -220,72 +220,72 @@ Difference: `; exports[`.toBe() fails for '"a"' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: \\"a\\" Received: \\"a\\"" `; exports[`.toBe() fails for '[]' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: [] Received: []" `; exports[`.toBe() fails for '{}' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: {} Received: {}" `; exports[`.toBe() fails for '1' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: 1 Received: 1" `; exports[`.toBe() fails for 'false' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: false Received: false" `; exports[`.toBe() fails for 'null' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: null Received: null" `; exports[`.toBe() fails for 'undefined' with '.not' 1`] = ` -"expect(received).not.toBe(expected) +"expect(received).not.toBe(expected) // Object.is equality -Expected value to not be (using Object.is): +Expected value to not be: undefined Received: undefined" `; exports[`.toBe() fails for: "abc" and "cde" 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: \\"cde\\" Received: \\"abc\\"" @@ -293,9 +293,9 @@ Received: exports[`.toBe() fails for: "with trailing space" and "without trailing space" 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: \\"without trailing space\\" Received: \\"with @@ -303,9 +303,9 @@ Received: `; exports[`.toBe() fails for: [] and [] 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: [] Received: [] @@ -316,9 +316,9 @@ Difference: `; exports[`.toBe() fails for: {"a": 1} and {"a": 1} 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: {\\"a\\": 1} Received: {\\"a\\": 1} @@ -329,9 +329,9 @@ Difference: `; exports[`.toBe() fails for: {"a": 1} and {"a": 5} 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: {\\"a\\": 5} Received: {\\"a\\": 1} @@ -348,9 +348,9 @@ Difference: `; exports[`.toBe() fails for: {} and {} 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: {} Received: {} @@ -361,9 +361,9 @@ Difference: `; exports[`.toBe() fails for: -0 and 0 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: 0 Received: -0 @@ -374,18 +374,18 @@ Difference: `; exports[`.toBe() fails for: 1 and 2 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: 2 Received: 1" `; exports[`.toBe() fails for: null and undefined 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: undefined Received: null @@ -396,16 +396,16 @@ Difference: `; exports[`.toBe() fails for: true and false 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: false Received: true" `; exports[`.toBeCloseTo() {pass: true} expect(0)toBeCloseTo( 0) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 0 @@ -414,7 +414,7 @@ Received: `; exports[`.toBeCloseTo() {pass: true} expect(0)toBeCloseTo( 0.001) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 0.001 @@ -423,7 +423,7 @@ Received: `; exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.225) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 1.225 @@ -432,7 +432,7 @@ Received: `; exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.226) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 1.226 @@ -441,7 +441,7 @@ Received: `; exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.229) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 1.229 @@ -450,7 +450,7 @@ Received: `; exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.234) 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected) Expected value not to be close to (with 2-digit precision): 1.234 @@ -459,7 +459,7 @@ Received: `; exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.000004, 5] 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected, precision) Expected value not to be close to (with 5-digit precision): 0.000004 @@ -468,7 +468,7 @@ Received: `; exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.0001, 3] 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected, precision) Expected value not to be close to (with 3-digit precision): 0.0001 @@ -477,7 +477,7 @@ Received: `; exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.1, 0] 1`] = ` -"expect(received).not.toBeCloseTo(expected, precision) +"expect(received).not.toBeCloseTo(expected, precision) Expected value not to be close to (with 0-digit precision): 0.1 @@ -486,7 +486,7 @@ Received: `; exports[`.toBeCloseTo() throws: [0, 0.01] 1`] = ` -"expect(received).toBeCloseTo(expected, precision) +"expect(received).toBeCloseTo(expected) Expected value to be close to (with 2-digit precision): 0.01 @@ -495,7 +495,7 @@ Received: `; exports[`.toBeCloseTo() throws: [1, 1.23] 1`] = ` -"expect(received).toBeCloseTo(expected, precision) +"expect(received).toBeCloseTo(expected) Expected value to be close to (with 2-digit precision): 1.23 @@ -504,7 +504,7 @@ Received: `; exports[`.toBeCloseTo() throws: [1.23, 1.2249999] 1`] = ` -"expect(received).toBeCloseTo(expected, precision) +"expect(received).toBeCloseTo(expected) Expected value to be close to (with 2-digit precision): 1.2249999 @@ -2667,7 +2667,7 @@ To have a nested property: `; exports[`.toHaveProperty() {pass: false} expect("abc").toHaveProperty('a.b.c', {"a": 5}) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: \\"abc\\" @@ -2679,7 +2679,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {"d": 1}}}}).toHaveProperty('a,b,c,d', 2) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {\\"d\\": 1}}}} @@ -2692,7 +2692,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {"d": 1}}}}).toHaveProperty('a.b.c.d', 2) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {\\"d\\": 1}}}} @@ -2705,7 +2705,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {"d": 1}}}}).toHaveProperty('a.b.ttt.d', 1) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {\\"d\\": 1}}}} @@ -2729,7 +2729,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {}}}}).toHaveProperty('a.b.c.d', 1) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {}}}} @@ -2742,7 +2742,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": 5}}}).toHaveProperty('a.b', {"c": 4}) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": 5}}} @@ -2765,7 +2765,7 @@ Difference: `; exports[`.toHaveProperty() {pass: false} expect({"a": {"b": 3}}).toHaveProperty('a.b', undefined) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": 3}} @@ -2793,7 +2793,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a": 1}).toHaveProperty('a.b.c.d', 5) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a\\": 1} @@ -2806,7 +2806,7 @@ Received: `; exports[`.toHaveProperty() {pass: false} expect({"a.b.c.d": 1}).toHaveProperty('a.b.c.d', 2) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a.b.c.d\\": 1} @@ -2818,7 +2818,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: false} expect({"a.b.c.d": 1}).toHaveProperty('a.b.c.d', 2) 2`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {\\"a.b.c.d\\": 1} @@ -2841,7 +2841,7 @@ To have a nested property: `; exports[`.toHaveProperty() {pass: false} expect({}).toHaveProperty('a', "a") 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {} @@ -2858,7 +2858,7 @@ Difference: `; exports[`.toHaveProperty() {pass: false} expect({}).toHaveProperty('a', "test") 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {} @@ -2870,7 +2870,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: false} expect({}).toHaveProperty('b', undefined) 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: {} @@ -2897,7 +2897,7 @@ To have a nested property: `; exports[`.toHaveProperty() {pass: false} expect(1).toHaveProperty('a.b.c', "test") 1`] = ` -"expect(object).toHaveProperty(path, value) +"expect(object).toHaveProperty(path, value) Expected the object: 1 @@ -2919,7 +2919,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a": {"b": [1, 2, 3]}}).toHaveProperty('a,b,1', 2) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": [1, 2, 3]}} @@ -2941,7 +2941,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a": {"b": {"c": {"d": 1}}}}).toHaveProperty('a,b,c,d', 1) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {\\"d\\": 1}}}} @@ -2963,7 +2963,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a": {"b": {"c": {"d": 1}}}}).toHaveProperty('a.b.c.d', 1) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": {\\"d\\": 1}}}} @@ -2975,7 +2975,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: true} expect({"a": {"b": {"c": 5}}}).toHaveProperty('a.b', {"c": 5}) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": {\\"c\\": 5}}} @@ -2997,7 +2997,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a": {"b": undefined}}).toHaveProperty('a.b', undefined) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": {\\"b\\": undefined}} @@ -3019,7 +3019,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a": 0}).toHaveProperty('a', 0) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a\\": 0} @@ -3041,7 +3041,7 @@ Not to have a nested property: `; exports[`.toHaveProperty() {pass: true} expect({"a.b.c.d": 1}).toHaveProperty('a.b.c.d', 1) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"a.b.c.d\\": 1} @@ -3053,7 +3053,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: true} expect({"property": 1}).toHaveProperty('property', 1) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {\\"property\\": 1} @@ -3065,7 +3065,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: true} expect({}).toHaveProperty('a', undefined) 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {} @@ -3077,7 +3077,7 @@ With a value of: `; exports[`.toHaveProperty() {pass: true} expect({}).toHaveProperty('b', "b") 1`] = ` -"expect(object).not.toHaveProperty(path, value) +"expect(object).not.toHaveProperty(path, value) Expected the object: {} diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 25258e7ef3b2..b99c6cff12be 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -40,13 +40,16 @@ type ContainIterable = const matchers: MatchersObject = { toBe(received: any, expected: number) { + const comment = 'Object.is equality'; const pass = Object.is(received, expected); const message = pass ? () => - matcherHint('.not.toBe') + + matcherHint('.not.toBe', undefined, undefined, { + comment, + }) + '\n\n' + - `Expected value to not be (using Object.is):\n` + + `Expected value to not be:\n` + ` ${printExpected(expected)}\n` + `Received:\n` + ` ${printReceived(received)}` @@ -61,9 +64,11 @@ const matchers: MatchersObject = { }); return ( - matcherHint('.toBe') + + matcherHint('.toBe', undefined, undefined, { + comment, + }) + '\n\n' + - `Expected value to be (using Object.is):\n` + + `Expected value to be:\n` + ` ${printExpected(expected)}\n` + `Received:\n` + ` ${printReceived(received)}` + @@ -79,11 +84,14 @@ const matchers: MatchersObject = { }, toBeCloseTo(actual: number, expected: number, precision?: number = 2) { + const secondArgument = arguments.length === 3 ? 'precision' : null; ensureNumbers(actual, expected, '.toBeCloseTo'); const pass = Math.abs(expected - actual) < Math.pow(10, -precision) / 2; const message = pass ? () => - matcherHint('.not.toBeCloseTo', 'received', 'expected, precision') + + matcherHint('.not.toBeCloseTo', undefined, undefined, { + secondArgument, + }) + '\n\n' + `Expected value not to be close to (with ${printExpected( precision, @@ -92,7 +100,9 @@ const matchers: MatchersObject = { `Received:\n` + ` ${printReceived(actual)}` : () => - matcherHint('.toBeCloseTo', 'received', 'expected, precision') + + matcherHint('.toBeCloseTo', undefined, undefined, { + secondArgument, + }) + '\n\n' + `Expected value to be close to (with ${printExpected( precision, @@ -488,11 +498,12 @@ const matchers: MatchersObject = { toHaveProperty(object: Object, keyPath: string | Array, value?: any) { const valuePassed = arguments.length === 3; + const secondArgument = valuePassed ? 'value' : null; if (!object && typeof object !== 'string' && typeof object !== 'number') { throw new Error( matcherHint('[.not].toHaveProperty', 'object', 'path', { - secondArgument: valuePassed ? 'value' : null, + secondArgument, }) + '\n\n' + `Expected ${RECEIVED_COLOR('object')} to be an object. Received:\n` + @@ -505,7 +516,7 @@ const matchers: MatchersObject = { if (keyPathType !== 'string' && keyPathType !== 'array') { throw new Error( matcherHint('[.not].toHaveProperty', 'object', 'path', { - secondArgument: valuePassed ? 'value' : null, + secondArgument, }) + '\n\n' + `Expected ${EXPECTED_COLOR( @@ -527,7 +538,7 @@ const matchers: MatchersObject = { const message = pass ? () => matcherHint('.not.toHaveProperty', 'object', 'path', { - secondArgument: valuePassed ? 'value' : null, + secondArgument, }) + '\n\n' + `Expected the object:\n` + @@ -542,7 +553,7 @@ const matchers: MatchersObject = { : ''; return ( matcherHint('.toHaveProperty', 'object', 'path', { - secondArgument: valuePassed ? 'value' : null, + secondArgument, }) + '\n\n' + `Expected the object:\n` + diff --git a/packages/jest-jasmine2/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/jest-jasmine2/src/__tests__/__snapshots__/matchers.test.js.snap index 06eadd13e8aa..d94175512f98 100644 --- a/packages/jest-jasmine2/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/jest-jasmine2/src/__tests__/__snapshots__/matchers.test.js.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`matchers proxies matchers to expect 1`] = ` -"expect(received).toBe(expected) +"expect(received).toBe(expected) // Object.is equality -Expected value to be (using Object.is): +Expected value to be: 2 Received: 1" diff --git a/packages/jest-matcher-utils/src/index.js b/packages/jest-matcher-utils/src/index.js index 8fec77bea145..518f5c24ba74 100644 --- a/packages/jest-matcher-utils/src/index.js +++ b/packages/jest-matcher-utils/src/index.js @@ -150,19 +150,21 @@ export const matcherHint = ( matcherName: string, received: string = 'received', expected: string = 'expected', - options: ?{ - secondArgument?: ?string, + options: { + comment?: string, isDirectExpectCall?: boolean, - }, + secondArgument?: ?string, + } = {}, ) => { - const secondArgument = options && options.secondArgument; - const isDirectExpectCall = options && options.isDirectExpectCall; + const {comment, isDirectExpectCall, secondArgument} = options; return ( chalk.dim('expect' + (isDirectExpectCall ? '' : '(')) + RECEIVED_COLOR(received) + chalk.dim((isDirectExpectCall ? '' : ')') + matcherName + '(') + EXPECTED_COLOR(expected) + - (secondArgument ? `, ${EXPECTED_COLOR(secondArgument)}` : '') + - chalk.dim(')') + (secondArgument + ? `${chalk.dim(', ')}${EXPECTED_COLOR(secondArgument)}` + : '') + + chalk.dim(`)${comment ? ` // ${comment}` : ''}`) ); };