@angular-builders/jest - Default moduleNameMapper config makes override hard
Describe the Bug
When using @angular-builders/jest and a custom jest config, the default config leads to unexpected behaviours when one is specifying a moduleNameMapper or transform config for image assets. Since jest will apply the first module name mapper it finds that matches, due to the fact that one exists in the default config means it might get picked up before one specified in a custom config. It is also problematic in the case that one tries to specify a transform option instead of a moduleNameMapper for more advanced handling, since it seems jest only applies the transform if it cannot find any moduleNameMapper match. This effectively means it is impossible to apply transforms for jpg and png atm.
In my particular case, I need to mock imported png's, jpeg's and other assets with their file name. This is describe in the Jest documentation to be achiveable via the transform parameter. However, not matter what I did to my config, my transform never seemed to be applied for jpg and png. Switching to moduleNameMapper instead did not change things for jpg and png files.
Minimal Reproduction
Just setup a new Angular project @angular-builder/jest as test runner and specify a moduleNameMapper config in jest.config.js where the regex key is slightly different from the default one. Should be easy to see even without a repro repo why this is a problem and what is causing it. The regex key used is "\\.(jpg|jpg|png|gif|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$", picked straight from this section in the jest documentation (never mind it's about css-modules, I'm not using them, just the transform for assets described there). Here's the transform function I use, which works fine for e.g. svg files:
const path = require('path');
module.exports = {
process(_src, filename, _config, _options) {
return 'module.exports = { default: ' + JSON.stringify(path.basename(filename)) + ' };';
},
};
Expected Behavior
The default config should not take precedence over the custom config. In this case, the default config leads to an unexpected case of custom config partially applying, which is hard to debug and understand. I also expect to be able to apply custom transforms to jpg and png assets.
Possible solution
If possible, remove moduleNameMapper from default config to make transform custom config of jpg and png's possible out of the box.
Workarounds
If one want to use a custom moduleNameMapper for jpg and png, you can duplicate the exact key in the default jest config and replace the value with whatever you need. Have not found any way to apply transforms to jpg and png however.
Hey @Naycon , I understand the problem but could you please provide a minimal reproduction repo so that I could investigate?
@just-jeb I think this should do it: https://github.com/Naycon/repro-angular-builders-jest-config-issue
The readme in that repo summaries what's going on, what's expected and how to reproduce it.
This is a jest-preset-angular bug. https://github.com/thymikee/jest-preset-angular/issues/908
@mshima Although they fixed it in jest-preset-angular (the fix was to remove the moduleNameMapper from the preset completely) the problem will still persist in the builder because the builder adds moduleNameMapper of its own.
@Naycon The main target of this builder is to provide a zero setup ng test with jest, so removing the moduleNameMapper completely is not a great solution in my opinion.
However I understand your struggle and I agree that a custom config should take precedence.
A possible solution is adding a check for moduleNameMapper property here and replacing it. This way your moduleNameMapper object (even if it's empty) will replace the default one and in general follow the priority described in the docs.
The only problem is that it might break stuff to those who already specify moduleNameMapper in their custom config. On the other hand, I don't see why one would do that today since it's practically useless.
WDYT?