-
-
Notifications
You must be signed in to change notification settings - Fork 147
Description
There is an issue with diff output from jest when changes are found in snapshots. Specifically, it will show extraneous diffs in lines that have no changes:
.c0 > span {
- margin-left: 0;
- margin-right: 0;
+ margin-left: 0;
+ margin-right: 0;
}The detection of changes itself is not flawed. This diff issue only happens when legitimate changes are detected elsewhere in the snapshot. The issue resides in the logic printing the changes.
Another CSS-in-JS library, emotion, and its jest library, @emotion/jest, had a very similar issue with diff output. It was identified in emotion-js/emotion#1847 and resolved with a serializer overhaul in emotion-js/emotion#1850 .
The root cause of the issue starts with some behavior introduced with Jest v25. Prior to Jest v25, snapshot diffs printed to stdout were sensitive to indentation, but a pull request made it insensitive to indentation like so: 
However, this new diff logic requires that snapshot serializers respect the indentation config in order for it to work properly. Older serializers that don't take the indentation config into account can get false positives on changed lines (like the diff I shared above). There is actually a fallback in the jest-snapshot logic to account for this, but in the case of jest-styled-components and presumably @emotion/jest, there is a mixture of compliant serializers and non-compliant serializers called to produce the output, which results in the fallback failing to work correctly.
The fix for this issue must be made in the logic provided by jest-styled-components.
First, the serializer must be updated from the old plugin style ({ test(){}, print(){} }) to the new plugin style ({ test(){}, serialize(){} }), in order to receive indentation configuration in the arguments. This may lose support for very old versions of Jest (I have confirmed at least jest >= 22.0.0 would be fine), so it might need to be considered a breaking change if the jest version is not enforced somewhere (I didn't see it in peerDependencies). Following that change, we have two options to fix the diff issue:
-
Respect the indentation configuration provided by jest. This is made difficult by the dependency on the
csslibrary for the serialization of style rules. That library has yet-unfixed bug in that indentation set as an empty string is ignored. -
Modify the indentation config being passed on by the serializer in jest-styled-components such that all serializers it calls are equally ignorant to indentation configuration, helping the fallback in jest-snapshot be triggered. This would allow us to fix the issue just with changes in this library, but it has the potential to change users' existing snapshots if they were using custom indentation before, and therefore might be considered a breaking change.