Jest cannot find tests when tests are located under `node_modules` directory - javascript

After I performed refactoring on my project, I found that Jest could not find any test modules. It reported following error.
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
No files found in /home/.../node_modules/.../... /api.
Make sure Jest's configuration does not exclude this directory.
To set up Jest, make sure a package.json file exists.
Jest Documentation: https://jestjs.io/docs/configuration
Pattern: - 0 matches
After I examined a while, I found the smallest reproducible example is following :
node_modules/foo.js
function foo() {
return 'hello';
}
module.exports.foo = foo;
node_modules/foo.test.js
test( 'foo' , ()=>{
console.error( require('./foo.js' ).foo() );
});
And if foo.js and foo.test.js are moved out from node_modules directory, Jest works as normal.
In order to avoid long relative package names, I put all files under node_modules directory. If possible, I don't want to relocate them.
Is there any workaround or, if possible, any permanent proper solution for the issue?
Edited)
Why do you want to put those in node_modules ?
See Document src/node_modules as official solution for absolute imports

This is a known bug and the bug was already fixed.
A quick fix is creating jest.config.js in the root directory of your project tree as following :
const config = {
"testEnvironment": "node",
"testPathIgnorePatterns": [],
"haste": {
"retainAllFiles": true
}
};
module.exports = config;
Or you can add following in the package.json :
"jest": {
"testEnvironment": "node",
"testPathIgnorePatterns": [],
"haste" : {
"retainAllFiles": true
}
}
This answer is a sort of my reminder; hoping this saves a couple of precious hours of my friends.
Jest not running tests in src/node_modules #2145 (Jest)
Enable src/node_modules #1081 (Create React App)
Bug: Unable to run a test from whitelisted "node_modules" #11781
fix: Allow searching for tests in node_modules #11084 (Jest)

Related

Module parse failed: Unexpected token ? Optional chaining not recognised in threejs svgloader.js [duplicate]

Project setup:
Vuejs 3
Webpack 4
Babel
TS
We created the project using vue-cli and add the dependency to the library.
We then imported a project (Vue Currency Input v2.0.0) that uses optional chaining. But we get the following error while executing the serve script:
error in ./node_modules/vue-currency-input/dist/index.esm.js
Module parse failed: Unexpected token (265:36)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| getMinValue() {
| let min = this.toFloat(-Number.MAX_SAFE_INTEGER);
> if (this.options.valueRange?.min !== undefined) {
| min = Math.max(this.options.valueRange?.min, this.toFloat(-Number.MAX_SAFE_INTEGER));
| }
I read that Webpack 4 doesn't support optional chaining by default. So, we added the Babel plugin for optional chaining. This is our babel.config.js file:
module.exports = {
presets: ["#vue/cli-plugin-babel/preset"],
plugins: ["#babel/plugin-proposal-optional-chaining"],
};
(But, if I am correct, this plugin is now enable by default in the babel-preset. So this modification might be useless ^^)
One thing that I don't understand is that we can use optional chaining in the .vue files.
I created a SandBox with all the files: SandBox
How could I solve this error?
I was able to overcome this issue using #babel/plugin-proposal-optional-chaining, but for me the only way I could get Webpack to use the Babel plugin was to shove the babel-loader configuration through the Webpack options in vue.config.js. Here is a minimal vue.config.js:
const path = require('path');
module.exports = {
chainWebpack: config => {
config.module
.rule('supportChaining')
.test(/\.js$/)
.include
.add(path.resolve('node_modules/PROBLEM_MODULE'))
.end()
.use('babel-loader')
.loader('babel-loader')
.tap(options => ({ ...options,
plugins : ['#babel/plugin-proposal-optional-chaining']
}))
.end()
}
};
NB replace "PROBLEM_MODULE" in the above with the module where you have the problem.
Surprisingly I did not need to install #babel/plugin-proposal-optional-chaining with NPM. I did a go/no-go test with an app scaffolded with #vue/cli 4.5.13, in my case without typescript. I imported the NPM module that has been causing my grief (#vime/vue-next 5.0.31 BTW), ran the serve script and got the Unexpected token error on a line containing optional chaining. I then plunked the above vue.config.js into the project root and ran the serve script again, this time with no errors.
My point is it appears this problem can be addressed without polluting one's development environment very much.
The Vue forums are in denial about this problem, claiming Vue 3 supports optional chaining. Apparently not, however, in node modules. A post in this thread by atflick on 2/26/2021 was a big help.
Had same issue with Vue 2 without typescript.
To fix this you need to force babel preset to include optional chaining rule:
presets: [
[
'#vue/cli-plugin-babel/preset',
{
include: ['#babel/plugin-proposal-optional-chaining'],
},
],
],
Can also be achieved by setting old browser target in browserslist config.
Most importantly, you need to add your failing module to transpileDependencies in vue.config.js:
module.exports = {
...
transpileDependencies: ['vue-currency-input],
}
This is required, because babel by default will exclude all node_modules from transpilation (mentioned in vue cli docs), thus no configured plugins will be applied.
I had a similar problem. I'm using nuxt but my .babelrc file looks like the below, and got it working for me.
{
"presets": [
["#babel/preset-env"]
],
"plugins":[
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
],
"env": {
"test": {
"plugins": [
["transform-regenerator", {
"regenerator": true
}],
"#babel/plugin-transform-runtime"
],
"presets": [
["#babel/preset-env", {
"useBuiltIns": false
}]
]
}
}
}
I managed to fix the solution by adding these lines to package.json:
...
"scripts": {
"preinstall": "npx npm-force-resolutions",
...
},
"resolutions": {
"acorn": "8.0.1"
},
...

Jest with tyescript in monorepo doesn't work with dependency out of the root folder

I use Jest with Typescript. I want to create a monorepo.
My folders structure is:
fe
|-app1
|--.jest.config.ts
|--tsconfig.json
|-shared
|--dummyData.ts
I want a unit test from app1 to access some data from shared folder.
fe/app1/demo.spec.ts:
import { someData } from '#shared/dummyData' //<--HERE: the alias is works, but jest can not understand "export" keyword
descrube('demo' () => {
it('demo test', () => {
expect(someData).toBe('DUMMY'));
})
})
fe/shared/dummyData.ts:
export const someData = 'DUMMY';
The problem is that jest throws an error:
Jest encountered an unexpected token
{"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export const someData = 'DUMMY';
^^^^^^
As I understand it cannot parse typescript or es6 modules that were produced by ts and babel.
The thing that it works fine while shared folder is inside app1, but once it's outside (and outside the root folder, i.g '<rootDir>/../shared/$1') it start throwing that error.
Here is my configs:
I described alias in fe/app1/tsconfig.json:
{
...
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"paths": {
"#/*": ["app/src/*"],
"#shared/*": ["shared/*"]
}
}
}
And in fe/app1/.jest.config.ts:
module.exports = {
...
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'^.+\\.(jsx?|tsx?)$': 'ts-jest'
},
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1',
'^#shared/(.*)$': '<rootDir>/../shared/$1',
}
}
Some thoughts:
As I understand I have to tell to jest to apply same parsers (babel, etc) for the code outside of the rootDir.
I guess it's possible to create a tsconfig in the root folder(fe), but I want to launch unit tests from fe/app1 folder...
Maybe it's possible to configure the things with such properties as projects, roots and etc, but I'm out of luck so far.
Okay, I found the solution:
For monorepo it is important to have babel config as a JS file
So, simply rename .babelrc to babel.config.js (in the folder you called jest from, in my case it is fe/app1)
For more info you could check this comment (and maybe this thread)

