Error with Icons testing React Native with Jest - javascript

I'm new to Jest and im trying to do unit tests to one component of my App in which i use Icons from #ui-kitten/components.
When trying to test i get the following Error:
console.error
The above error occurred in the <Icon> component:
at Icon (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\ui\icon\icon.component.tsx:87:34)
at DateIcon
at FalsyFC (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\#ui-kitten\components\devsupport\components\falsyFC\falsyFC.component.js:41:37)
at View
at View (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\jest\mockComponent.js:28:18)
at View
at View (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\jest\mockComponent.js:28:18)
at AnimatedComponent (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\Libraries\Animated\createAnimatedComponent.js:42:43)
at AnimatedComponentWrapper
at TouchableOpacity (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js:53:37)
at TouchableWithoutFeedback (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\devsupport\components\touchableWithoutFeedback.component.tsx:32:1)
at Input (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\ui\input\input.component.tsx:141:1)
at Wrapper (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\theme\style\styled.tsx:104:3)
at Input
at RNCSafeAreaView
at RNCSafeAreaView (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\jest\setup.js:332:22)
at vehicleFormtest
at View
at View (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\react-native\jest\mockComponent.js:28:18)
at ModalPanel (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\theme\modal\modalPanel.component.tsx:35:1)
at ThemeProvider (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\#ui-kitten\components\theme\theme\themeProvider.component.js:46:37)
at MappingProvider (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\#ui-kitten\components\theme\mapping\mappingProvider.component.js:39:37)
at StyleProvider (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\node_modules\#ui-kitten\components\theme\style\styleProvider.component.js:46:37)
at ApplicationProvider (C:\Users\Cazam\Desktop\TT3\Testing-VraVa\src\components\theme\application\applicationProvider.component.tsx:105:46)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
VehicleFormtest.js
import React from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import { Icon, Input } from "#ui-kitten/components";
const DateIcon = (props) => <Icon {...props} name="calendar-outline" />;
const vehicleFormtest = () => (
<SafeAreaView style={{ flex: 1 }}>
<Input accessoryRight={DateIcon} />
</SafeAreaView>
);
export default vehicleFormtest;
VehicleFormtest.test.js
import React from "react";
import { render } from "#testing-library/react-native";
import * as eva from "#eva-design/eva";
import { ApplicationProvider, IconRegistry } from "#ui-kitten/components";
import VehicleFormtest from "./vehicleFormtest";
describe("<VehicleForm />", () => {
it("test", () => {
const tree = render(
<ApplicationProvider {...eva} theme={eva.light}>
<VehicleFormtest />
</ApplicationProvider>
);
});
});
Jest config on package.json
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?#react-native|react-native|react-clone-referenced-element|#react-native-community|expo(nent)?|#expo(nent)?/.*|react-navigation|#react-navigation/.*|#unimodules/.*|sentry-expo|native-base|#ui-kitten)"
]
Honestly i dont know if it's problem of the EvaIcons or something else on the jest configuration. Any help will be welcomed.
Using these versions
"#eva-design/eva": "^2.1.1"
"#ui-kitten/components": "^5.1.0",
"#ui-kitten/eva-icons": "^5.1.0",

Try this:
import React from "react";
import { render } from "#testing-library/react-native";
import * as eva from "#eva-design/eva";
import { ApplicationProvider, IconRegistry } from "#ui-
kitten/components";
import { EvaIconsPack } from "#ui-kitten/eva-icons";
import VehicleFormtest from "./vehicleFormtest";
describe("<VehicleForm />", () => {
it("test", () => {
const tree = render(
<ApplicationProvider {...eva} theme={eva.light}>
<IconRegistry icons={EvaIconsPack} />
<VehicleFormtest />
</ApplicationProvider>
);
});
});

Related

React Native not picking functions from file directory

I am using react-native to build an app. The app has 2 screens: HomeScreen and Search screen. The file explorer cant find the module for Search but the same path for HomeScreen is working. Also I am using android if it helps.
My App.js includes:
import React from 'react';
import type { Node } from 'react';
import { StatusBar } from 'react-native';
import Search from './src/screens/Search/index';
const App: () => Node = () => {
return (
<>
<StatusBar barStyle='dark-content' />
<Search />
</>
);
};
export default App;
Search/index.js includes
import React from "react";
import { View, Text } from "react-native-vector-icons";
const Search = (props) => {
return (
<View>
<Text>Hi</Text>
</View>
);
};
export default Search;
Error:
However if I replace Search by HomeScreen, the app works. Could you please help my figure out what I am doing wrong. I am using the same code and same directory search style in both my index.js files. However, I made HomeScreen/index.js before Search/index.js.
Here is my HomeScreen/index.js
import React from "react";
import { View, Text } from "react-native";
import HomeMap from '../../components/HomeScreenMap';
const HomeScreen = (props) => {
return (
<View>
<HomeMap />
</View>
);
};
export default HomeScreen;
Here is my directory:
MEDLIFE
>__tests__
>.vscode
>android
>ios
>node_modules
>src
>components
>screens
>HomeScreen
>index.js
>Search
>index.js
.buckconfig
.editorconfig
.eslintrc.js
.flowconfig
.gitattributes
.gitignore
.prettierrc.js
.watchmanconfig
App.js
app.json
babel.config.js
index.js
metro.config.js
package.json
yarn.lock
Change this:
import { View, Text } from "react-native-vector-icons";
To this:
import { View, Text } from "react-native";

No QueryClient set, use QueryClientProvider to set one

I was trying to react query for the first time then I got this at the start of my React app.
import React from 'react'
import { useQuery } from "react-query";
const fetchPanets = async () => {
const result = await fetch('https://swapi.dev/api/people')
return result.json()
}
const Planets = () => {
const { data, status } = useQuery('Planets', fetchPanets)
console.log("data", data, "status", status)
return (
<div>
<h2>Planets</h2>
</div>
)
}
export default Planets
As the error suggests, you need to wrap your application in a QueryClientProvider. This is on the first page of the docs:
import { QueryClient, QueryClientProvider, useQuery } from 'react-query'
const queryClient = new QueryClient()
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
While this is most commonly caused by not having your application wrapped in a <QueryClientProvider>, in my case it happened because I was importing some shared components, which ended up with a different context. You can fix this by setting the contextSharing option to true
That would look like:
import { QueryClient, QueryClientProvider } from 'react-query'
const queryClient = new QueryClient()
function App() {
return <QueryClientProvider client={queryClient} contextSharing={true}>...</QueryClientProvider>
}
From the docs: (https://react-query.tanstack.com/reference/QueryClientProvider)
contextSharing: boolean (defaults to false)
Set this to true to enable context sharing, which will share the first and at least one instance of the context across the window to ensure that if React Query is used across different bundles or microfrontends they will all use the same instance of context, regardless of module scoping.
Just make changes like below it will work fine
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
ReactDOM.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
document.getElementById('root')
);
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
const queryClient = new QueryClient();
const fetchPanets = async () => {
const result = await fetch('https://swapi.dev/api/people')
return result.json()
}
const Planets = () => {
const { data, status } = useQuery('Planets', fetchPanets)
console.log("data", data, "status", status)
return (
<div>
<h2>Planets</h2>
</div>
);
}
export default function Wraped(){
return(<QueryClientProvider client={queryClient}>
<Planets/>
</QueryClientProvider>
);
}
Single SPA (micro-frontend) - React Query v3.34.15
I was getting this error while trying to integrate a sigle-spa react parcel into the root application.
I used craco-plugin-single-spa-application for the building of a CRA app as a way to adapt it for a parcel. In the entry config I was pointing to my single-spa-react config.
// craco.config.js
const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')
module.exports = {
plugins: [
{
plugin: singleSpaApplicationPlugin,
options: {
orgName: 'uh-platform',
projectName: 'hosting',
entry: 'src/config/single-spa-index.cf.js',
orgPackagesAsExternal: false,
reactPackagesAsExternal: true,
externals: [],
minimize: false
}
}
]
}
In the single-spa-index.cf.js file I had the following configs.
import React from 'react'
import ReactDOM from 'react-dom'
import singleSpaReact from 'single-spa-react'
import App from '../App'
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary() {
return <div>Ocorreu um erro desconhecido!</div>
}
})
export const { bootstrap, mount, unmount } = lifecycles
After reading a bunch of forums and the react-query documentation, the only thing that I figured out I needed to change was pass in the QueryClientProvider the prop contextSharing as true. After had did this change, ran the building and access the route that opens my parcel. I got the same error.
import React from 'react'
import ReactDOM from 'react-dom'
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'
import App from './App'
const queryClient = new QueryClient()
const isDevelopmentEnv = process.env.NODE_ENV === 'development'
if (isDevelopmentEnv) {
import('./config/msw/worker').then(({ worker }) => worker.start())
}
ReactDOM.render(
<React.StrictMode>
<QueryClientProvider contextSharing={true} client={queryClient}>
<App />
{isDevelopmentEnv && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientProvider>
</React.StrictMode>,
document.getElementById('root')
)
But, how do I solved that. Well, it was was simple. I couldn't even imagine why it was working locally. But not after building and integration.
The problem was because I put the React Query Provider inside the index o the application and in my single-spa-index.cf.js I was importing import App from '../App' which really wasn't wrapped by the provider. Once I also was importing App in the application index, where It was wrapped making It works locally. 😢😢
So after figure that out, my code was like that:
CODE AFTER SOLUTION
// craco.config.js
const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')
module.exports = {
plugins: [
{
plugin: singleSpaApplicationPlugin,
options: {
orgName: 'uh-platform',
projectName: 'hosting',
entry: 'src/config/single-spa-index.cf.js',
orgPackagesAsExternal: false,
reactPackagesAsExternal: true,
externals: [],
minimize: false
}
}
]
}
// src/config/single-spa-index.cf.js
import React from 'react'
import ReactDOM from 'react-dom'
import singleSpaReact from 'single-spa-react'
import App from '../App'
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary() {
return <div>Ocorreu um erro desconhecido!</div>
}
})
export const { bootstrap, mount, unmount } = lifecycles
// App.tsx
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'
import { config } from 'config/react-query'
import Routes from 'routes'
import GlobalStyles from 'styles/global'
import * as S from './styles/shared'
const queryClient = new QueryClient(config)
const isDevelopmentEnv = process.env.NODE_ENV === 'development'
if (isDevelopmentEnv) {
import('./config/msw/worker').then(({ worker }) => worker.start())
}
function App() {
return (
<QueryClientProvider contextSharing={true} client={queryClient}>
<S.PanelWrapper>
<Routes />
<GlobalStyles />
</S.PanelWrapper>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}
export default App
// index.tsx
import { StrictMode } from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
document.getElementById('root')
)
Well, it was long but I hope it helps someone that's undergoing for the same problem as mine. 🙌🙌🙌
I was trying to fix the same thing:
I followed the React Query docs
and used the concept of Higher Order Component
See if it helps:
import React from 'react';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
import Planet from './Planet';
const queryClient = new QueryClient();
const fetchPlanets = async () => {
const res = await fetch('http://swapi.dev/api/planets/');
return res.json();
}
const Planets = () => {
const { data, status } = useQuery('planets', fetchPlanets);
return (
<div>
<h2>Planets</h2>
{ status === 'loading' && (<div>Loading data...</div>)}
{ status === 'error' && (<div>Error fetching data</div>)}
{
status === 'success' && (
data.results.map(planet =>
<Planet
key={planet.name}
planet={planet}
/>
)
)
}
</div>
)
}
// Higher order function
const hof = (WrappedComponent) => {
// Its job is to return a react component warpping the baby component
return (props) => (
<QueryClientProvider client={queryClient}>
<WrappedComponent {...props} />
</QueryClientProvider>
);
};
export default hof(Planets);
In my case I was importtng from 'react-query' in one place and '#tanstack/react-query' in another.
I got that error when trying to add the react-query devtools.
The problem was I was installing it wrongly according my version, I was using react-query v3.
WRONG FOR react-query V3 (GOOD FOR V4)
import { ReactQueryDevtools } from '#tanstack/react-query-devtools';
OK FOR react-query V3
import { ReactQueryDevtools } from 'react-query/devtools';
In my case I accidentally used two different versions of react-query in my modules.
In my case
Error import { QueryClient, QueryClientProvider } from "#tanstack/react-query";
Solution import { QueryClient, QueryClientProvider } from "react-query";
remove it #tanstack/
Just be careful when upgrade from react-query v3 to #tanstack/react-query v4.
Ensure that you replace all imports as "react-query" to "#tanstack/react-query" and then run yarn remove the lib that you won't use anymore, otherwise you may accidentally import the unexpected one.
This happened to me and caused this error.

