Jest fails with "Unexpected token *" on import statement - javascript

Why does Jest fail with "Unexpected token *" on a simple import statement???
Error log:
Admin#Admin-PC MINGW32 /d/project (master)
$ npm run test
> MyApp#0.0.1 test D:\project
> jest
FAIL __tests__/App-test.tsx
? Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
D:\project\node_modules\react-navigation-tabs\src\navigators\createBottomTabNavigator.js:3
import * as React from 'react';
^
SyntaxError: Unexpected token *
14 | // );
15 |
> 16 | export default createBottomTabNavigator({
| ^
17 | map: {
18 | screen: MapView,
19 | navigationOptions: {
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
at Object.get createBottomTabNavigator [as createBottomTabNavigator] (node_modules/react-navigation-tabs/src/index.js:9:12)
at Object.<anonymous> (src/app/main.view.tsx:16:16)
FAIL src/component/reinput/example/__tests__/index.ios.js (19.352s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
FAIL src/component/reinput/example/__tests__/index.android.js (19.365s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
Test Suites: 3 failed, 3 total
Tests: 2 failed, 2 total
Snapshots: 0 total
Time: 22.774s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! MyApp#0.0.1 test: `jest`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the MyApp#0.0.1 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Admin\AppData\Roaming\Roaming\npm-cache\_logs\2019-04-22T11_52_36_984Z-debug.log
package.json file:
{
"name": "MyApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.4",
"react-native-gesture-handler": "^1.1.0",
"react-native-reanimated": "^1.0.1",
"react-native-splash-screen": "^3.2.0",
"react-navigation": "^3.8.1",
"react-navigation-tabs": "^2.1.1"
},
"devDependencies": {
"#babel/core": "^7.4.3",
"#babel/runtime": "^7.4.3",
"#types/jest": "^24.0.11",
"#types/react": "^16.8.13",
"#types/react-dom": "^16.8.4",
"#types/react-native": "^0.57.46",
"#types/react-test-renderer": "^16.8.1",
"babel-jest": "^24.7.1",
"jest": "^24.7.1",
"metro-react-native-babel-preset": "^0.53.1",
"react-test-renderer": "16.8.3",
"typescript": "^3.4.3"
},
"jest": {
"preset": "react-native"
}
}
babel.config.js file:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
jest.config.js file:
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
Note: I am using react-native type-script template, like react-native init MyApp --template typescript

Some react-native libraries ship uncompiled ES6 code.
ES6 code needs to be compiled before it can be run by Jest.
The Jest doc about Testing React Native Apps includes a section about compiling dependencies that don't ship pre-compiled code.
You will need to tell Jest to compile react-navigation-tabs by whitelisting it in the transformIgnorePatterns option in your Jest config.
Example:
Changing the jest.config.js file into something like below, fixed the issue mentioned in OP.
But the react-native-reanimated module (which requires native integration) needs further work, and we should "Mock" modules with such native requirements (as described in another post).
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transformIgnorePatterns: [
"node_modules/(?!(react-native"
+ "|react-navigation-tabs"
+ "|react-native-splash-screen"
+ "|react-native-screens"
+ "|react-native-reanimated"
+ ")/)",
],
}
Note that the transformIgnorePatterns option (which is an array of Regular-Expressions) is originally meant to exclude files from being compiled, but using (?!(some-dir-name|another-name)) pattern, with the "(?!...)" negative look-ahead, we do tell Jest to exclude anything in node_modules directory, except the names that we did specify.

As it has been said, some modules needs to be transpiled, & some don't.
Here is a regex I use that work in a lot of projects
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|#react-native-community/(.*)|#react-navigation/(.*)|bs-platform|(#[a-zA-Z]+/)?(bs|reason|rescript)-(.*)+)"
]
}
It's working for most common react native thing, & include also a specific package (here bs-platform) as an example, when isn't captured by previous patterns.

I had a similar issue on a React + Typescript app.
The first mistake I made was to define the jest.config.js as jest.config.ts
Running on Node v12.latest
Then the configuration that worked for me were the following:
// jest.config.js
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["./src"],
transform: { "\\.ts$": ["ts-jest"] },
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
globals: {
"ts-jest": {
tsConfig: {
// allow js in typescript
allowJs: true,
},
},
},
};
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "."
},
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
// package.json
"devDependencies": {
"#types/jest": "^26.0.5",
"jest": "^26.1.0",
"ts-jest": "^26.1.3"
}

