Unexpected import token - testing React Native with Jest - react-native

I'm getting a weird import error when I try to test my react-native app with jest. I have babel-jest, babel-preset-react-native, jest, jest-react-native and react-test-render all installed but get this error message when I run npm test.
● Test suite failed to run
/Users/maftalion/www/stars20/kiosk/node_modules/native-base/index.js:4
import Drawer from './Components/vendor/react-native-drawer';
^^^^^^
**SyntaxError: Unexpected token import**
at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:316:10)
at Object.<anonymous> (src/routes/Identification.js:3:17)
at Object.<anonymous> (src/routes/router.js:4:21)
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 1.011s

Figured it out, basically throw any node modules that use es6 syntax in transformIgnorePatterns.
"transformIgnorePatterns": [
"node_modules/(?!react-native|native-base|react-clone-referenced-element)"
],

Try adding transformIgnorePatterns to your package.json:
{
"name": "MyAwesomeApp",
...
"jest": {
"transformIgnorePatterns": ["/node_modules/"]
}
}
For me Jest works out of the box, however:
$ react-native init MyAwesomeApp
$ cd MyAwesomeApp
$ npm test
...
Tests: 2 passed
I'm using React Native v0.37.0.

I found the answers given earlier didn't solve Unexpected token import errors in the tests itself, if they are written in ES6 (like the boilerplate tests created by the Ignite CLI after ignite new MyProject).
I finally managed to remove ES6-related errors by adding to the test task in package.json:
"test": "NODE_ENV=test jest --no-cache"
I am using RN 0.45.1, Node 7.10.1 (and 8.1.2), Yarn 0.24.6 and Jest 20.0.4
PS: Don't always see this in the console, but in VS Code v1.13.1 setting --no-cache makes the difference.

You configured Babel in your webpack config and this will only apply to webpack. When other tools, like Jest, use Babel, they won't see that configuration because they don't look at the webpack config. You can use a .babelrc file to configure Babel and that will apply to anything that runs Babel (not just webpack).
Using a .babelrc is usually preferred as you want to have a general babel config, and if you need to override a setting, you can still do that in the specific application like in the webpack config.
Create the following .babelrc:
{
"presets": ["es2015", "react"]
}
With that, you can remove the presets option in your webpack config because it will use the .babelrc. Note that the [cacheDirectory option][3] is specific to babel-loader and is not used to configure the underlying Babel.
You also have a typo in your test, toMatchSnapShot() should be toMatchSnapshot().
expect(rendered.toJSON()).toMatchSnapshot();

I needed to add .babelrc with:
{
"presets": ["#babel/env","#babel/react"]
}
I also needed to install this module
npm install add --dev react-test-renderer

Related

Vue Jest Aliases Configuration

I have an error when I want to run Jest because of moduleNameMapper settings.
I tried several methods, but nothing changes.
To reproduce:
clone the repo: https://github.com/zoztorun/reproduce-webpack-alias-error
npm install
npm run test
Since you're using Vue CLI, you should use #vue/cli-plugin-unit-jest, which can be added to your Vue CLI project with this command:
vue add unit-jest
This will also add a <rootDir>/test directory with a sample test, but that doesn't fit your project's test file pattern, which places *.spec.js adjacent to the source files.
To adapt the result to your project:
Delete <rootDir>/test (as it would be unused, and because it points to a nonexistent HelloWorld.vue)
Edit the jest config in package.json to be:
{
"jest": {
"preset": "#vue/cli-plugin-unit-jest",
"testMatch": [
"**/src/**/*.spec.[jt]s?(x)"
]
}
}
Delete your test NPM script, since #vue/cli-plugin-unit-jest automatically adds its own test:unit script, which must be used instead (i.e., use npm run test:unit).

Jest Test Fail in React Native