React Native - Invariant Violation - i18next integration

I am trying to create a react-native application, I'm currently at the starting point and I cannot understand an issue that I encountered.
I need to integrate i18next for translations. I did this by following their step-by-step tutorial
I have the following code
App.js
import React, { Suspense, Component } from 'react';
import { ScrollView, StyleSheet, Text, View, } from 'react-native';
import { useTranslation } from 'react-i18next';
import { Colors, } from 'react-native/Libraries/NewAppScreen';
const MyComponent = () => {
const { t, i18n } = useTranslation();
return <Text>{t('index.welcome')}</Text>;
};
const App = () => {
return (
<Suspense fallback="loading">
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<View style={styles.body}>
<MyComponent />
</View>
</ScrollView>
</Suspense>
);
};
const styles = StyleSheet.create({
scrollView: {
backgroundColor: Colors.lighter,
},
body: {
backgroundColor: Colors.white,
},
});
export default App;
The issue here is that I get an Invariant Violation: Text strings must be rendered within a <Text> component error
If I change MyComponent to the following the application works
const MyComponent = () => {
return <Text>Anything</Text>;
};
So the issue here for me seems to be the useTranslation() hook.
What am I missing here?
LE
I was missing the namespace in the useTranslation()
I've added it useTranslations('translation') but still I have the same issue
The issue seems to be with the path for the translation files which cannot be parsed
i18next::backendConnector: loading namespace translation for language en failed failed parsing /translations/en/translation.json to json
In React the files would be public available via the public folder, in React-Native how should this be used? I think that the app cannot access that folder, where should the folder be placed?
LE2
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-xhr-backend';
i18n
.use(Backend)
.use(initReactI18next)
.init({
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
backend: {
loadPath: '/translations/{{lng}}/{{ns}}.json',
},
});
export default i18n;
And the translations folder is placed in the root of the project