No tests found on running jest with grunt

I am trying to run my jest with a grunt task but on doing so I get No tests found message in console. Here is the setup for the same:
gruntfile.js snippet :
exec: {
jest: 'node node_modules/jest/bin/jest -u --config="test/unit/jest/jest.conf.json"'
}
jest.conf.json :
{
"testEnvironment": "jsdom",
"setupTestFrameworkScriptFile": "./enzyme.setup.js",
"testResultsProcessor": "jest-teamcity-reporter"
}
enzyme.setup.js :
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15.4';
configure({ adapter: new Adapter() });
Console on running the grunt exec task shows below:
No tests found
In C:\Vishal\UI\Jest-Grunt\proj\test\unit\jest
3 files checked.
testMatch: .js?(x),**/?(*.)(spec|test).js?(x) - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 3 matches
Pattern: - 0 matches
Done, without errors.
However the surprising thing is if I don't pass the jest config file path in cli inside grunt exec task and instead specify the jest configuration in package.json file then it works.
Not sure why this is behaving like this.
Aah, after banging my head around. I noticed that the error is pity straight forward:
In C:\My-User\UI\Jest-Grunt\proj\test\unit\jest
This clearly explains that JEST tries to execute test cases inside folder specified above. But ideally JEST looks into __tests__. Hence I had to specify the roots folder myself. With package json this doesn't occur. Strange though!
Here is my updates jest configuration:
{
"testEnvironment": "jsdom",
"setupTestFrameworkScriptFile": "./enzyme.setup.js",
"testResultsProcessor": "jest-teamcity-reporter",
"coverageReporters": [
"teamcity", "lcov"
],
"roots": [
"../../../__tests__"
]
}

pass variable to webpack to build different bundle