I'm very new to React Native, mobile app development and the whole stack of technologies, so assume I could have done even the most basic thing wrong. I'm trying to set up a simple React Native app but can't get a test to successfully execute.
Steps to reproduce:
Run react-native init MyAwesomeApp
The default app successfully runs in emulator using react-native run-android
Create __tests__ folder
Add basic test myfirst.test.js to folder
const counter = (a) => a + 1;
describe('counter: Should increment the passed value', () => {
expect(counter(1)).toBe(2);
});
Execute tests with npm test.
Output:
> trytest#0.0.1 test /home/xxxxx/MyAwesomeApp
> jest
FAIL __tests__/myfirst.test.js
* Test suite failed to run
Couldn't find preset "module:metro-react-native-babel-preset" relative to directory "/home/xxxxx/MyAwesomeApp"
at node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
at Array.map (<anonymous>)
at OptionManager.resolvePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
at OptionManager.mergePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
at OptionManager.init (node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
at File.initOptions (node_modules/babel-core/lib/transformation/file/index.js:212:65)
at new File (node_modules/babel-core/lib/transformation/file/index.js:135:24)
at Pipeline.transform (node_modules/babel-core/lib/transformation/pipeline.js:46:16)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.161s
Ran all test suites.
npm ERR! Test failed. See above for more details.
After lots of Googling, one thing I have tried which appears to have fixed that particular error is to change the contents of .babelrc from "presets": ["module:metro-react-native-babel-preset"] to "presets": ["react-native"]. The error I now see when executing the tests is:
> trytest#0.0.1 test /home/xxxxx/MyAwesomeApp
> jest
FAIL __tests__/myfirst.test.js
* Test suite failed to run
Cannot find module 'AccessibilityInfo' (While processing preset: "/home/xxxxx/MyAwesomeApp/node_modules/react-native/Libraries/react-native/react-native-implementation.js")
at Object.get AccessibilityInfo [as AccessibilityInfo] (node_modules/react-native/Libraries/react-native/react-native-implementation.js:22:12)
at node_modules/lodash/_baseClone.js:163:23
at arrayEach (node_modules/lodash/_arrayEach.js:15:9)
at baseClone (node_modules/lodash/_baseClone.js:160:3)
at cloneDeepWith (node_modules/lodash/cloneDeepWith.js:37:10)
at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:206:44)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.169s
Ran all test suites.
npm ERR! Test failed. See above for more details.
For me to get this to work for react-native version 0.57.8 I did:
After changing .babelrc to:
{
"presets": ["react-native"]
}
Seem like you need to install babel-preset-react-native. So:
yarn add babel-preset-react-native or npm install babel-preset-react-native.
Unfortunately, we started to have problems with the build when we made this change. So I am guessing there is a better way to solve the problem.
I then looked it to this thread and found this worked for me (without the change to the .babelrc file).
"jest": {
"preset": "react-native",
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
}
}
You should check Jest version in Package.json and update if required

Configure a Create-React-Native-App project to use MobX and use Babel to enable decorators

I've created a project with CRNA and after some considerations I've decided to go with MobX for state management. MobX works best with the decorator syntax (most MobX documentation is written using the decorator syntax) so I wanted to install the Babel plugin enabling the use of decorators.
I've successfully installed MobX (yarn add mobx mobx-react), but after installing the Babel plugin to enable decorators (npm install --save-dev babel-plugin-transform-decorators and adding "transform-decorators" to the plugins section in .babelrc, yarn start stopped working throwing an error about react-native-scripts not being found.
I've then run yarn installand this time it threw an error saying
Error starting packager: TypeError: Invalid Version: undefined
at new SemVer (D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\semver\semver.js:279:11)
at Function.major (D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\semver\semver.js:551:10)
at D:\xdl\src\project\Doctor.js:634:18
at D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\lodash\lodash.js:4944:15
at baseForOwn (D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\lodash\lodash.js:3001:24)
at D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\lodash\lodash.js:4913:18
at Function.forEach (D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\lodash\lodash.js:9359:14)
at D:\xdl\src\project\Doctor.js:624:9
at Generator.throw (<anonymous>)
at step (D:\Projects\ReactNativePlayground\omar\MRKT\node_modules\xdl\build\project\Doctor.js:615:191)
error Command failed with exit code 1.
Does anyone have experience with CRNA and MobX? Any help is much appreciated!
I've solved it. Turns out that running npm install --save-dev babel-plugin-transform-decorators broke something. What I should have been running is yarn add --dev babel-plugin-transform-decorators-legacy and add "transform-decorators-legacy" to .babelrc plugins section. After doing those steps I ran yarn install and it fixed my project.
Additionally, my editor (VSCode) threw warnings about extensions being experimental so I added a jsconfig.json file to the root folder and added the following inside:
{
"compilerOptions": {
"experimentalDecorators": true
},
"exclude": [".expo/*", "node_modules/*"]
}

unable to load 3rd party library to aurelia cli

