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

Can't run jest tests with 0.56.0 #19859

Open
adamivancza opened this Issue Jun 23, 2018 · 38 comments

Comments

Projects
None yet
@adamivancza

adamivancza commented Jun 23, 2018

Environment

React Native Environment Info:
System:
OS: macOS High Sierra 10.13.4
CPU: x64 Intel(R) Core(TM) i7-3740QM CPU @ 2.70GHz
Memory: 27.74 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 8.9.0 - /usr/local/bin/node
npm: 6.1.0 - /usr/local/bin/npm
Watchman: 4.5.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
Android SDK:
Build Tools: 23.0.1, 23.0.2, 23.0.3, 24.0.2, 25.0.0, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 27.0.0, 27.0.3
API Levels: 19, 22, 23, 24, 25, 26, 27
IDEs:
Android Studio: 2.2 AI-145.3360264
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.3.2 => 16.3.2
react-native: 0.56.0-rc.2 => 0.56.0-rc.2
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7

Description

My jest tests are broken - it displays this error for each test file:
Plugin 0 specified in "project/node_modules/babel-preset-react-native/index.js" provided an invalid property of "default" (While processing preset: "project/node_modules/babel-preset-react-native/index.js")

at Plugin.init (node_modules/babel-core/lib/transformation/plugin.js:131:13)
at Function.normalisePlugin (node_modules/babel-core/lib/transformation/file/options/option-manager.js:152:12)
at node_modules/babel-core/lib/transformation/file/options/option-manager.js:184:30
at Array.map ()
at Function.normalisePlugins (node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
at node_modules/babel-core/lib/transformation/file/options/option-manager.js:265:14
at node_modules/babel-core/lib/transformation/file/options/option-manager.js:323:22
at Array.map ()
at OptionManager.resolvePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)

these tests worked perfectly fine with 0.53.3

my .babelrc file:
{
"presets": ["react-native"]
}

my jest version is "23.1.0"

@vovkasm

This comment has been minimized.

Contributor

vovkasm commented Jun 23, 2018

I experienced the same problem. And for pure js projects it can be resolved by force all bebel 7 deps to be at top level node_modules directory (probably). Specifically, I added these deps to devDependencies of my package.json:

   "@babel/core": "^7.0.0-beta",
   "babel-core": "^7.0.0-beta",
   "babel-preset-react-native": "5.0.2",

But for typescript projects I'am still wait for ts-jest update or to have time to return to custom ts transformations. (another option would be to use babel's typescript support, but this support is somewhat weaken, so not for me)

@kelset kelset added the 🔧Tooling label Jun 25, 2018

@adamivancza

This comment has been minimized.

adamivancza commented Jun 25, 2018

thx for your suggestions @vovkasm - that's indeed fixed our test problems. FYI I've used these in my package.json:
"@babel/core": "^7.0.0-beta.51", "babel-core": "^7.0.0-beta.51", "babel-preset-react-native": "5.0.2",

and I also had to delete my node_modules folder prior installation as that prevented some updates.

nope - this doesn't work either. I got this error now:

babel-plugin-jest-hoist: The module factory ofjest.mock()is not allowed to reference any out-of-scope variables. Invalid variable access: MockNativeMethods Whitelisted objects: Array, ArrayBuffer, Boolean, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, Generator, GeneratorFunction, Infinity, Int16Array, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, String, Symbol, SyntaxError, TypeError, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, arguments, console, expect, isNaN, jest, parseFloat, parseInt, require, undefined, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE, global, process, Buffer, clearImmediate, clearInterval, clearTimeout, setImmediate, setInterval, setTimeout. Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed withmock are permitted.

@timwangdev

This comment has been minimized.

Collaborator

timwangdev commented Jun 25, 2018

Fixed in facebook/jest#6505
Please use jest@^23.2.0

@timwangdev timwangdev added the Fixed label Jun 25, 2018

@hramos

This comment has been minimized.

Contributor

hramos commented Jun 26, 2018

Thanks @timwangdev! I'll close this issue once Jest is updated.

@hramos hramos added the Core Team label Jun 26, 2018

@hramos hramos self-assigned this Jun 26, 2018

@hramos

This comment has been minimized.

Contributor

hramos commented Jun 26, 2018

I'm still working on this. Due to the way the repo is set up internally, we can't simply upgrade Jest in the RN repo, we have to upgrade Jest across all projects.

Still, jest is working fine in CI, which worries me. Can someone add a failing test case to cover this situation? It would 1) ensure the upgrade to 23.2.0 fixes the issue, and 2) prevent this breakage from going unnoticed in the future.

@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jun 27, 2018

Hmm I'm still seeing an issue with this with one of my projects using jest 23.2.0.... I'll see if I can make it happen in the react-native internal tests as well.

@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jun 27, 2018

