Open ghost opened 6 years ago
I'm having similar issue.
package.json:
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.0",
"jest-enzyme": "^4.0.2",
"jest-expo": "^24.0.0",
"jest-styled-components": "^4.10.0",
I got an error:
/projectDir/node_modules/jest-styled-components/src/native/toHaveStyleRule.js:15
const mergedStyles = styles.reduce((acc, item) => ({ ...acc, ...item }), {})
^^^
SyntaxError: Unexpected token ...
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
at Object.<anonymous> (node_modules/jest-styled-components/native/index.js:1:114)
at Object.<anonymous> (setupTest.js:2:1)
jest.config.js:
module.exports = {
preset: 'jest-expo',
verbose: true,
setupFiles: ['./jest.setup.js'],
snapshotSerializers: ['enzyme-to-json/serializer'],
setupTestFrameworkScriptFile: './setupTest.js',
}
It seems, it breaks because of spread operator. When using Object.assign instead I can run my test.
In my case I was using const tree = renderer.create(<Component />).toJSON()
, now I switched to enzyme shallow and getting the same error as mentioned by @MoeSattler
Everything works when invoking toJSON function from enzyme-to-json
manually.
import toJSON from 'enzyme-to-json'
const tree = toJSON(shallow(<Component />))
expect(tree).toMatchSnapshot()
expect(tree).toHaveStyleRule('color', 'red')
So, as a workaround I've created custom shallow function in jest.setup.js
, so I don't have to invoke it manually in each file anymore:
import Enzyme, { shallow } from 'enzyme'
import toJSON from 'enzyme-to-json'
Enzyme.configure({ adapter: new Adapter() })
const customShallow = (tree) => {
return toJSON(shallow(tree))
}
global.shallow = customShallow
Hey there! I didn't design it having enzyme in mind tbh, but I'm glad you figured out! For me, it feels like the problem that you experience @vitbokisch is related to your jest run environment rather than to the toHaveStyleRule matcher itself. Try to run it using babel-node
(I believe I tested it with it), it should do the trick.
I was having the same issue.
Apparently, it's because of the difference in the versions of NODE. I had 6.x.x on my server and 9.x.x locally (where they were passing)
I had several issues:
1) it looked like the global serialization config (as described here: https://github.com/styled-components/jest-styled-components#enzyme) didn't work, so I had to use enzyme-to-json
and call toJson
from my file.
2) second, I was using styled-components and I had to call dive()
to get access to the actual component that I can use the toHaveStyleRule
call on.
So I ended up writing a helper function like this:
import toJSON from "enzyme-to-json"
const shallowDive = component => {
return toJSON(shallow(component).dive())
}
Hi! i'm getting the same issue with the latest stable version of react native and everything that comes prepackaged, with the following configuration:
package.json:
{
"dependencies": {
"@react-native-community/masked-view": "^0.1.10",
"@react-native-firebase/app": "^10.8.0",
"@react-native-firebase/auth": "^10.8.0",
"@react-navigation/drawer": "^5.12.3",
"@react-navigation/native": "^5.9.2",
"@react-navigation/stack": "^5.14.2",
"formik": "^2.2.6",
"react": "16.13.1",
"react-native": "0.63.4",
"react-native-gesture-handler": "^1.10.1",
"react-native-paper": "^4.7.1",
"react-native-reanimated": "^1.13.2",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "^2.17.1",
"react-native-svg": "^12.1.0",
"react-native-vector-icons": "^8.0.0",
"styled-components": "^5.2.1",
"yup": "^0.32.9"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/runtime": "^7.8.4",
"@react-native-community/eslint-config": "^1.1.0",
"babel-jest": "^25.1.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6",
"enzyme-to-json": "^3.6.1",
"eslint": "^6.5.1",
"jest": "^25.1.0",
"jest-environment-enzyme": "^7.1.2",
"jest-enzyme": "^7.1.2",
"jest-styled-components": "^7.0.3",
"metro-react-native-babel-preset": "^0.59.0",
"react-dom": "16.13.1",
"react-native-svg-transformer": "^0.14.3",
"react-test-renderer": "16.13.1"
},
"jest": {
"preset": "react-native",
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"testEnvironment": "enzyme",
"testEnvironmentOptions": {
"enzymeAdapter": "react16"
},
"collectCoverage": true,
"collectCoverageFrom": [
"<rootDir>/src/**/**.js"
],
"coverageThreshold": {
"global": {
"branches": 90,
"functions": 90,
"lines": 90,
"statements": 90
}
},
"setupFilesAfterEnv": [
"jest-enzyme",
"<rootDir>/jest.setup.js",
"<rootDir>/node_modules/react-native-gesture-handler/jestSetup.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|@?react-navigation)"
]
},
"resolutions": {
"styled-components": "^5"
}
}
babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
env: {
production: {
plugins: ['react-native-paper/babel'],
},
},
};
jest.setup.js:
import 'react-native-gesture-handler/jestSetup';
import 'jest-styled-components/native'; // doesn't work!
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
const {JSDOM} = require('jsdom');
const jsdom = new JSDOM();
const {window} = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter((prop) => typeof target[prop] === 'undefined')
.map((prop) => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
Reanimated.default.call = () => {};
return Reanimated;
});
import {NativeModules} from 'react-native';
NativeModules.RNGestureHandlerModule = {
attachGestureHandler: jest.fn(),
createGestureHandler: jest.fn(),
dropGestureHandler: jest.fn(),
updateGestureHandler: jest.fn(),
State: {},
Directions: {},
};
NativeModules.ImagePickerManager = {
showImagePicker: jest.fn(),
};
NativeModules.Linking = {
canOpenUrl: jest.fn().mockResolvedValue(true),
openUrl: jest.fn().mockResolvedValue(true),
};
NativeModules.Platform = {
OS: 'iOS',
};
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
jest.mock('react-native/Libraries/Animated/src/animations/TimingAnimation');
Enzyme.configure({adapter: new Adapter()});
I've been reading both this repo's issues, and stack overflow answers, but couldn't find any solution...The error i'm getting is:
TypeError: Cannot read property 'filter' of undefined
at Object.toHaveStyleRule (.../node_modules/jest-styled-components/src/native/toHaveStyleRule.js:4:40)
at __EXTERNAL_MATCHER_TRAP__ (.../node_modules/expect/build/index.js:342:30)
at Object.throwingMatcher (.../node_modules/expect/build/index.js:343:15)
at .../src/components/atoms/snackbar/snackbar.style.spec.js:26:60
at Object.<anonymous> (.../node_modules/jest-each/build/bind.js:76:13)
at Object.asyncJestTest (.../node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
at .../node_modules/jest-jasmine2/build/queueRunner.js:45:12
at new Promise (<anonymous>)
at mapper (.../node_modules/jest-jasmine2/build/queueRunner.js:28:19)
at .../node_modules/jest-jasmine2/build/queueRunner.js:75:41
at processTicksAndRejections (internal/process/task_queues.js:93:5)
Any help would be appreciated!
I cannot use the
toHaveStyleRule
function, it throws errors.The resulting error is
I am using following dependencies:
config