refactor: update example apps (#1024)

This commit is contained in:
Maciej Jastrzebski
2022-07-26 14:55:24 +02:00
committed by GitHub
parent 14dba849d7
commit 7dd403b2ea
18 changed files with 128 additions and 267 deletions
-12
View File
@@ -1,14 +1,2 @@
import 'react-native-gesture-handler/jestSetup';
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;
});
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
+2 -2
View File
@@ -1,7 +1,7 @@
module.exports = {
preset: 'react-native',
setupFiles: ['./jest-setup.js'],
setupFilesAfterEnv: ['./jest-setup.js'],
transformIgnorePatterns: [
'node_modules/(?!(jest-)?react-native|@react-native-community|@react-navigation)',
'node_modules/(?!(jest-)?react-native|@react-native|@react-native-community|@react-navigation)',
],
};
+12 -17
View File
@@ -7,25 +7,20 @@
"test": "jest"
},
"dependencies": {
"@react-native-community/masked-view": "^0.1.9",
"@react-navigation/drawer": "^5.11.4",
"@react-navigation/native": "^5.1.6",
"@react-navigation/stack": "^5.2.13",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-native": "^0.62.2",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.5.0"
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"@react-navigation/stack": "^6.2.2",
"react": "^18.0.0",
"react-native": "^0.69.2",
"react-native-safe-area-context": "^4.3.1",
"react-native-screens": "^3.15.0"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/runtime": "^7.9.2",
"babel-jest": "^25.4.0",
"jest": "^25.4.0",
"metro-react-native-babel-preset": "^0.59.0",
"@testing-library/react-native": "^7.0.0-rc.0",
"react-test-renderer": "^16.13.1"
"@testing-library/react-native": "^11.0.0",
"babel-jest": "^28.0.0",
"jest": "^28.0.0",
"metro-react-native-babel-preset": "^0.70.0",
"react-test-renderer": "^18.0.0"
}
}
-2
View File
@@ -1,8 +1,6 @@
import 'react-native-gesture-handler';
import React from 'react';
import { StatusBar, StyleSheet, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import AppNavigator from './AppNavigator';
export default function App() {
+6 -9
View File
@@ -1,18 +1,15 @@
import * as React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';
const { Screen, Navigator } = createStackNavigator();
const Stack = createNativeStackNavigator();
export default function Navigation() {
const options = {};
return (
<Navigator>
<Screen name="Home" component={HomeScreen} />
<Screen options={options} name="Details" component={DetailsScreen} />
</Navigator>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}
@@ -0,0 +1,24 @@
import * as React from 'react';
import { screen, fireEvent } from '@testing-library/react-native';
import { renderWithNavigation } from './test-utils';
import AppNavigator from './AppNavigator';
test('page contains the header and 10 items', async () => {
renderWithNavigation(<AppNavigator />);
const header = await screen.findByText('List of numbers from 1 to 20');
expect(header).toBeTruthy();
const items = screen.getAllByText(/Item number/);
expect(items.length).toBe(10);
});
test('clicking on one item takes you to the details screen', async () => {
renderWithNavigation(<AppNavigator />);
const toClick = await screen.findByText('Item number 5');
fireEvent(toClick, 'press');
expect(screen.getByText('Showing details for 5')).toBeTruthy();
expect(screen.getByText('the number you have chosen is 5')).toBeTruthy();
});
-13
View File
@@ -1,13 +0,0 @@
import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import DrawerAppNavigator from './DrawerAppNavigator';
export default function DrawerApp() {
return (
<NavigationContainer>
<DrawerAppNavigator />
</NavigationContainer>
);
}
@@ -1,35 +0,0 @@
import React from 'react';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {View, Button, Text} from 'react-native';
const { Screen, Navigator } = createDrawerNavigator();
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Welcome!</Text>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>This is the notifications screen</Text>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
export default function Navigation() {
return (
<Navigator>
<Screen name="Home" component={HomeScreen} />
<Screen name="Notifications" component={NotificationsScreen} />
</Navigator>
);
}
@@ -1,41 +0,0 @@
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, fireEvent } from '@testing-library/react-native';
import AppNavigator from '../AppNavigator';
describe('Testing react navigation', () => {
test('page contains the header and 10 items', async () => {
const component = (
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
);
const { findByText, findAllByText } = render(component);
const header = await findByText('List of numbers from 1 to 20');
const items = await findAllByText(/Item number/);
expect(header).toBeTruthy();
expect(items.length).toBe(10);
});
test('clicking on one item takes you to the details screen', async () => {
const component = (
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
);
const { findByText } = render(component);
const toClick = await findByText('Item number 5');
fireEvent(toClick, 'press');
const newHeader = await findByText('Showing details for 5');
const newBody = await findByText('the number you have chosen is 5');
expect(newHeader).toBeTruthy();
expect(newBody).toBeTruthy();
});
});
@@ -1,39 +0,0 @@
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, fireEvent } from '@testing-library/react-native';
import DrawerAppNavigator from '../DrawerAppNavigator';
describe('Testing react navigation', () => {
test('screen contains a button linking to the notifications page', async () => {
const component = (
<NavigationContainer>
<DrawerAppNavigator />
</NavigationContainer>
);
const { findByText, findAllByText } = render(component);
const button = await findByText('Go to notifications');
expect(button).toBeTruthy();
});
test('clicking on the button takes you to the notifications screen', async () => {
const component = (
<NavigationContainer>
<DrawerAppNavigator />
</NavigationContainer>
);
const { queryByText, findByText } = render(component);
const oldScreen = queryByText('Welcome!');
const button = await findByText('Go to notifications');
expect(oldScreen).toBeTruthy();
fireEvent(button, 'press');
const newScreen = await findByText('This is the notifications screen');
expect(newScreen).toBeTruthy();
});
});
@@ -12,7 +12,7 @@ export default function HomeScreen({ navigation }) {
new Array(20).fill(null).map((_, idx) => idx + 1)
);
const onOpacityPress = item => navigation.navigate('Details', item);
const onOpacityPress = (item) => navigation.navigate('Details', item);
return (
<View>
@@ -0,0 +1,9 @@
/* eslint-disable import/no-extraneous-dependencies */
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render } from '@testing-library/react-native';
/** Render helper that renders `ui` within `NavigationContainer`. */
export function renderWithNavigation(ui) {
return render(<NavigationContainer>{ui}</NavigationContainer>);
}
+20 -33
View File
@@ -1,40 +1,27 @@
import * as React from 'react';
import { Provider } from 'react-redux';
import { fireEvent, render } from '@testing-library/react-native';
import configureStore from '../store';
import { screen, fireEvent } from '@testing-library/react-native';
import { renderWithRedux } from '../test-utils';
import AddTodo from './AddTodo';
describe('Application test', () => {
test('adds a new test when entry has been included', () => {
const store = configureStore();
test('adds a new todo to redux store when submitting form', () => {
const { store } = renderWithRedux(<AddTodo />);
const component = (
<Provider store={store}>
<AddTodo />
</Provider>
);
const input = screen.getByPlaceholderText(/repository/i);
expect(input).toBeTruthy();
const { getByPlaceholderText, getByText } = render(component);
const textToEnter = 'This is a random element';
fireEvent.changeText(input, textToEnter);
fireEvent.press(screen.getByText('Submit form'));
const input = getByPlaceholderText(/repository/i);
expect(input).toBeTruthy();
const textToEnter = 'This is a random element';
fireEvent.changeText(input, textToEnter);
fireEvent.press(getByText('Submit form'));
const todosState = store.getState().todos;
expect(todosState.length).toEqual(1);
expect(todosState).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 1,
text: textToEnter,
date: expect.any(Date),
}),
])
);
});
const todosState = store.getState().todos;
expect(todosState).toHaveLength(1);
expect(todosState).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 1,
text: textToEnter,
date: expect.any(Date),
}),
])
);
});
+28 -51
View File
@@ -1,57 +1,34 @@
import * as React from 'react';
import { Provider } from 'react-redux';
import { fireEvent, render } from '@testing-library/react-native';
import configureStore from '../store';
import { screen, fireEvent } from '@testing-library/react-native';
import { renderWithRedux } from '../test-utils';
import TodoList from './TodoList';
describe('Application test', () => {
test('it should execute with a store with 4 elements', () => {
const initialState = {
todos: [
{ id: 1, text: 'Sing something', date: new Date() },
{ id: 2, text: 'Dance something', date: new Date() },
{ id: 3, text: 'Sleep something', date: new Date() },
{ id: 4, text: 'Sleep something', date: new Date() },
],
};
const store = configureStore(initialState);
const initialState = {
todos: [
{ id: 1, text: 'Sing something', date: new Date() },
{ id: 2, text: 'Dance something', date: new Date() },
{ id: 3, text: 'Sleep something', date: new Date() },
{ id: 4, text: 'Sleep something', date: new Date() },
],
};
const component = (
<Provider store={store}>
<TodoList />
</Provider>
);
test('it should execute with a store with 4 elements', () => {
renderWithRedux(<TodoList />, { initialState });
const { getAllByText } = render(component);
const todoElems = getAllByText(/something/i);
expect(todoElems.length).toEqual(4);
});
test('should execute with 2 elements and end up with 1 after delete', () => {
const initialState = {
todos: [
{ id: 1, text: 'Sing something', date: new Date() },
{ id: 2, text: 'Dance something', date: new Date() },
],
};
const store = configureStore(initialState);
const component = (
<Provider store={store}>
<TodoList />
</Provider>
);
const { getAllByText } = render(component);
const todoElems = getAllByText(/something/i);
expect(todoElems.length).toBe(2);
const buttons = getAllByText('Delete');
expect(buttons.length).toBe(2);
fireEvent.press(buttons[0]);
expect(getAllByText('Delete').length).toBe(1);
});
const todoElems = screen.getAllByText(/something/i);
expect(todoElems).toHaveLength(4);
});
test('should execute with 2 elements and end up with 1 after delete', () => {
renderWithRedux(<TodoList />, { initialState });
const todoElems = screen.getAllByText(/something/i);
expect(todoElems.length).toBe(4);
const buttons = screen.getAllByText('Delete');
expect(buttons).toHaveLength(4);
fireEvent.press(buttons[0]);
const buttonsAfterDelete = screen.getAllByText('Delete');
expect(buttonsAfterDelete).toHaveLength(3);
});
+2
View File
@@ -0,0 +1,2 @@
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
preset: '@testing-library/react-native',
setupFiles: ['./jest-setup.js'],
};
+9 -12
View File
@@ -2,25 +2,22 @@
"name": "redux-example",
"description": "Testing Redux interactions with RNTL",
"version": "0.0.1",
"private": true,
"scripts": {
"test": "jest"
},
"dependencies": {
"react": "~16.9.0",
"react-native": "~0.61.5",
"react": "~18.0.0",
"react-native": "~0.69.2",
"react-redux": "^7.2.0",
"redux": "^4.0.5"
},
"devDependencies": {
"@babel/core": "^7.8.6",
"babel-jest": "~25.2.6",
"jest": "~25.2.6",
"metro-react-native-babel-preset": "^0.59.0",
"@testing-library/react-native": "^7.0.0-rc.0",
"react-test-renderer": "~16.9.0"
},
"private": true,
"jest": {
"preset": "react-native"
"@babel/core": "^7.9.0",
"@testing-library/react-native": "^11.0.0",
"@types/jest": "^28.0.0",
"jest": "^28.0.0",
"metro-react-native-babel-preset": "^0.70.0",
"react-test-renderer": "^18.0.0"
}
}
+11
View File
@@ -0,0 +1,11 @@
/* eslint-disable import/no-extraneous-dependencies */
import * as React from 'react';
import { Provider } from 'react-redux';
import { render } from '@testing-library/react-native';
import configureStore from './store';
export function renderWithRedux(ui, options) {
const store = options?.store ?? configureStore(options?.initialState);
const queries = render(<Provider store={store}>{ui}</Provider>);
return { ...queries, store };
}