@hramos what's really interesting in my project, is that going back to babel-preset-react-native version 4 allows jest tests to pass, but breaks packaging of the JS bundle for actually running the app.

@timwangdev timwangdev removed the Fixed label Jun 27, 2018

@timwangdev

This comment has been minimized.

Collaborator

timwangdev commented Jun 27, 2018

The babel issue is still occurs, the jest version only fix babel-plugin-jest-hoist error.

@timwangdev

This comment has been minimized.

Collaborator

timwangdev commented Jun 27, 2018

@hramos I think there is a jest e2e test suit in https://github.com/facebook/react-native/blob/master/scripts/run-ci-e2e-tests.js#L266-L270 to and the job is defined in https://github.com/facebook/react-native/blob/master/.circleci/config.yml#L343-L345 . But it not being used in any of the workflow in CircleCI.

Maybe we should re-enable this?

@adamivancza

This comment has been minimized.

adamivancza commented Jun 27, 2018

thx @timwangdev - using jest@^23.2.0 solved our issue

@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jun 27, 2018

This is still breaking on 0.56.0-rc.4, same error as above:

Plugin 0 specified in "/Users/dlowder/Documents/iosProjects/Salesforce1/Chatter/src/Chatter/SFOReactNativeSDK/S1ReactNative/node_modules/babel-preset-react-native/index.js" provided an invalid property of "default" (While processing preset: "/Users/dlowder/Documents/iosProjects/Salesforce1/Chatter/src/Chatter/SFOReactNativeSDK/S1ReactNative/node_modules/babel-preset-react-native/index.js")

      at Plugin.init (node_modules/babel-core/lib/transformation/plugin.js:131:13)
      at Function.normalisePlugin (node_modules/babel-core/lib/transformation/file/options/option-manager.js:152:12)
.
.
.
@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jun 27, 2018

Hmm.... now I'm making progress.... many tests are passing now after adding the following explicitly to my top level package.json for my project:

+    "@babel/core": "^7.0.0-beta.47",
+    "babel-core": "^7.0.0-beta.47",
+    "babel-jest": "^23.2.0",
+    "babel-plugin-jest-hoist": "^23.2.0",

Still seeing a few 'unexpected token import' errors in tests, but this is definitely progress. @hramos

@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jun 27, 2018

Ok so all the remaining test failures seem to be related to the use of react-test-renderer. Upgrading that to 16.4.1 doesn't seem to help.

markholland added a commit to redbadger/pride-london-app that referenced this issue Jun 29, 2018

@macrozone

This comment has been minimized.

macrozone commented Jul 2, 2018

I also fail to run tests. I get the dreaded SyntaxError: Unexpected token import error on node_modules that contain import statements.

Adding these files to transformIgnorePatterns no longer works. I can remove the option and get the exact same result.

There is tons of issues around, e.g. in facebook/jest#2081, but i could not find a solution.

my .babelrc is failry simple:

{
  "presets": ["react-native"],
  "plugins": ["babel-plugin-styled-components", "babel-plugin-inline-import"],
  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}
@dlowder-salesforce

This comment has been minimized.

Collaborator

dlowder-salesforce commented Jul 3, 2018

@hramos Here's a simple example that should work, but fails with the "Plugin 0 specified.... provided an invalid property of default". Maybe this could be added to CI?

  • react-native init Test56 --version=0.56.0-rc.4
  • cd Test56
  • mkdir __tests__
  • Create a file __tests__/AppTest.js that has the following lines:
import React from 'react';
import renderer from 'react-test-renderer';
import App from '../App';

test('App matches Snapshot', () => {
  const component = renderer.create(<App />);
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});
  • yarn test

With version 0.55.4, yarn test runs fine and the test passes.

Adding more babel dependencies to package.json gets past the above issue, but then hits the "Unexpected token" errors:

{
  "name": "Test56",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.4.1",
    "react-native": "0.56.0-rc.4"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.47",
    "babel-core": "^7.0.0-beta.47",
    "babel-jest": "^23.2.0",
    "babel-plugin-jest-hoist": "^23.2.0",
    "babel-plugin-module-resolver": "^3.1.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-jest": "^23.2.0",
    "babel-preset-react-native": "^5",
    "jest": "23.2.0",
    "jest-react-native": "^18.0.0",
    "react-test-renderer": "16.4.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

I tried adding a Jest test that doesn't use react-test-renderer (just tests some utility functions in a module), and it works fine with the above package.json. So I think the test renderer may either be the problem, or may be helpful in finding the problem.

@hramos

This comment has been minimized.

Contributor

hramos commented Jul 3, 2018

Thanks for looking into it, seems like something we can test in CI.

@kelset

This comment has been minimized.

Collaborator

kelset commented Jul 4, 2018

In our app we had to add this babel-bridge and enforce yarn resolutions in order to make sure that everything worked properly. Have you tried using them? I feel this issue may be related to something not "using" babel7 🤔

@todorone

This comment has been minimized.

todorone commented Jul 5, 2018

@dlowder-salesforce Installing babel-core@7.0.0-bridge.0 did help me

@vovkasm

This comment has been minimized.

Contributor

vovkasm commented Jul 5, 2018

To summarize experience with our projects. It works if:

  1. Babel 7 in deps:
"@babel/core": "^7.0.0-beta",
"babel-core": "7.0.0-bridge.0",
  1. package.json should not contain dependencies, that requires babel6 and can be part of transformation pipeline, for ex:
    2.1 babel-preset-react-native should be "5.0.2"
    2.2 babel-preset-env, should be @babel/preset-env, etc...
    2.3 ts-jest, if used, should be at least 23.0.0

Update after #19859 (comment):

  1. If it doesn't work with jest, use of internal RN preprocessor may help:
    Add to jest config:
    "transform": {
        "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    }
If anyone interested, there is my diff of upgrading one of simple project.
diff --git a/package.json b/package.json
index 60b597d..c78fc29 100644
--- a/package.json
+++ b/package.json
@@ -17,25 +17,27 @@
     "mobx": "^4.3.1",
     "mobx-react": "^5.2.3",
     "mobx-utils": "^5.0.0",
-    "react": "16.3.1",
-    "react-native": "0.55.4",
+    "react": "16.4.1",
+    "react-native": "0.56.0-rc.5",
     "react-native-web-image": "git+https://github.com/vovkasm/react-native-web-image.git#0c34bd076878dfc604d1fd54239c4cd9685c0a4c",
     "tslib": "^1.9.3"
   },
   "devDependencies": {
+    "@babel/core": "^7.0.0-beta",
     "@types/bluebird": "^3.5.20",
     "@types/jest": "^23.0.2",
     "@types/react": "^16.4.4",
     "@types/react-native": "^0.55.21",
     "@types/react-test-renderer": "^16.0.0",
     "@vovkasm/tslint-config": "2.0.1",
+    "babel-core": "7.0.0-bridge.0",
     "babel-jest": "^23.2.0",
-    "babel-preset-react-native": "4.0.0",
+    "babel-preset-react-native": "5.0.2",
     "jest": "^23.2.0",
     "jest-junit": "^5.1.0",
     "prettier": "1.13.7",
     "react-native-typescript-transformer": "^1.2.0",
-    "react-test-renderer": "16.3.1",
+    "react-test-renderer": "16.4.1",
     "ts-jest": "^23.0.0",
     "tslint": "^5.9.1",
     "tslint-plugin-prettier": "^1.3.0",

Then rm -rf node_modules package-lock.json && npm install

@EdwardDrapkin

This comment has been minimized.

EdwardDrapkin commented Jul 5, 2018

Still doesn't work for me if I follow @vovkasm's directions.

My .babelrc
{
    "presets": [
        "react-native"
    ],
    "plugins": [
        [
            "module-resolver",
            {
                "root": [
                    "./src"
                ]
            }
        ]
    ]
}
My babel dependencies (removed everything else for brevity)
    "dependencies": {
        "@babel/cli": "^7.0.0-beta",
        "@babel/core": "^7.0.0-beta",
        "@babel/preset-flow": "^7.0.0-beta",
        "@babel/preset-stage-2": "^7.0.0-beta",
        "@babel/preset-stage-3": "^7.0.0-beta",
        "babel-core": "7.0.0-bridge.0",
        "babel-eslint": "^9.0.0-beta.1",
        "babel-jest": "^23.2.0",
        "babel-plugin-module-resolver": "^3.1.1",
        "babel-preset-react-native": "5.0.2",
        "jest": "23.3.0",
        "react-test-renderer": "16.4.1"
    },
  
And the broken test file...
import React from 'react';
import renderer from 'react-test-renderer';
import { Text } from 'react-native';

class MyComponent extends React.Component {
render() {
return <Text>Hello world.</Text>;
}
}

it('Breaks Jest', () => {
const component = renderer.create();
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

...fails like so:
 FAIL  test/JestBreakage.spec.js
  ● Console
console.error node_modules/fbjs/lib/warning.js:33
  Warning: MyComponent(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.
console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6309
  The above error occurred in the <MyComponent> component:
      in MyComponent

  Consider adding an error boundary to your tree to customize error handling behavior.
  Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

● Breaks Jest

TypeError: instance.render is not a function

  at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5276:31)
  at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5238:10)
  at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5907:14)
  at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7949:12)
  at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7980:24)
  at renderRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8020:7)
  at performWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8592:22)
  at performWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8527:7)
  at performSyncWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8499:3)
  at requestWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8399:5)

@facebook facebook locked as resolved and limited conversation to collaborators Jul 6, 2018

