Skip to content
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

Jest fails with "SyntaxError: Unexpected reserved word" everytime #256

Closed
half-shell opened this issue Feb 9, 2017 · 24 comments
Closed

Comments

@half-shell
Copy link

Hello,
I'm working with react-native and when I run the basic index.android.js test file, it systematically fails with the following:

SyntaxError: Unexpected reserved word
      
  at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:320:12)
  at Object.StackNavigator (node_modules/react-navigation/src/react-navigation.js:15:33)
  at Object.<anonymous> (src/appNavigator.js:13:37)

It looks like I'm doing something wrong, but I can't figure out what. I've tried fiddling around with it (mostly changing variables name), but I keep getting the same error.

The application works though, it doesn't show any error. It is the simpliest navigation app I could make, following the react-navigation doc, using redux.
I was wondering if this happened to anyone else, or if anyone has a clue of the dumb mistake I made.

@grabbou
Copy link

grabbou commented Feb 9, 2017

cc: @ferrannp

@ferrannp
Copy link

ferrannp commented Feb 9, 2017

You need to use transformIgnorePatterns, see from the docs:

The transformIgnorePatterns option can be used to whitelist or blacklist files from being transformed with babel. Many react-native npm modules unfortunately don't pre-compile their source code before publishing.

By default the jest-react-native preset only processes the project's own source files and react-native. If you have npm dependencies that have to be transformed you can customize this configuration option by whitelisting modules other than react-native.

So you can add in your package.json:

  "jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-navigation)"
    ]
  }

Unfortunately, it seems that we will still have an error related to PlatformHelpers.native.js:

 Invariant Violation: Native module cannot be null.
      at invariant (node_modules/fbjs/lib/invariant.js:44:15)
      at Linking.NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:32:1)
      at new Linking (node_modules/react-native/Libraries/Linking/Linking.js:119:141)
      at Object.<anonymous> (node_modules/react-native/Libraries/Linking/Linking.js:191:16)
      at Object.Linking (node_modules/react-native/Libraries/react-native/react-native.js:91:22)
      at Object.<anonymous> (node_modules/react-navigation/src/PlatformHelpers.native.js:10:21)

So this is basically something we will need to look at.

@grabbou
Copy link

grabbou commented Feb 9, 2017

CC: @satya164 in terms of the latter. If that fixes the issue, maybe we should document it? I am afraid people get into troubles when trying to run basic test cases.

@ferrannp
Copy link

ferrannp commented Feb 9, 2017

After transformIgnorePatterns, I can confirm the issue is with Jest importing PlatformHelpers.native.js instead of PlatformHelpers.js.

@half-shell
Copy link
Author

@grabbou @ferrannp thanks guys, I guess I missed that line in the doc. I'll be glad to help improve the documentation, and not only on that particular issue.
I'll try to send a PR soon to "fix" the areas that seem blurry to me in the docs (since I'm pretty new to the whole react / redux / react-native ecosystem).

@grabbou
Copy link

grabbou commented Feb 9, 2017

Sounds really good, thank you! I am happy that we were able to help! I am flagging that one with docs - feel free to close it with a PR fixing the issue :)

half-shell added a commit to half-shell/react-navigation that referenced this issue Feb 14, 2017
@matthamil
Copy link
Member

matthamil commented Feb 15, 2017

@ferrannp Is there any way to force Jest to import PlatformHelpers.js instead of PlatformHelpers.native.js? I get the same Invariant Violation: Native module cannot be null.:

  ● Test suite failed to run

    Invariant Violation: Native module cannot be null.
      
      at invariant (node_modules/fbjs/lib/invariant.js:44:15)
      at Linking.NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:32:1)
      at new Linking (node_modules/react-native/Libraries/Linking/Linking.js:119:141)
      at Object.<anonymous> (node_modules/react-native/Libraries/Linking/Linking.js:191:16)
      at Object.get Linking [as Linking] (node_modules/react-native/Libraries/react-native/react-native.js:91:22)
      at Object.<anonymous> (node_modules/react-navigation/src/PlatformHelpers.native.js:10:21)

This happens after making the changes to my Jest configuration that @half-shell recommended.

@ferrannp
Copy link

@matthamil I think that for now, in your app you can mock that PlatformHelpers.native.js and implement a manual mock (a copy of PlatformHelpers.js).

@matthamil
Copy link
Member

@ferrannp Sorry, I don't think I understand exactly what you mean by mocking and implementing a manual mock?

@lbonanni
Copy link