If you're using not only React Native but also Expo, I fixed the same issue but for Expo components by following the official guide, Testing with Jest. Specifically, install via package manager the jest preset jest-expo, and then update my package.json as they describe:
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|#react-native-community|expo(nent)?|#expo(nent)?/.*|react-navigation|#react-navigation/.*|#unimodules/.*|unimodules|sentry-expo|native-base|#sentry/.*)"
]
}
I also needed to add to the end of the transformIgnorePatterns regexp string an exception for |.*font.* as the Expo Fonts were what were giving me trouble. Probably I could have made it a bit more specific, but I hate regex, and this worked so I left it there!

Somewhere in your config file (.babelrc.js or package.json) you have to have "modules" under "presets" set to one of the "amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false.
referer this fragment from the documentation
something like this:
"presets": [
[
"#babel/preset-env", {
"targets": process.env.BABEL_TARGET === 'node' ? {
"node": 'current'
} : {
"browsers": [ "last 2 versions" ]
},
"loose": true,
"modules": 'commonjs'
}
]
]

I am using react-native-web and the fix for my issue was to add the react-native-web preset to my jest.config.js:
module.exports = {
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
timers: 'fake',
testPathIgnorePatterns: [
'<rootDir>/build/',
'<rootDir>/node_modules/',
'<rootDir>/rndemo/build/',
],
globals: {
'ts-jest': {
diagnostics: {
warnOnly: true,
},
},
},
preset: 'react-native-web',
}

modifying babel.config.js to below worked for me. Also presets should come first and then all other configs.
module.exports = {
presets: [['#babel/preset-env',{targets: {node:
'current',},loose:true,},],],
}

Related

Jest or Mocha with Vue: SyntaxError: Cannot use import statement outside a module

Edit: This post got out of hand with edits, please follow this link to a new Stackoverflow post which is clearer:
SyntaxError: Cannot use import statement outside a module when following vue-test-utils official tutorial
There are thousands of posts and threads about this issue and I still can't fix my problem.
I followed the "Getting started" portions of Jest AND Mocha and get the same error both times:
SyntaxError: Cannot use import statement outside a module but their provided link doesn't help at all.
Theres a new edit at the bottom with steps for a clean new project with jest for you to follow along which results in an error.
"vue-jest": "^3.0.7",
"vue": "^2.6.12",
"#vue/test-utils": "^1.2.2"
package.json
"mocha": "mocha 'tests/Frontend/**/*.test.js'"
example.test.js:
import { mount } from "#vue/test-utils"
import Dashboard from "../../resources/js/views/Dashboard";
import * as assert from "assert";
describe('test example', () => {
it('should work', () => {
assert.equal([1, 2, 3].indexOf(4), -1); // doesn't matter what I do here
})
})
What I've tried:
Using the --require #babel/register flag with mocha
Setting "transformIgnorePatterns": [] and thus allowing all node_modules to be considered
Adding a .babelrc file with the following content: This resulted in following error on building the app though:
Error: Multiple configuration files found. Please remove one:
- package.json
- C:\Users\f.marchi\workspace\projects\sanctum-test\.babelrc
{
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Can someone confirm, that those docs are missing some very important steps? I really don't know what I'm doing wrong, I'm just following the tutorials.
Edit: jest.config.js:
module.exports = {
clearMocks: true,
collectCoverage: true,
coverageDirectory: "coverage",
moduleFileExtensions: [
"js",
"json",
"vue"
],
transform: {
".*\\.(vue)$": "vue-jest"
},
transformIgnorePatterns: []
};
Edit:
I just tried again, you can follow along if you want:
vue create jest-test
npm install --save-dev jest #vue/test-utils vue-jest
Added jest config to package.json:
{
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
".*\\.(vue)$": "vue-jest"
}
}
}
npm install --save-dev babel-jest #babel/core #babel/preset-env babel-core#^7.0.0-bridge.0
Adjusted jest config to:
{
"jest": {
"transform": {
// process `*.js` files with `babel-jest`
".*\\.(js)$": "babel-jest" //<-- changed this
}
}
}
Adjusted babel config to:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset',
'#babel/preset-env' //<-- added this
]
};
You should use vue-cli API.
In your package.json add to scripts this:
"test:unit": "vue-cli-service test:unit"
You have vue-cli and test-utils installed so it should now work.

Node.js says "ReferenceError: require is not defined" when bundling a TypeScript project with Webpack