I'm trying to install jwt-decode to my aurelia cli application. I've npm installed the library and added it to my aurelia.json file:
"dependencies": [
... other deps
{
"name": "jwt-decode",
"path": "../node_modules/jwt-decode/lib",
"main": "index"
}
... other deps
]
When I run au build or au run everything compiles and I can see the the cli is tracing the jwt-decode package; however, when I try to include it in a file I get an error:
src/stores/auth/service.ts(4,24): error TS2307: Cannot find module 'jwt-decode'.
[22:13:04] gulp-notify: [Error running Gulp] Error: src/stores/auth/service.ts(4,24): error TS2307: Cannot find module 'jwt-decode'.
[22:13:04] TypeScript: 1 semantic error
[22:13:04] TypeScript: emit succeeded (with errors)
I've even tried adding it to the prepend property but it did not work. I'm also using typescript so I don't know if that could be causing an issue.
Your dependencies section in aurelia.json is correct.
This error is related to TypeScript: typing definition (.d.ts file) is missing for 'jwt-decode' package.
You can install it by typings install dt~jwt-decode --global --save
After that, import it as a global module: import * as jwt from 'jwt-decode';

How to use Jest with React Native

The testing section of the docs for React Native suggest that Jest is the official way to do unit tests. However, they don't explain how to get it setup. Running Jest without any setup gives syntax errors (with no line numbers :( ) because it doesn't apply the transforms (eg ES6 features, JSX and Flow) that React Native code tends to use. There's a jestSupport folder in the React Native source try that contains a env.js and scriptPrerocess.js, the latter has code for apply the transforms. So I've copied those into my project and added the following section to my package.json:
"jest": {
"scriptPreprocessor": "jestSupport/scriptPreprocess.js",
"setupEnvScriptFile": "jestSupport/env.js"
},
This fixes the first error but I still get the following error:
Using Jest CLI v0.4.0
FAIL js/sync/__tests__/SynchronisedStorage-tests.js
SyntaxError: /Users/tom/my-project/js/sync/__tests__/SynchronisedStorage-tests.js: /Users/tom/my-project/js/sync/SynchronisedStorage.js: /Users/tom/my-project/node_modules/react-native/Libraries/react-native/react-native.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/browser/ui/React.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/utils/ReactChildren.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/addons/ReactFragment.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/classic/element/ReactElement.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/core/ReactContext.js: /Users/tom/my-project/node_modules/react-native/node_modules/react-tools/src/vendor/core/warning.js: Unexpected token .
1 test failed, 0 tests passed (1 total)
Run time: 0.456s
Is there more I need to do to make Jest understand React Native? Are there any examples of Jest setup to test React Native?
EDIT:
There was a check in scriptPreprocess that stopped it from running over any file in node_modules which of course included the whole of React Native. Removing that fixes the error above. However, I'm now getting more errors from the React Native source, it definitely seems like it isn't meant to be run within Jest.
EDIT2:
Explicitly setting the mock for the react-native module works:
jest.setMock('react-native', {});
That seems like it's going to be very manual and not very useful for testing code that interacts with the React Native API a lot. I definitely still feel like I'm missing something!
I got Jest to work for my React Native application, and it is running tests without any problem on files with ES6 and ES7 transforms.
To get Jest to work, I followed these steps:
Copied the jestSupport folder from the React Native master repo to my react-native folder in node_modules.
Edited the "jest" line in my packages.json to points to the files in the jestSupport folder
The "jest" line in my packages.json now looks lke this:
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/react-native/jestSupport/scriptPreprocess.js",
"setupEnvScriptFile": "<rootDir>/node_modules/react-native/jestSupport/env.js",
"testFileExtensions": [
"js"
],
"unmockedModulePathPatterns": [
"source-map"
]
},
As of React Native v0.37.0, Jest is part of the new app template.
In a new app you can run tests right away:
$ react-native init MyAwesomeApp
$ cd MyAwesomeApp
$ npm test
...
Tests: 2 passed
For newer versions of jest, setting it up for react-native is very easy.
Install jest using
npm install --save-dev jest-cli babel-jest
In package.json, add this
"scripts": {
"start": "babel-node ./server/server.js",
"import-data": "babel-node ./scripts/import-data-from-parse.js",
"update-schema": "babel-node ./server/schema/updateSchema.js",
"test": "jest",
"lint": "eslint ."
},
"jest": {
"haste": {
"defaultPlatform": "ios",
"platforms": [
"ios",
"android"
],
"providesModuleNodeModules": [
"react-native"
]
}
},
You might only need to add lines related to jest
Now you can use
npm test
to run jest.
Refer to f8app's github repo to find more about this.