lbonanni commented Feb 17, 2017

Thanks @ferrannp ! But, after changing my package.json, a new error has showing up :

SyntaxError: Unexpected token ) at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:316:10) at Object.<anonymous> (node_modules/react-native/Libraries/CustomComponents/ListView/ListView.js:44:28)

In fact, it misses react-clone-referenced-element that we can find in jest-preset.json.

So we need to add this in the package.json :
"transformIgnorePatterns": [ "<rootDir>/node_modules/(?!(jest-)?react-native|react-navigation|react-clone-referenced-element)" ],

Now it works for me :)

@tugorez
Copy link

tugorez commented Mar 4, 2017

Hi guys, I managed all this test-concerns (with jest)

using this in my package.json

{
   .
   .
   .
  "jest": {                                                                      
    "preset": "react-native",                                                    
    "setupFiles": ["<rootDir>/jest/setup.js"],                                   
    "transformIgnorePatterns": [                                                 
      "node_modules/(?!(jest-)?react-native|react-navigation)"                   
    ]                                                                            
  },
  .
  .
  .                                                                              
}  

and this mock in /jest/setup.js

jest.mock('Linking', () => ({                                                    
  addEventListener: jest.fn(),                                                   
  removeEventListener: jest.fn(),                                                
  openURL: jest.fn(),                                                            
  canOpenURL: jest.fn(),                                                         
  getInitialURL: jest.fn(),                                                      
})); 

an this in my .flowconfig (in case you're using flow too)

[ignore] 

.
.
.
; react-navigation isn't compatible with the newest flow version, ignore it         
.*/node_modules/react-navigation*
.
.
.                                                     
 

I'm using
React Native 0.42
React 15.4.1
Jest 19.0.0

Based on

  1. Jest fails with "SyntaxError: Unexpected reserved word" everytime #256
  2. Jest React Native - Invariant Violation: Native module cannot be null. jestjs/jest#2208
  3. Flow errors expo/ex-navigation#87

@alvaromb
Copy link

I've fixed the Linking mock, the one provided above fails when testing because some functions return a promise.

jest.mock('Linking', () => ({
  addEventListener: jest.fn(),
  removeEventListener: jest.fn(),
  openURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
  canOpenURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
  getInitialURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
}))

@ferrannp
Copy link

I think these should go into the react-native repo, probably in here https://github.com/facebook/react-native/blob/master/jest/setup.js.

@alvaromb
Copy link

Thanks @ferrannp!

I was sure that should go to the RN repo, but I couldn't find exactly where. Will send a PR.

@AlanFoster
Copy link

AlanFoster commented Apr 3, 2017

For anyone visiting this in the future you can place @alvaromb's snippet into a file jest/setup.js, and ensure you've updated your package.json with something similar to:

  "jest": {
    "preset": "react-native",
    "verbose": true,
    "setupFiles": [
      "./jest/setup.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-navigation)"
    ],
    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[@./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
    }
  }

That fixes the error Invariant Violation: Native module cannot be null.

Although I currently have unrelated issues now:

  ● renders correctly

    TypeError: _this._scrollView.scrollTo is not a function

      at TabViewPagerScroll._this._scrollTo (node_modules/react-native-tab-view/src/TabViewPagerScroll.js:68:19)
      at TabViewPagerScroll.componentDidMount (node_modules/react-native-tab-view/src/TabViewPagerScroll.js:123:197)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
      at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
      at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
      at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)

Edit: Cross-referencing the issue which reports the above stack trace and has a pull request up for it facebook/react-native#13034 👍

