jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.23k stars 6.46k forks source link

Show word diffs in strings when they are properties on an object #9940

Closed orta closed 1 year ago

orta commented 4 years ago

🚀 Feature Proposal

I have some snapshots which are pretty chunky strings of markdown

Screen Shot 2020-05-01 at 11 29 49 AM

I'd like to be able to more quickly see where the string differ! This is already supported when directly diffing strings (expect('a b').toEqual('a c') or expect('a c').toMatchSnapshot()), but not for strings within other structures.

Motivation

I'd like a clue where the difference starts

Example

Any snapshot

Pitch

It's a nice to have! :D

orta commented 4 years ago

diff-so-pretty does this, which might also be an option:

Screen Shot 2020-05-01 at 11 39 03 AM

jeysal commented 4 years ago

@pedrottimark has already implemented word diff with background color highlighting for many matchers. Apparently you've found a missing one, snapshots?

jeysal commented 4 years ago

Just tried it out, it works for snapshots that are strings, but not for string properties in other structures being snapshotted. @orta mind changing the issue to be about extending word diff support to strings nested in other structures (snapshot or toEqual doesn't matter, not related to snapshots) and we can stick a help wanted label onto it?

Getriax commented 4 years ago

I was able hack something like this. I can continue working on it if you'd like me to.

jest-9940-PoC

jeysal commented 4 years ago

Is this just by word diffing each whole line? While not a super sophisticated solution (that'd have to come from something like #7893), I think that'd be good enough. Would also word diff property keys, but that could actually be a good thing for people that have typos in there. Some cases may be weird if it diffs "2" (string) vs 2 (number) and 'complains' about the quotes..

Getriax commented 4 years ago

Yes, for now I am using diffStringsRaw for the lines (with [-, +] pattern). However their order does not always work like this (attachment). I think better option would be to highlight the lines before pretty-formating the object and just compare the strings by keys. Idk if there is a better option, WDYT?

jest-9940-compare

pedrottimark commented 4 years ago

Thank you for giving this realistic example of the need for substring differences.

For snapshots of serialized objects or elements, my tests of substring differences have been sadly divided almost equally between clear and confusing results.

Therefore, I have been working on non-snapshot deep equality assertions:

Here is an overdue progress update on the relevant comparison project. Over Thanksgiving weekend, it hit me that prettier provides a pattern for data-driven differences. I have adapted its intermediate description tree and printing loop for steps 2 and 3:

  1. compute comparison tree according to strict criteria with 11 node types:

    • 'changeCollection' for example, changes in array, object, map, set
    • 'changeConstructor' for strict deep equality
    • 'changeKey' for example, from className to class
    • 'changeString1' for one-line string
    • 'changeString2' for multiple-line strings
    • 'changeType' for example, number and string, or object and nullish
    • 'changeVal' for example, unequal primitive values
    • 'commonCollection' for example, no changes in array, object, map, set
    • 'commonVal' for example, equal primitive values
    • 'delete' for example, expected object has property but received does not
    • 'insert' for example, received object has property but expected does not
  2. build description tree

  3. print lines with colors for indent size and line width

Substring differences: baseline at left and improved at right:

9940 substring

A goal of the description is valid ECMAScript, if you omit the + received lines that are aligned under a - expected line

--no-expand option: baseline at left for 5 context lines and improved at right for 2 context units:

9940 context

The next major step is to decide on an interface for the description plugins which provides enough information to keep improving the --no-expand option in the future.

Your thoughts, questions, or concerns are welcome.

orta commented 4 years ago

Just kinda stunned, honestly. Those are incredible diffs.

SimenB commented 4 years ago

woah, those diffs look amazing @pedrottimark! You got me all fired up now 😀

maricn commented 3 years ago

@pedrottimark Hi, thanks for the last update. Are there any new updates on this topic?

davidnormo commented 2 years ago

@pedrottimark those changes look great, are you still working on it or can share your branch so I/someone else can contribute?

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] commented 1 year ago

This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

github-actions[bot] commented 1 year ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.