Skip to content

Commit 175b9b9

Browse files
aleclarsonthymikeemdjastrzebski
authored
feat: call "cleanup" automatically (#238)
* feat: add "cleanup" function * docs: add "cleanup" section * feat: automatically call "cleanup" after each test ...if an "afterEach" global function is defined, and process.env.RTL_SKIP_AUTO_CLEANUP is falsy. Taken from: https://github.com/testing-library/react-testing-library/blob/14670debd45236d2c5d0a61a83dadc72af1bef7c/src/index.js * docs: mention automatic cleanup * add within * fix lint * Updated tests, added auto-cleanup test * Added ways to prevent auto cleanup * Small fix * Code review changes * Update website/docs/API.md Co-authored-by: Michał Pierzchała <[email protected]> * More changes * Removed afterEach(cleanup) calls in examples * Code cleanup Co-authored-by: Michał Pierzchała <[email protected]> Co-authored-by: Maciej Jastrzebski <[email protected]>
1 parent 3ef0064 commit 175b9b9

File tree

15 files changed

+151
-31
lines changed

15 files changed

+151
-31
lines changed

dont-cleanup-after-each.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
process.env.RNTL_SKIP_AUTO_CLEANUP = true;

examples/reactnavigation/src/__tests__/AppNavigator.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import React from 'react';
22
import { NavigationContainer } from '@react-navigation/native';
3-
import { render, fireEvent, cleanup } from 'react-native-testing-library';
3+
import { render, fireEvent } from 'react-native-testing-library';
44

55
import AppNavigator from '../AppNavigator';
66

77
// Silence the warning https://github.com/facebook/react-native/issues/11094#issuecomment-263240420
88
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
99

1010
describe('Testing react navigation', () => {
11-
afterEach(cleanup);
12-
1311
test('page contains the header and 10 items', () => {
1412
const component = (
1513
<NavigationContainer>

examples/redux/components/AddTodo.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React from 'react';
22
import { Provider } from 'react-redux';
3-
import { cleanup, fireEvent, render } from 'react-native-testing-library';
3+
import { fireEvent, render } from 'react-native-testing-library';
44
import configureStore from '../store';
55
import AddTodo from './AddTodo';
66

77
describe('Application test', () => {
8-
afterEach(cleanup);
9-
108
test('adds a new test when entry has been included', () => {
119
const store = configureStore();
1210

examples/redux/components/TodoList.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React from 'react';
22
import { Provider } from 'react-redux';
3-
import { cleanup, fireEvent, render } from 'react-native-testing-library';
3+
import { fireEvent, render } from 'react-native-testing-library';
44
import configureStore from '../store';
55
import TodoList from './TodoList';
66

77
describe('Application test', () => {
8-
afterEach(cleanup);
9-
108
test('it should execute with a store with 4 elements', () => {
119
const initialState = {
1210
todos: [

examples/redux/reducers/todoReducer.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export default function todoReducer(state = [], action) {
66
return state.concat(action.payload);
77

88
case actions.REMOVE:
9-
console.log(action);
109
return state.filter((todo) => todo.id !== action.payload.id);
1110

1211
case actions.MODIFY:

pure.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// makes it so people can import from 'react-native-testing-library/pure'
2+
module.exports = require('./build/pure');

src/__tests__/auto-cleanup-skip.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import { View } from 'react-native';
3+
4+
let render;
5+
beforeAll(() => {
6+
process.env.RNTL_SKIP_AUTO_CLEANUP = 'true';
7+
const rtl = require('../');
8+
render = rtl.render;
9+
});
10+
11+
let isMounted = false;
12+
13+
class Test extends React.Component<*> {
14+
componentDidMount() {
15+
isMounted = true;
16+
}
17+
18+
componentWillUnmount() {
19+
isMounted = false;
20+
if (this.props.onUnmount) {
21+
this.props.onUnmount();
22+
}
23+
}
24+
render() {
25+
return <View />;
26+
}
27+
}
28+
29+
// This just verifies that by importing RNTL in pure mode in an environment which supports
30+
// afterEach (like jest) we won't get automatic cleanup between tests.
31+
test('component is mounted, but not umounted before test ends', () => {
32+
const fn = jest.fn();
33+
render(<Test onUnmount={fn} />);
34+
expect(fn).not.toHaveBeenCalled();
35+
});
36+
37+
test('component is NOT automatically umounted after first test ends', () => {
38+
expect(isMounted).toEqual(true);
39+
});

src/__tests__/auto-cleanup.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import { View } from 'react-native';
3+
import { render } from '..';
4+
5+
let isMounted = false;
6+
7+
class Test extends React.Component<*> {
8+
componentDidMount() {
9+
isMounted = true;
10+
}
11+
12+
componentWillUnmount() {
13+
isMounted = false;
14+
if (this.props.onUnmount) {
15+
this.props.onUnmount();
16+
}
17+
}
18+
render() {
19+
return <View />;
20+
}
21+
}
22+
23+
// This just verifies that by importing RNTL in an environment which supports afterEach (like jest)
24+
// we'll get automatic cleanup between tests.
25+
test('component is mounted, but not umounted before test ends', () => {
26+
const fn = jest.fn();
27+
render(<Test onUnmount={fn} />);
28+
expect(fn).not.toHaveBeenCalled();
29+
});
30+
31+
test('component is automatically umounted after first test ends', () => {
32+
expect(isMounted).toEqual(false);
33+
});

src/__tests__/cleanup.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* eslint-disable react/no-multi-comp */
33
import React from 'react';
44
import { View } from 'react-native';
5-
import { cleanup, render } from '..';
5+
import { cleanup, render } from '../pure';
66

77
class Test extends React.Component<*> {
88
componentWillUnmount() {

src/__tests__/waitFor.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ test('waits for element until timeout is met', async () => {
5555
await expect(
5656
waitFor(() => getByText('Fresh'), { timeout: 100 })
5757
).rejects.toThrow();
58+
59+
// Async action ends after 300ms and we only waited 100ms, so we need to wait
60+
// for the remaining async actions to finish
61+
await waitFor(() => getByText('Fresh'));
5862
});
5963

6064
test('waits for element with custom interval', async () => {

0 commit comments

Comments
 (0)