ericvicenti pushed a commit that referenced this issue Apr 4, 2017
* add jest config for react-navigation in docs (#256)

* Docs: Update redux-integration guide #246
lintonye added a commit to lintonye/react-navigation that referenced this issue Apr 4, 2017
* master:
  add jest config for react-navigation in docs (react-navigation#256) (react-navigation#331)
@grabbou
Copy link

grabbou commented Apr 23, 2017

Closed in e8726c1

@Maxime-Antoine
Copy link

Hi,

Unfortunately, I still get this issue:

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.

  at invariant (node_modules/fbjs/lib/invariant.js:44:15)
  at createFiberFromElementType (node_modules/react-test-renderer/lib/ReactFiber.js:247:54)
  at Object.<anonymous>.exports.createFiberFromElement (node_modules/react-test-renderer/lib/ReactFiber.js:192:15)
  at reconcileSingleElement (node_modules/react-test-renderer/lib/ReactChildFiber.js:882:19)
  at reconcileChildFibers (node_modules/react-test-renderer/lib/ReactChildFiber.js:992:37)
  at reconcileChildrenAtPriority (node_modules/react-test-renderer/lib/ReactFiberBeginWork.js:130:30)
  at reconcileChildren (node_modules/react-test-renderer/lib/ReactFiberBeginWork.js:108:5)
  at updateHostRoot (node_modules/react-test-renderer/lib/ReactFiberBeginWork.js:287:7)
  at beginWork (node_modules/react-test-renderer/lib/ReactFiberBeginWork.js:645:16)
  at performUnitOfWork (node_modules/react-test-renderer/lib/ReactFiberScheduler.js:634:16)

With:

package.json

"dependencies": {
     "react": "16.0.0-alpha.6",
        "react-native": "^0.44.0",
        "react-navigation": "1.0.0-beta.11"
   },
   "devDependencies": {
     "babel-jest": "^20.0.3",
     "babel-preset-react-native": "^1.9.2",
     "jest": "^20.0.4",
     "react-test-renderer": "^16.0.0-alpha.6"
   },
   "jest": {
     "preset": "react-native",
     "verbose": true,
     "setupFiles": [
       "./jest-setup.js"
     ],
     "transformIgnorePatterns": [
       "node_modules/(?!(jest-)?react-native|react-navigation)"
     ]
   }, 

.flowconfig

 [ignore]
 ; react-navigation isn't compatible with the newest flow version, ignore it         
 .\*/node_modules/react-navigation\* 

jest-setup.js

 jest.mock('Linking', () => ({
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    openURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
    canOpenURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
    getInitialURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
 }))

Is there something I'm missing ?

@KevKo1990
Copy link

I have the same failure as @Maxime-Antoine , I changed the jest import in package.json as described here: https://github.com/react-community/react-navigation/blob/master/docs/guides/Redux-Integration.md#mocking-tests

Snapshots are not possible... my error message:


    console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
      Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

  ● renders correctly

    Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
      
      at invariant (node_modules/fbjs/lib/invariant.js:44:15)
      at ReactCompositeComponentWrapper.instantiateReactComponent [as _instantiateReactComponent] (node_modules/react-test-renderer/lib/instantiateReactComponent.js:77:56)
      at ReactCompositeComponentWrapper.performInitialMount (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:367:22)
      at ReactCompositeComponentWrapper.mountComponent (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:258:21)
      at Object.mountComponent (node_modules/react-test-renderer/lib/ReactReconciler.js:46:35)
      at mountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:55:31)
      at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20)
      at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactDefaultBatchingStrategy.js:62:26)

@KevKo1990
Copy link

@grabbou you have any idea, why it is not working?

@KevKo1990
Copy link

@Maxime-Antoine Could you solve it?

@Maxime-Antoine
Copy link

@KevKo1990 no, not yet

@KevKo1990
Copy link

@grabbou do you need anything else for investigating?

@niom
Copy link

niom commented Oct 17, 2017

@KevKo1990 @Maxime-Antoine If you didn't get this fixed. I faced the same issue and I had a stupid user error in my test configuration.

//index.android.js

import React from 'react'
import { AppRegistry } from 'react-native'
import App from './app/App'

AppRegistry.registerComponent('AwesomeApp', () => App);
//__tests__/AppTest.js
import 'react-native';
import React from 'react';
import App from '../index.android';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
jest.mock('react-native-camera', () => require.requireActual('../__mocks__/react-native-camera').default)

it('renders correctly', () => {
  const tree = renderer.create(
    <App />
  );
});

This configuration made the test fail with Exception:

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. 

Reason was that I was trying to test the AppRegistry file instead of the actual component

so with the correct test:

//__tests__/AppTest.js
import 'react-native';
import React from 'react';
import App from '../app/App'; //<- Correct component

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
jest.mock('react-native-camera', () => require.requireActual('../__mocks__/react-native-camera').default)

it('renders correctly', () => {
  const tree = renderer.create(
    <App />
  );
});

Hope that you got your problem solved.

@miticous
Copy link

miticous commented Jul 8, 2020

After a lot of tries (yes, I've tried everything listed before this comment) I solved this problem by create a manual mock for NavigationService.js. Just follow this question on stackoverflow

https://stackoverflow.com/questions/55319581/why-isn%C2%B4t-mock-from-mock-folder-invoked-when-running-test-for-redux-action

You're welcome

joshuapinter pushed a commit to cntral/react-navigation that referenced this issue Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests