Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jest-snapshot: Highlight substring differences when matcher fails, part 3 #8569

Merged
merged 17 commits into from Jun 18, 2019
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- `[expect]` Highlight substring differences when matcher fails, part 1 ([#8448](https://github.com/facebook/jest/pull/8448))
- `[expect]` Highlight substring differences when matcher fails, part 2 ([#8528](https://github.com/facebook/jest/pull/8528))
- `[jest-snapshot]` Highlight substring differences when matcher fails, part 3 ([#8569](https://github.com/facebook/jest/pull/8569))
- `[jest-cli]` Improve chai support (with detailed output, to match jest exceptions) ([#8454](https://github.com/facebook/jest/pull/8454))
- `[*]` Manage the global timeout with `--testTimeout` command line argument. ([#8456](https://github.com/facebook/jest/pull/8456))
- `[pretty-format]` Render custom displayName of memoized components
Expand Down
14 changes: 4 additions & 10 deletions e2e/__tests__/__snapshots__/failures.test.ts.snap
Expand Up @@ -790,11 +790,8 @@ FAIL __tests__/snapshot.test.js

Snapshot name: \`failing snapshot 1\`

- Snapshot
+ Received

- "bar"
+ "foo"
Snapshot: "bar"
Received: "foo"

9 |
10 | test('failing snapshot', () => {
Expand All @@ -819,11 +816,8 @@ FAIL __tests__/snapshotWithHint.test.js

Snapshot name: \`failing snapshot with hint: descriptive hint 1\`

- Snapshot
+ Received

- "bar"
+ "foo"
Snapshot: "bar"
Received: "foo"

9 |
10 | test('failing snapshot with hint', () => {
Expand Down
Expand Up @@ -6,10 +6,8 @@ FAIL __tests__/bar.spec.js
● bar
expect(received).toMatchSnapshot()
Snapshot name: \`bar 1\`
- Snapshot
+ Received
- "foo"
+ "bar"
Snapshot: "foo"
Received: "bar"
1 |
> 2 | test('bar', () => { expect('bar').toMatchSnapshot(); });
| ^
Expand Down
2 changes: 1 addition & 1 deletion e2e/__tests__/toMatchSnapshot.test.ts
Expand Up @@ -108,7 +108,7 @@ test('first snapshot fails, second passes', () => {
writeFiles(TESTS_DIR, {[filename]: template([`'kiwi'`, `'banana'`])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch('Snapshot name: `snapshots 1`');
expect(stderr).toMatch('- "apple"\n + "kiwi"');
expect(stderr).toMatch('Snapshot: "apple"\n Received: "kiwi"');
expect(stderr).not.toMatch('1 obsolete snapshot found');
expect(status).toBe(1);
}
Expand Down
1 change: 1 addition & 0 deletions packages/jest-snapshot/package.json
Expand Up @@ -15,6 +15,7 @@
"chalk": "^2.0.1",
"expect": "^24.8.0",
"jest-diff": "^24.8.0",
"jest-get-type": "^24.8.0",
"jest-matcher-utils": "^24.8.0",
"jest-message-util": "^24.8.0",
"jest-resolve": "^24.8.0",
Expand Down
@@ -0,0 +1,185 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`empty string expected and received single line 1`] = `
Snapshot: <g>""</>
Received: <r>"single line string"</>
`;

exports[`empty string received and expected multi line 1`] = `
Snapshot: <g>"multi</>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the empty/multiline case, maybe start the multiline string on the next line so that the indentation is less off (still off by one because of the ")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super question, as usual. Extra credit for thinking about alignment.

Here are 2 alternatives for response or maybe they provoke some other solution:

multiline empty

I though about omitting double quote marks, but content of string might be ambiguous with serialization of other data types.

I’m thinking backticks for multiline string property in future data-driven diff at right:

multiline property value

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second one is probably easier on the eyes if the string itself has lines indented by 2. Wondering if inserting indentation into people's strings is a good idea though - is there a legitimate use case for copying it out of the terminal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, inserting indentation is a concern. Although Jest indents the reports in console.

Of alternatives above, I agree with you to prefer at the right.

Here is the minimal solution at the left and another indented alternative at the right:

multi 2

Unless there is a clear winner, I think to leave it alone (as it has been) for this pull request.

<g>line</>
<g>string"</>
Received: <r>""</>
`;

exports[`escape backslash in multi line string 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<g>- Forward / slash<i> and b</i>ack \\ slash</>
<r>+ Forward / slash</>
<r>+ <i>B</i>ack \\ slash</>
`;

exports[`escape backslash in single line string 1`] = `
Snapshot: <g>"<i>f</i>orward / slash and back \\\\ slash"</>
Received: <r>"<i>F</i>orward / slash and back \\\\ slash"</>
`;

exports[`escape double quote marks in string 1`] = `
Snapshot: <g>"What does \\"<i>oo</i>bleck\\" mean?"</>
Received: <r>"What does \\"<i>ew</i>bleck\\" mean?"</>
`;

exports[`escape regexp 1`] = `
Snapshot: <g>/\\\\\\\\\\("\\)/g</>
Received: <r>/\\\\\\\\\\("\\)/</>
`;

exports[`expand false 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<y>@@ -12,7 +12,9 @@</>
<d> ? "number"</>
<d> : T extends boolean</>
<d> ? "boolean"</>
<d> : T extends undefined</>
<d> ? "undefined"</>
<g>- : T extends Function<i> </i>? "function"<i> </i>: "object";</>
<r>+ : T extends Function</>
<r>+ ? "function"</>
<r>+ : "object";</>
<d> ↵</>
`;

exports[`expand true 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<d> type TypeName<T> =</>
<d> T extends string ? "string" :</>
<d> T extends number ? "number" :</>
<d> T extends boolean ? "boolean" :</>
<d> T extends undefined ? "undefined" :</>
<d> T extends Function ? "function" :</>
<d> "object";</>
<d> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</>
<d> type TypeName<T> = T extends string</>
<d> ? "string"</>
<d> : T extends number</>
<d> ? "number"</>
<d> : T extends boolean</>
<d> ? "boolean"</>
<d> : T extends undefined</>
<d> ? "undefined"</>
<g>- : T extends Function<i> </i>? "function"<i> </i>: "object";</>
<r>+ : T extends Function</>
<r>+ ? "function"</>
<r>+ : "object";</>
<d> ↵</>
`;

exports[`fallback to line diff 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<r>+ ====================================options=====================================</>
<r>+ parsers: ["flow", "typescript"]</>
<r>+ printWidth: 80</>
<r>+ | printWidth</>
<r>+ =====================================input======================================</>
<d> [...a, ...b,];</>
<d> [...a, ...b];</>
<g>- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</>
<r>+ </>
<r>+ =====================================output=====================================</>
<d> [...a, ...b];</>
<d> [...a, ...b];</>
<d> </>
<r>+ ================================================================================</>
`;

exports[`isLineDiffable false boolean 1`] = `
Snapshot: <g>true</>
Received: <r>false</>
`;

exports[`isLineDiffable false number 1`] = `
Snapshot: <g>-0</>
Received: <r>NaN</>
`;

exports[`isLineDiffable true array 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<d> Array [</>
<d> Object {</>
<r>+ "_id": "b14680dec683e744ada1f2fe08614086",</>
<d> "code": 4011,</>
<d> "weight": 2.13,</>
<d> },</>
<d> Object {</>
<r>+ "_id": "7fc63ff01769c4fa7d9279e97e307829",</>
<d> "code": 4019,</>
<d> "count": 4,</>
<d> },</>
<d> ]</>
`;

exports[`isLineDiffable true object 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<d> Object {</>
<d> "props": Object {</>
<g>- "className": "logo",</>
<g>- "src": "/img/jest.png",</>
<r>+ "alt": "Jest logo",</>
<r>+ "class": "logo",</>
<r>+ "src": "/img/jest.svg",</>
<d> },</>
<d> "type": "img",</>
<d> }</>
`;

exports[`isLineDiffable true single line expected and received 1`] = `
Snapshot: <g>Array []</>
Received: <r>Object {}</>
`;

exports[`multi line small change in one line and other is unchanged 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<g>- There is no route defined for key <i>'</i>Settings<i>'</i>.</>
<r>+ There is no route defined for key Settings.</>
<d> Must be one of: 'Home'</>
`;

exports[`multi line small changes 1`] = `
<g>- Snapshot</>
<r>+ Received</>

<g>- 6<i>9</i> |·</>
<r>+ 6<i>8</i> |·</>
<g>- <i>70</i> | test('assert.doesNotThrow', () => {</>
<r>+ <i>69</i> | test('assert.doesNotThrow', () => {</>
<g>- > 7<i>1</i> | assert.doesNotThrow(() => {</>
<r>+ > 7<i>0</i> | assert.doesNotThrow(() => {</>
<d> | ^</>
<g>- 7<i>2</i> | throw Error('err!');</>
<r>+ 7<i>1</i> | throw Error('err!');</>
<g>- 7<i>3</i> | });</>
<r>+ 7<i>2</i> | });</>
<g>- 7<i>4</i> | });</>
<r>+ 7<i>3</i> | });</>
<g>- at Object.doesNotThrow (__tests__/assertionError.test.js:7<i>1</i>:10)</>
<r>+ at Object.doesNotThrow (__tests__/assertionError.test.js:7<i>0</i>:10)</>
`;

exports[`single line large changes 1`] = `
Snapshot: <g>"<i>A</i>rray length<i> must be a finite positive integer</i>"</>
Received: <r>"<i>Invalid a</i>rray length"</>
`;