Error on jest when I try to run the test

This is the error in the console: Cannot find module 'expo' from 'setup.js'.
Below is my code:
component.test.js:
import React from 'react';
import MyComponent from '../components/Component';
import renderer from 'react-test-renderer';
test('create component correctly', () =>{
const tree = renderer.create(
<MyComponent/>
).toJSON();
expect(tree).toMatchSnapshot();
});
Component.js:
import React, { Component } from 'react';
import {Text, View } from 'react-native';
export default class MyComponent extends React.Component{
render(){
return(
<View style={{flex: 1}}>
<View style={styles.cameraContainer}>
<Text> Test Component </Text>
</View>
</View>
);
}
}
When I try to use npm test the error that I mentioned before appears and I already try to uninstall and re-install jest and the error keeps showing.
Assuming you are using create-react-native-app, looks like this is coming from the "jest-expo" preset in the jest configuration.
Replace it with the react-native Jest preset, which is now built in to Jest:
jest.config.js:
module.exports = {
preset: 'react-native'
};
Or in package.json:
"jest": {
"preset": "react-native"
}

Cannot read property 'navigate' of undefined - React Native Navigation

I am currently working on a app which works with react native and I tried to make a flow using react-navigation working on this tutorial but I am having trouble at the point of running my project, I've done a lot of research and i just cant get to the solution, first for all I am using react-native-cli: 2.0.1 and react-native: 0.48.3, this is my code:
App.js:
import React, { Component } from 'react';
import { Text, Button, View } from 'react-native';
import {
StackNavigator,
} from 'react-navigation';
class App extends Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
console.log(this.props.navigation);
const { navigate } = this.props.navigation;
return (
<View>
<Text>Go to maps!</Text>
<Button
onPress={() => navigate('Map')}
title="MAP"
/>
</View>
);
}
}
export default App;
my Router.js
import {
StackNavigator,
} from 'react-navigation';
import MapMarker from './MapMarker';
import App from './App';
export const UserStack = StackNavigator({
ScreenMap:
{
screen: MapMarker,
navigationOptions:
{
title: "Map",
header:null
},
},
ScreenHome:
{
screen: App,
navigationOptions:
{
title: "Home",
headerLeft:null
},
},
});
As you can see this is a pretty basic App which i just cant make work, this is a screenshot of my error on the simulator:
I would really really appreciate if you guys could help me with this.
Thanks.
You should change the code onPress={() => navigate('Map')} to onPress={() => navigate('ScreenMap')} and ScreenHome should be the first screen then ScreenMap as you want to navigate from App to MapMarker. Or you can set initialRouteName: ScreenHome in the stacknavigator.
You create your StackNavigator, but where do you use it? You should have something like
import React, { Component } from 'react';
import {
AppRegistry,
View
} from 'react-native';
import {
StackNavigator,
} from 'react-navigation';
export default class MyApp extends Component {
render() {
return (
<View style={{flex:1}}>
<StackNavigator/>
</View>
);
}
}
AppRegistry.registerComponent('MyApp', () => MyApp);
Now that your StackNavigator is controlling what is shown, your App component will have navigation in its props. Note, you do not "pass" the navigation prop. This is handled for you.

Categories