-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
Asset basenames in Jest snapshots #13319
Conversation
04fd23e
to
cb67bc1
Compare
@myrjola I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the mock for snapshots shaped more similar to the actual asset objects.
jest/assetFileTransformer.js
Outdated
// the correct images are loaded for components. So require('img1.png') | ||
// becomes 'img1.png' in the Jest snapshot. | ||
process: (_, filename) => | ||
`module.exports = ${JSON.stringify(path.basename(filename))};` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to mimic what the actual transformer does and return an object.
require('/images/image1.png') will be replaced with 'image1.png' in the snapshot instead of 1 returned by RelativeImageStub. This makes it possible to test conditional asset loading in components.
cb67bc1
to
bee962c
Compare
Rebased the code and addressed the requested changes. I also chose to return relative path instead of basename. Updated the PR description with the latest changes and also added a breaking changes section. |
jest/assetFileTransformer.js
Outdated
`module.exports = ${JSON.stringify(path.basename(filename))};` | ||
`module.exports = {uri: ${JSON.stringify(path.relative('.', filename))}};`, | ||
|
||
getCacheKey: createCacheKeyFunction([__filename]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function was needed after rebasing on latest master. I took some inspiration from https://github.com/facebook/react-native/blob/master/jest/preprocessor.js.
Without it running Jest will give the following error:
FAIL Libraries/Image/__tests__/assetBaseNameInSnapshot.js
● renders assets based on basename
/Users/martin/git/react-native/Libraries/Image/__tests__/img/img1.png:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){module.exports = [object Object];
^^^^^^
SyntaxError: Unexpected identifier
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
at Object.<anonymous> (Libraries/Image/__tests__/assetBaseNameInSnapshot.js:21:64)
at tryCallTwo (node_modules/promise/lib/core.js:45:5)
at doResolve (node_modules/promise/lib/core.js:200:13)
✕ renders assets based on basename (144ms)
0895f74
to
05f41f2
Compare
Attention: @facebook/react-native Generated by 🚫 dangerJS |
jest/assetFileTransformer.js
Outdated
// require('img1.png') becomes `Object { "uri": 'path/to/img1.png' }` in the | ||
// Jest snapshot. | ||
process: (_, filename) => | ||
`module.exports = {uri: ${JSON.stringify(path.relative('.', filename))}};`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "uri" field doesn't actually exist at runtime, maybe call it testUri so it's clear this field is defined only in tests?
@cpojer how does this look to you? |
Renamed uri to testUri in the latest commit and updated description. |
@mjesun mind taking care of this one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, looks nice :)
One minor nit: could we use real images (a 1x1 PNG would be enough). I know it does not change anything from the test PoV, but GH has hard times trying to load the invalid image.
Thanks!
Changed empty PNG files to real PNGs. Now GitHub is happy again. |
@mjesun has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
Sorry for the late reply; we haven't forgot about that, but we had some issues importing the PR :( (unrelated to the PR itself). |
@myrjola Just a small heads up; we adjusted the test so it is able to run on our infra (and potentially anywhere regardless of the exec folder 🙂. Thanks again for the contribution! 😊 |
@@ -7,12 +7,15 @@ | |||
] | |||
}, | |||
"moduleNameMapper": { | |||
"^[./a-zA-Z0-9$_-]+\\.(bmp|gif|jpg|jpeg|png|psd|svg|webp)$": "RelativeImageStub", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing this broke importing files with multiple device resolution variations. Metro bundler will resolve require('./file.png')
to ./file@2x.png
if you're on a 2x screen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reporting! Could you give a bit more detail what the problem is? Apparently this change has broken your tests. Could you give some steps to reproduce?
I immediately notice that the regex ^[./a-zA-Z0-9$_-]+\\.(bmp|gif|jpg|jpeg|png|psd|svg|webp)$
does not match the @
character in ./file@2x.png
. The regex has been moved from moduleNameMapper
to the transform
mapper on line 17 in the same file. Perhaps the change from ./file.png
to ./file@2x.png
happens between the mappers. @oblador, could you edit the regex on line 17 to ^[./a-zA-Z0-9@$_-]+\\.(bmp|gif|jpg|jpeg|png|psd|svg|webp)$
, so that it also matches ./file@2x.png
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also breaks tests completely on Windows for me. Please see #19370 for details
Replace regexp to match on Windows filesystems, replace backslashes with forward slashes in assetFileTransformer.js
This change only affects tests run with Jest.
require('/images/image1.png')
will be replaced within the Jest snapshot instead of always being 1 returned by RelativeImageStub. This change makes it possible to test conditional asset loading in components.
The problem with this change is that it will probably break a lot of existing snapshots, but that should be easily fixed when a project updates to a new version of React Native by running
jest -u
to update all snapshots.Motivation:
A component can have conditional asset loading based on its props, this logic would be nice to test with Jest snapshots. This problem has been discussed in jestjs/jest#2838.
Test Plan:
I have added a snapshot test
assetRelativePathInSnapshot
.It is easy to verify from the snapshot that the change works.
Libraries/Image/tests/snapshots/assetBaseNameInSnapshot.js.snap:
Without the change the output would look like this:
Breaking changes:
Jest snapshots will need to be updated
Image
in Jest snapshotsjest -u
will update the snapshots, the snapshots should be reviewed that they are correct.