I have a simple test.ts file which I'd like to bundle using webpack. The file contains some code and the following imports without any error:
import { from, interval, Observable, of, pipe, Subject, timer, BehaviorSubject, zip, EMPTY } from 'rxjs/index.js'
import { filter, map, mergeMap, delay, concatMap, concatMapTo, concatAll, toArray, catchError, retry, retryWhen, delayWhen, tap, take, switchMap, repeat, scan, withLatestFrom, reduce, expand, exhaustMap, mapTo } from 'rxjs/operators/index.js'
import axios from 'axios'
import cheerio from 'cheerio'
import chalk from 'chalk'
This is the content of my package.json file:
{
"name": "myproject",
"version": "0.0.1",
"description": "",
"private": "true",
"type": "module",
"scripts": {
"test": "tsc && node dist/test.js",
"build": "webpack"
},
"author": "",
"license": "ISC",
"dependencies": {
"#types/node": "^14.14.39",
"axios": "^0.21.1",
"chalk": "^4.1.1",
"cheerio": "^1.0.0-rc.6",
"rxjs": "^6.6.7",
"telegraf": "^4.3.0"
},
"devDependencies": {
"webpack": "^5.36.2",
"webpack-cli": "^4.6.0"
}
}
The tsconfig.json file looks like this:
{
"compilerOptions": {
/* Basic Options */
"target": "ES2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"allowJs": true, /* Allow javascript files to be compiled. */
"checkJs": true, /* Report errors in .js files. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
/* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"exclude": ["./dist/**/*"]
}
When compiling the project I get the following message:
Cannot write file 'd:/asant/Desktop/myproject/webpack.config.js' because it would overwrite input file.
And this is the webpack.config.js file:
const path = require('path')
module.exports = {
entry: './src/test.ts',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
When the build script is run it will output:
[webpack-cli] Failed to load 'D:\asant\Desktop\myproject\webpack.config.js' config
[webpack-cli] ReferenceError: require is not defined
at file:///D:/asant/Desktop/myproject/webpack.config.js:1:14
at ModuleJob.run (internal/modules/esm/module_job.js:152:23)
at async Loader.import (internal/modules/esm/loader.js:166:24)
at async loadConfig (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:1346:35)
at async WebpackCLI.resolveConfig (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:1454:38)
at async WebpackCLI.createCompiler (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:1839:22)
at async WebpackCLI.buildCommand (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:1954:20)
at async Command.<anonymous> (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:735:25)
at async Promise.all (index 1)
at async Command.<anonymous> (D:\asant\Desktop\myproject\node_modules\webpack-cli\lib\webpack-cli.js:1284:13)
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! myproject#0.0.1 build: `webpack`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the myproject#0.0.1 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\asant\AppData\Roaming\npm-cache\_logs\2021-05-01T14_28_01_191Z-debug.log
The terminal process "C:\WINDOWS\System32\cmd.exe /d /c npm run build" terminated with exit code: 2.
Also running test will output:
error TS5055: Cannot write file 'D:/asant/Desktop/myproject/webpack.config.js' because it would overwrite input file.
error TS6059: File 'D:/asant/Desktop/myproject/webpack.config.js' is not under 'rootDir' 'D:/asant/Desktop/myproject/src'. 'rootDir' is expected to contain all source files.
The file is in the program because:
Matched by include pattern '**/*' in 'D:/asant/Desktop/myproject/tsconfig.json'
Found 2 errors.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! myproject#0.0.1 test: `tsc && node dist/test.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the myproject#0.0.1 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\asant\AppData\Roaming\npm-cache\_logs\2021-05-01T14_29_07_580Z-debug.log
The terminal process "C:\WINDOWS\System32\cmd.exe /d /c npm run test" terminated with exit code: 1.

Node modules not being parsed correctly for tests?

I'm working in an application and am trying to add a testing framework to automate testing across the app. I'm using Vue, Electron, TypeScript, and Node and am having trouble getting any test that actually uses components to run. For some reason Jest doesn't seem to want to work with the node modules... I have had very little luck finding anything online that points to ways to fix this.
Anyone with any knowledge on the subject who has any pointers or ideas on how to resolve the issue with importing these node modules while running the tests would be greatly appreciated. I can't imagine that this is impossible to do but there really isn't much I can find through my searches.
Error:
$ npm run test
> mdc#1.0.0 test C:\Users\daniel\Desktop\MDC\mdc
> jest --detectOpenHandles
FAIL src/app/features/mdc-window/mdc-window.component.test.ts
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
C:\Users\daniel\Desktop\MDC\mdc\node_modules\bootstrap-vue\es\components\modal\modal.js:3
import bBtn from '../button/button';
^^^^^^
SyntaxError: Unexpected token import
> 1 | import bModal from 'bootstrap-vue/es/components/modal/modal'
| ^
2 | import bTooltip from 'bootstrap-vue/es/components/tooltip/tooltip'
3 | import throttle from 'lodash.throttle'
4 | import Vue from 'vue'
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at Object.<anonymous> (src/app/features/mdc-window/mdc-window.component.ts:1:1)
at Object.<anonymous> (src/app/features/mdc-window/mdc-window.component.test.ts:3:1)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 9.13s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! mdc#1.0.0 test: `jest --detectOpenHandles`
npm ERR! Exit status 1
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
verbose: true,
testPathIgnorePatterns: [
'/build/',
'/config/',
'/data/',
'/dist/',
'/node_modules/',
'/test/',
'/vendor/'
],
globals: {
'ts-jest': {
tsConfig: './src/app/tsconfig.json'
}
}
}
test.ts
import { expect } from 'chai'
import 'jest'
import { MDCWindowComponent } from './mdc-window.component'
const mdcWindowComponent = new MDCWindowComponent()
describe('Test: Set Title Function', () => {
it('should set the variable title to the passed variable', () => {
const title = 'this is a test'
mdcWindowComponent.setTitle(title)
expect(mdcWindowComponent.title).to.equal(title)
})
tsconfig
{
"compilerOptions": {
"allowJs": true,
"outDir": "./built/",
"sourceMap": true,
"strict": true,
"moduleResolution": "node",
"target": "ES2017",
"experimentalDecorators": true,
"noImplicitAny": false,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"esModuleInterop": true,
"lib": ["es2017", "dom"]
},
"include": [
"**/*",
"../types/**/*",
"../../node_modules/bootstrap-vue/**/*",
"../../node_modules/electron/**/*"
]
}
relevant packages
"#types/jest": "^23.3.9",
"jest": "^23.6.0",
"ts-jest": "^23.10.4",
To fix this specific error
SyntaxError: Unexpected token import
I fixed this using the following jest.config.js
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'node',
verbose: true,
moduleDirectories: ['node_modules', 'src'],
modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
moduleFileExtensions: ['js', 'ts', 'json', 'node'],
transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
testPathIgnorePatterns: [
'/build/',
'/config/',
'/data/',
'/dist/',
'/node_modules/',
'/test/',
'/vendor/'
],
globals: {
'ts-jest': {
tsConfig: './src/app/tsconfig.json'
},
NODE_ENV: 'test'
}
}
Note
preset: 'ts-jest/presets/js-with-ts',
transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
this seemingly was what helped fix the issue, though if you compare the jest.config.js in this answer to my response i did add a few other options which may also be helpful for others.
A healthy amount of reading on the ts-jest config documentation, jest config documentation, and tsconfig documentation does wonders.

getting nyc/istanbul coverage report to work with typescript

I'm struggling to get proper coverage with nyc/istanbul for my typescript/mocha/gulp project. I've tried a number of approaches, some of them seem to be unable to use source maps and other fails due to ts-node/tsc errors. My current setup is:
nyc relevant config in package.json
"scripts": {
"test:coverage": "nyc npm run test:unit",
"test:unit": "gulp mocha"
}
"nyc": {
"check-coverage": true,
"all": true,
"extension": [
".js",
".jsx",
".ts",
".tsx"
],
"include": [
"src/**/!(*.test.*).[tj]s?(x)"
],
"reporter": [
"html",
"lcov",
"text",
"text-summary"
],
"report-dir": "docs/reports/coverage"
}
gulpfile.js mocha relevant part
const SRC_DIR = path.join(__dirname, 'src');
const SRC_FILES = path.join(SRC_DIR, '**', '*.[jt]s?(x)');
const TEST_FILES = path.join(SRC_DIR, '**', '*.test.[jt]s?(x)');
const MOCHA_CONFIG = {
src: [
TEST_FILES
],
watchSrc: [
SRC_FILES,
TEST_FILES
],
mocha: {
// compilers: [
// 'ts:ts-node/register',
// 'tsx:ts-node/register'
// ],
require: [
'./tests/setup.js',
'ignore-styles',
'source-map-support/register'
]
}
};
gulp.task('mocha', mocha(MOCHA_CONFIG));
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"rootDir": "./src",
"outDir": "./build",
"allowJs": true,
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "dom"],
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": false,
"experimentalDecorators": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"jsx": "react",
"moduleResolution": "node"
},
"exclude": [
"docs",
"tests",
"**/*.test.js",
"**/*.test.jsx",
"**/*.test.ts",
"**/*.test.tsx",
"tools",
"gulpfile.js",
"node_modules",
"build",
"typings/main",
"typings/main.d.ts"
],
"awesomeTypescriptLoaderOptions": {
"useCache": true,
"useBabel": true
}
}
With the above setup coverage produces results for all the files but they are incorrect for TS files most probably due to source maps not being used (i.e. report shows no coverage for lines which are comments and the numbers seems to be wrong as well).
With a number of variant approaches tried with no success one of the most commonly suggested is to add "require": ["ts-node/register"] to nyc configuration yet then I'm getting errors complaining about i.e. gulpfile.js, docs/reports/coverage/lcov-report/prettify.js and number of other JS files to be not under 'rootDir' which is correct yet it is not clear why ts-node tries to process all the files out of src even if they are excluded in tsconfig.json (still the configuration gets really complex).
I'll appreciate any suggestion which way to go to get proper coverage report for TS files.
Recently I found a satisfiable solution by using "target": "es6" instead of es5 in tsconfig.json's compilerOptions. While changing target directly in tsconfig.json may not be an option as it affects build, the other tip is to use TS_NODE_COMPILER_OPTIONS='{"target":"es6"} which can be added directly in package.json scripts as i.e. :
"test:coverage": "TS_NODE_COMPILER_OPTIONS='{\"target\":\"es6\"}' nyc npm run test:unit",
where test:unit is whatever way being used to run actual tests (in my case just gulp mocha.
NOTE: I've also updated nyc to latest 11.1.0 and ts-node to 3.3.0 as suggested on https://github.com/istanbuljs/nyc/issues/618 thread
I'm not sure this is the same problem but I'll put this here in case it helps future developers...
I wasn't getting any coverage data until I added exclude-after-remap=false to the nyc section of my package.json.
This is listed in the documentation but not in a very prominent way (IMO).
Since a lot of changes broke old working setups I created a verbose example project covering typescript + mocha + nyc supporting proper coverage also for non called files (this is often not included in examples) as well as some unit test examples and quality checks using latest versions.
I had several issues whilst going to mocha 8+ nyc 15+. Maybe it also helps someone else stumbling across it.
https://github.com/Flowkap/typescript-node-template
If you're only interested in coverage check the .ncyrc.yml and mocharc.yml as well as the call config in package.json. VsCode launch configs also included:
.nycrc.yml
extends: "#istanbuljs/nyc-config-typescript"
reporter:
- html
- lcovonly
- clover
# those 2 are for commandline outputs
- text
- text-summary
report-dir: coverage
.mocharc.yml
require:
- ts-node/register
- source-map-support/register
recursive: true
color: true
exit: true
extension:
- ts
- test.ts
test job in package.json
"test": "npm run lint && nyc mocha src test",

How to use ESLint with Jest

I'm attempting to use the ESLint linter with the Jest testing framework.
Jest tests run with some globals like jest, which I'll need to tell the linter about; but the tricky thing is the directory structure, with Jest the tests are embedded with the source code in __tests__ folders, so the directory structure looks something like:
src
foo
foo.js
__tests__
fooTest.js
bar
bar.js
__tests__
barTest.js
Normally, I'd have all my tests under a single dir, and I could just add an .eslintrc file there to add the globals... but I certainly don't want to add a .eslintrc file to every single __test__ dir.
For now, I've just added the test globals to the global .eslintrc file, but since that means I could now reference jest in non-testing code, that doesn't seem like the "right" solution.
Is there a way to get eslint to apply rules based on some pattern based on the directory name, or something like that?
The docs show you are now able to add:
"env": {
"jest/globals": true
}
To your .eslintrc which will add all the jest related things to your environment, eliminating the linter errors/warnings.
You may need to include plugins: ["jest"] to your esconfig, and add the eslint-plugin-jest plugin if it still isn't working.
ESLint supports this as of version >= 4:
/*
.eslintrc.js
*/
const ERROR = 2;
const WARN = 1;
module.exports = {
extends: "eslint:recommended",
env: {
es6: true
},
overrides: [
{
files: [
"**/*.test.js"
],
env: {
jest: true // now **/*.test.js files' env has both es6 *and* jest
},
// Can't extend in overrides: https://github.com/eslint/eslint/issues/8813
// "extends": ["plugin:jest/recommended"]
plugins: ["jest"],
rules: {
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error"
}
}
],
};
Here is a workaround (from another answer on here, vote it up!) for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
You can also set the test env in your test file as follows:
/* eslint-env jest */
describe(() => {
/* ... */
})
To complete Zachary's answer, here is a workaround for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
As of 2021, I think the correct way or at least the one that works is to install #types/jest and eslint-plugin-jest:
npm i -D eslint-plugin-jest #types/jest
And adding the Jest plugin into .eslintrc.js with the overrides instruction mentioned by #Loren:
module.exports = {
...
plugins: ["jest"],
...
overrides: [
{
files: ["**/*.test.js"],
env: { "jest/globals": true },
plugins: ["jest"],
extends: ["plugin:jest/recommended"],
},
],
...
};
This way you get linting errors in your source files as well as in test files, but in test files you don't get linting errors for test and other Jest's functions, but you will get them in your source files as they will appear as undefined there.
I solved the problem REF
Run
# For Yarn
yarn add eslint-plugin-jest -D
# For NPM
npm i eslint-plugin-jest -D
And then add in your .eslintrc file
{
"extends": ["airbnb","plugin:jest/recommended"],
}
some of the answers assume you have eslint-plugin-jest installed, however without needing to do that, you can simply do this in your .eslintrc file, add:
"globals": {
"jest": true,
}
First install eslint-plugin-jest
Running:
yarn add eslint-plugin-jest or npm install eslint-plugin-jest
Then edit .eslintrc.json
{
"env":{
"jest": true
}
}
As of ESLint V 6 (released in late 2019), you can use extends in the glob based config as follows:
"overrides": [
{
"files": ["*.test.js"],
"env": {
"jest": true
},
"plugins": ["jest"],
"extends": ["plugin:jest/recommended"]
}
]
Add environment only for __tests__ folder
You could add a .eslintrc.yml file in your __tests__ folders, that extends you basic configuration:
extends: <relative_path to .eslintrc>
env:
jest: true
If you have only one __tests__folder, this solution is the best since it scope jest environment only where it is needed.
Dealing with many test folders
If you have more test folders (OPs case), I'd still suggest to add those files. And if you have tons of those folders can add them with a simple zsh script:
#!/usr/bin/env zsh
for folder in **/__tests__/ ;do
count=$(($(tr -cd '/' <<< $folder | wc -c)))
echo $folder : $count
cat <<EOF > $folder.eslintrc.yml
extends: $(printf '../%.0s' {1..$count}).eslintrc
env:
jest: true
EOF
done
This script will look for __tests__ folders and add a .eslintrc.yml file with to configuration shown above. This script has to be launched within the folder containing your parent .eslintrc.
Pattern based configs are scheduled for 2.0.0 release of ESLint. For now, however, you will have to create two separate tasks (as mentioned in the comments). One for tests and one for the rest of the code and run both of them, while providing different .eslintrc files.
P.S. There's a jest environment coming in the next release of ESLint, it will register all of the necessary globals.
I got it running after spending some time trying out different options. Hope this helps anyone else getting stuck.
.eslintrc.json (in root project folder):
{
"env": {
"browser": true,
"es2021": true,
"jest/globals": true
},
"extends": [
"standard",
"plugin:jest/all"
],
"parser": "#babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"jest/no-hooks": [
"error",
{
"allow": [
"afterEach",
"beforeEach"
]
}
]
},
"plugins": [
"jest"
]
}
Empty .babelrc (in root project folder):
{}
.package.json (in root project folder):
{
"scripts": {
"test": "jest",
"lint": "npx eslint --format=table .",
"lintfix": "npx eslint --fix ."
},
"devDependencies": {
"#babel/core": "^7.15.0",
"#babel/eslint-parser": "^7.15.0",
"aws-sdk-mock": "^5.2.1",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.24.0",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"jest": "^27.0.6"
}
}
VS Code settings.xml (editor configuration: enables auto fix on save + babel parser):
"eslint.alwaysShowStatus": true,
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"eslint.options": {
"parser": "#babel/eslint-parser"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript"
]
In your .eslintignore file add the following value:
**/__tests__/
This should ignore all instances of the __tests__ directory and their children.

Categories