vovkasm added a commit to vovkasm/react-native that referenced this issue Jul 6, 2018

Fix jest-preset to use internal preprocessor instead of plain babel-j…
…est (should fix #19859)

By unknown reason babel-jest can't transform tests and react-native's files, see #19859 for details. But internal preprocessor.js can, so use it for now in published jest-preset.json.

@kelset kelset referenced this issue Jul 19, 2018

Closed

React native server doesn't start #20286

3 of 3 tasks complete

@kelset kelset added the PR Submitted label Jul 23, 2018

@kelset

This comment has been minimized.

Collaborator

kelset commented Jul 23, 2018

Update on this issue: #20068 (comment)


I'm unlocking because (as mentioned in the link) I'm investigating it further and it seems that there is something "weird" going on with babel-jest not working properly.

By investigating in the jest repo, it seems that changing the .babelrc file to the babel.config.js should fix it completely, but I can't manage to make it work. So I'd like some feedback on the approach proposed over there: facebook/jest#6053 (comment)

and potentially related too: facebook/jest#6229

@facebook facebook unlocked this conversation Jul 23, 2018

@hramos hramos changed the title from Can't run jest tests with 0.56.0-rc.2 to Can't run jest tests with 0.56.0 Jul 23, 2018

@SudoPlz

This comment has been minimized.

Contributor

SudoPlz commented Jul 24, 2018

I'm not using typescript, so the changes I had to make so that it now works were:

package.json:

devDependencies now using:

"@babel/core": "7.0.0-beta.54",
"babel-core": "7.0.0-bridge.0",
"babel-bridge": "^1.12.11",
"babel-preset-react-native": "^5.0.2",
"babel-jest": "23.4.0",
"jest": "23.4.1"

jest (in the same file):

"jest": {
-    "preset": "react-native"
+    "preset": "react-native",
+    "transform": {
+      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
+    }
},
@kelset

This comment has been minimized.

Collaborator

kelset commented Jul 25, 2018

Ok, so, after a whole lot of testing and investigating here's the TLDR

  1. the interaction between babel-jest (which is the default transformer jest uses when testing your code) and babel 7 is not fully reliable (hence, the issue above).

  2. It seems that for simple projects changing the .babelrc file to a babel.config.js should fix that interaction (facebook/jest#6053 (comment))*

  3. In complex scenarios, you should use the workaround presented above of modifying your jest configuration to use as custom transformer the one included in the react-native node module:

+    "transform": {
+      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
+    }
  1. in even more complex scenarios, where you may need to use some custom babel plugins, I suggest you copy the preprocessor locally and add the extra plugins the dedicated section of the config. Then, similarly to the point above, modify your jest config to use this custom preprocessor:
+    "transform": {
+      "^.+\\.js$": "<RELATIVE_PATH>/preprocessor.js"
+    }

I'd like to thank @vovkasm for his help in finding a way to fix this issue.

(I'm locking this issue again since I'd prefer to keep this as last comment, if there are any evolutions on the subject please open a new issue)


*It may break Metro parsing the .babelrc, reason why I suggest you use babel.config.js and a "mock" .babelrc that contains only these lines:

{
  "extends": "<RELATIVE_PATH>/babel.config.js"
}

@facebook facebook locked as resolved and limited conversation to collaborators Jul 25, 2018

@hramos

This comment has been minimized.

Contributor

hramos commented Aug 16, 2018

@deecewan provided additional details in a duplicate of this issue: #20683

@grabbou

This comment has been minimized.

Collaborator

grabbou commented Aug 20, 2018

I believe we should get this fixed in master so that it works out of the box. @kelset, are you able to tackle this since you have done significant research into it already? I believe it can be connected with our "preset" PR (the one that was about to remove babelrc completely from the project).

@janicduplessis

This comment has been minimized.

Collaborator

janicduplessis commented Oct 7, 2018

I just updated tests in a project to work on RN master and here are the steps I had to do (thanks @kelset)

  1. yarn add --dev babel-jest babel-core@^7.0.0-bridge.0 @babel/core regenerator-runtime as per https://jestjs.io/docs/en/getting-started.html#using-babel
  2. rename my .babelrc file to babel.config.js
@kelset

This comment has been minimized.

Collaborator

kelset commented Oct 8, 2018

Yeah it's been a while since the workaround I wrote, may be worth updating the HelloWorld template to have the steps you list embedded, what do you think @janicduplessis? I think that now we should be able to have safely babel.config.js as "starting" file 🤔

@janicduplessis

This comment has been minimized.

Collaborator

janicduplessis commented Oct 9, 2018

Ideally .babelrc should work, I guess there is a bug somewhere but I don’t really have the time to investigate this for now.

I agree that we should update the starting template to install the dependencies in my comment and include the babel.config.js workaround.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.