I am trying to build a different bundle based on an argument passed to webpack.
I have a create-react-app that I have ejected from and currently currently if I do npm run build it builds a bundle using webpack. As I have both an english and spanish version of the site I was hoping that I could pass an argument here. i.e. to build a Spanish version something like npm run build:es.
My webpack file currently just builds the English bundle. There is a separate process during the application to pull in translations, but during the building of the bundle it would be great if I could stipulate which language to build the bundle for.
Anyone have any ideas.
The relevant webpack code is below:
//default messages for translations
var defaultMessages = require('/translations/en.json');
//more webpack stuff......
{
test: /\.(js|jsx)$/,
loader: require.resolve('string-replace-loader'),
query: {
multiple: Object.keys(defaultMessages).map(key => ({
search: `__${key}__`,
replace: defaultMessages[key]
}))
}
},
Webpack can receive a --env argument, which is then passed to the webpack.config file. The key is to export a function returning the configuration from your webpack.config.js, not the raw configuration.
$ webpack --env=lang_es
And in webpack.config.js:
module.exports = function(env) {
if (env === 'lang_es') {
// ...
}
return {
module: {
// ...
},
entry: {
// ...
}
}
}
And in package.json:
"scripts": {
"build_es": "webpack --env=lang_es",
}
This was originally really meant to distinguish between build types, e.g. development or production, but it's just a string passed into the config file - you can give it any meaning you want.
As hinted in the comments, using environment variables is the second, webpack-independent, approach. You can set the environment variable directly in package.json's scripts section:
"scripts": {
"build_es": "BUILD_LANG=es webpack",
}
(Use cross-env to set the environment when developing on Windows).
And in webpack.config.js:
if (process.env.BUILD_LANG === 'es') {
// ...
}
This environment-based approach has been used in a few places already (for example Babel's BABEL_ENV variable), so I'd say that it has gathered enough mileage to consider it proven and tested.
Edit: fixed the cross-env part to mention that it's only necessary on Windows.

"No ESLint configuration found" error

Recently, we've upgraded to ESLint 3.0.0 and started to receive the following message running the grunt eslint task:
> $ grunt eslint
Running "eslint:files" (eslint) task
Warning: No ESLint configuration found. Use --force to continue.
Here is the grunt-eslint configuration:
var lintTargets = [
"<%= app.src %>/**/*/!(*test|swfobject)+(.js)",
"test/e2e/**/*/*.js",
"!test/e2e/db/models/*.js"
];
module.exports.tasks = {
eslint: {
files: {
options: {
config: 'eslint.json',
fix: true,
rulesdir: ['eslint_rules']
},
src: lintTargets
}
}
};
What should we do to fix the error?
The error you are facing is because your configuration is not present.
To configure the eslint type
eslint --init
then configure as your requirement.
then execute the project again.
I've had the same error. It seems to need configuration.
Go to your project root & run in terminal
./node_modules/.bin/eslint --init
Try to swap config with configFile. Then :
Create eslint.json file and
Point the right location of it (relative to Gruntfile.js file)
Place some configuration in that file (eslint.json), i.e.:
.
{
"rules": {
"eqeqeq": "off",
"curly": "warn",
"quotes": ["warn", "double"]
}
}
for more examples, go here.
I hade the same problem with Gulp and running "gulp-eslint": "^3.0.1" version.
I had to rename config: to configFile in Gulp task
.pipe(lint({configFile: 'eslint.json'}))
For those having the same problem, this is how we've fixed it.
Following the Requiring Configuration to Run migration procedure, we had to rename eslint.json to .eslintrc.json which is one of the default ESLint config file names now.
We've also removed the config grunt-eslint option.
Create a new file on the root directory called .eslintrc.json file:
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "error"
}
}
Just follow the steps
1.create eslint config file name eslintrc.json
2.place the code as given below
gulp.src(jsFiles)
// eslint() attaches the lint output to the "eslint" property
// of the file object so it can be used by other modules.
.pipe(eslint({configFile: 'eslintrc.json'}))
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failAfterError last.
.pipe(eslint.failAfterError());
Webpack
I had eslint.rc file in my root project directory but event though
I was getting error.
Solution was to add exclude property to "eslint-loader" rule config:
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
// eslint options (if necessary)
}
},
],
},
// ...
}
We faced this problem today and realized, that the issue was not caused inside the project that we were working on, but inside a package that we had a link on using the command:
yarn link
Which is a feature often useful to test out new features or when trying to debug an issue in a package that manifests itself in another project.
We solved it by either removing the link, or in case of ember.js disabling the developer mode of our addon package.
index.js
module.exports = {
isDevelopingAddon: function() {
return false;
},
...
}
gulp.task('eslint',function(){
return gulp.src(['src/*.js'])
.pipe(eslint())
.pipe(eslint.format())
});
`touch .eslintrc` instead of .eslint
these two steps may help you!
Run the command ember init.
When it asks for overwriting the existing file(s). Type n to skipping overwriting the file.
Now it will automatically create required files like .eslintrc, etc.
For me the same issue occurred when i copied my folder except dist, dist_production and node_modules folder to another system and tried running ember build.

Categories