Skip to content
This repository was archived by the owner on Jul 30, 2020. It is now read-only.

feat(cleanup): add after each cleanup helper #19

Merged
merged 3 commits into from
May 21, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cleanup-after-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
afterEach(require('./dist').cleanup);
Binary file modified other/cheat-sheet.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"files": [
"dist",
"typings",
"cleanup-after-each.js",
"jest-preset.js"
],
"engines": {
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/act.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import 'jest-native/extend-expect';
import { Button } from 'react-native';

import { render, fireEvent } from '../';
import { render, fireEvent, cleanup } from '../';

afterEach(cleanup);

test('render calls useEffect immediately', () => {
const effectCb = jest.fn();
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/bugs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';

import { render, queryAllByProp } from '../';
import { render, queryAllByProp, cleanup } from '../';

afterEach(cleanup);

// This is to ensure custom queries can be passed to render. In most cases, you
// wouldn't/shouldn't need to do this, but we do allow it so we'll test to
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/debug.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
import { Text } from 'react-native';

import { render } from '../';
import { cleanup, render } from '../';

beforeEach(() => {
jest.spyOn(console, 'log').mockImplementation(() => {});
});

afterEach(() => {
cleanup();
console.log.mockRestore();
});

Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/end-to-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import 'jest-native/extend-expect';
import { Text } from 'react-native';

import { render, wait } from '../';
import { cleanup, render, wait } from '../';

afterEach(cleanup);

const fetchAMessage = () =>
new Promise(resolve => {
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import 'jest-native/extend-expect';
import { Button, Image, Text, TextInput, TouchableHighlight } from 'react-native';

import { render, fireEvent, eventMap, NativeTestEvent, getEventHandlerName, wait } from '../';
import { render, fireEvent, eventMap, getEventHandlerName, wait, cleanup } from '../';

afterEach(cleanup);

Object.keys(eventMap).forEach(key => {
describe(`${key} events`, () => {
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import 'jest-native/extend-expect';
import { TouchableOpacity, Text, View } from 'react-native';

import { render, fireEvent, wait } from '../';
import { render, fireEvent, wait, cleanup } from '../';

afterEach(cleanup);

global.fetch = require('jest-fetch-mock');

Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/forms.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import { Button, TextInput, View } from 'react-native';
import { render, fireEvent } from '../';
import { render, fireEvent, cleanup } from '../';

afterEach(cleanup);

function Login({ onSubmit, user }) {
return (
Expand Down
10 changes: 6 additions & 4 deletions src/__tests__/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import { Button, Picker, Text, View } from 'react-native';
import { toMatchDiffSnapshot } from 'snapshot-diff';

import { fireEvent, render } from '../';
import { cleanup, fireEvent, render } from '../';

afterEach(cleanup);

test('<Picker /> works', () => {
function Wrapper() {
Expand Down Expand Up @@ -32,15 +34,15 @@ test('fragments can show diffs', () => {

expect.extend({ toMatchDiffSnapshot });

const { getByText, asFragment } = render(<TestComponent />);
const firstRender = asFragment();
const { getByText, asJSON } = render(<TestComponent />);
const firstRender = asJSON();

fireEvent.press(getByText(/Click to increase/));

// This will snapshot only the difference between the first render, and the
// state of the DOM after the click event.
// See https://github.com/jest-community/snapshot-diff
expect(firstRender).toMatchDiffSnapshot(asFragment());
expect(firstRender).toMatchDiffSnapshot(asJSON());
});

test('finds only valid children', () => {
Expand Down
10 changes: 6 additions & 4 deletions src/__tests__/render.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, SafeAreaView, View } from 'react-native';

import { render, toJSON } from '../';
import { cleanup, render } from '../';

afterEach(cleanup);

test('renders View', () => {
const { container } = render(<View />);
Expand All @@ -24,10 +26,10 @@ it('supports fragments', () => {
}
}

const { asFragment, unmount } = render(<Test />);
expect(asFragment()).toMatchSnapshot();
const { asJSON, unmount } = render(<Test />);
expect(asJSON()).toMatchSnapshot();
unmount();
expect(asFragment()).toBeNull();
expect(asJSON()).toBeNull();
});

test('renders options.wrapper around node', () => {
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/rerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import 'jest-native/extend-expect';
import { Text } from 'react-native';

import { render } from '../';
import { cleanup, render } from '../';

afterEach(cleanup);

test('rerender will re-render the element', () => {
const Greeting = props => <Text>{props.message}</Text>;
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/stopwatch.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Button, Text, View } from 'react-native';

import { render, fireEvent, prettyPrint } from '../';
import { render, fireEvent, prettyPrint, cleanup } from '../';

afterEach(cleanup);

class StopWatch extends React.Component {
state = { lapse: 0, running: false };
Expand Down
21 changes: 17 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import {
getQueriesForElement,
NativeTestEvent,
prettyPrint,
proxyElement as proxy,
proxyElement,
} from './lib';
import act from './act-compat';

const renderers = new Set();

function render(ui, { options = {}, wrapper: WrapperComponent, queries } = {}) {
const wrapUiIfNeeded = innerElement =>
WrapperComponent ? (
Expand All @@ -28,7 +30,9 @@ function render(ui, { options = {}, wrapper: WrapperComponent, queries } = {}) {
testRenderer = TR.create(wrapUiIfNeeded(ui), options);
});

const wrappers = proxy(testRenderer.root).findAll(n => n.getProp('pointerEvents') === 'box-none');
renderers.add(testRenderer);

const wrappers = proxyElement(testRenderer.root).findAll(n => n.type === 'View');
const baseElement = wrappers[0]; // Includes YellowBox and your render
const container = wrappers[1]; // Includes only your render

Expand All @@ -42,13 +46,22 @@ function render(ui, { options = {}, wrapper: WrapperComponent, queries } = {}) {
testRenderer.update(wrapUiIfNeeded(rerenderUi));
});
},
asFragment: () => {
asJSON: () => {
return toJSON(container);
},
...getQueriesForElement(baseElement, queries),
};
}

function cleanup() {
renderers.forEach(cleanupRenderer);
}

function cleanupRenderer(renderer) {
renderer.unmount();
renderers.delete(renderer);
}

function fireEvent(...args) {
let returnValue;
act(() => {
Expand All @@ -68,4 +81,4 @@ Object.keys(rntlFireEvent).forEach(typeArg => {
});

export * from './lib';
export { act, fireEvent, render, NativeTestEvent };
export { act, cleanup, fireEvent, render, NativeTestEvent };
4 changes: 3 additions & 1 deletion src/lib/__tests__/get-by-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import cases from 'jest-in-case';

import { render } from '../../';
import { cleanup, render } from '../../';

afterEach(cleanup);

cases(
'getBy* queries throw an error when there are multiple elements returned',
Expand Down
6 changes: 4 additions & 2 deletions src/lib/__tests__/misc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';
import { View } from 'react-native';

import { render, queryByProp, queryByTestId } from '../../';
import { render, queryByProp, queryByTestId, cleanup } from '../../';

afterEach(cleanup);

test('queryByProp', () => {
const { container } = render(
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/pretty-print.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';

import { render, prettyPrint } from '../../';
import { render, prettyPrint, cleanup } from '../../';

afterEach(cleanup);

test('it prints correctly with no children', () => {
const { container } = render(<View />);
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/queries.find.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Button, Image, Text, TextInput, View } from 'react-native';

import { render } from '../../';
import { cleanup, render } from '../../';

afterEach(cleanup);

test('find asynchronously finds elements', async () => {
const {
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/text-matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import cases from 'jest-in-case';
import { Button, Image, Text, TextInput, TouchableOpacity } from 'react-native';

import { getDefaultNormalizer, render } from '../../';
import { cleanup, getDefaultNormalizer, render } from '../../';

afterEach(cleanup);

cases(
'matches find case-sensitive full strings by default',
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/to-json.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';

import { prettyPrint, render, toJSON } from '../../';
import { cleanup, prettyPrint, render, toJSON } from '../../';

afterEach(cleanup);

test('it converts to json', () => {
function ParentComponent({ children }) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { View } from 'react-native';

import { render, waitForElementToBeRemoved } from '../../';
import { cleanup, render, waitForElementToBeRemoved } from '../../';

afterEach(cleanup);

jest.useFakeTimers();

Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/wait-for-element-to-be-removed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { View } from 'react-native';

import { render, waitForElementToBeRemoved } from '../../';
import { cleanup, render, waitForElementToBeRemoved } from '../../';

afterEach(cleanup);

test('resolves only when the element is removed', async () => {
class MutatedElement extends React.Component {
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/wait-for-element.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';

import { render, waitForElement } from '../../';
import { cleanup, render, waitForElement } from '../../';

afterEach(cleanup);

test('waits for element to appear', async () => {
const { rerender, getByTestId } = render(<View />);
Expand Down
4 changes: 3 additions & 1 deletion src/lib/__tests__/within.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Button, View } from 'react-native';

import { render, within } from '../../';
import { cleanup, render, within } from '../../';

afterEach(cleanup);

test('it works when scoping to a smaller set of elements', () => {
const { getByTestId } = render(
Expand Down
4 changes: 4 additions & 0 deletions src/preset/configure.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { asyncAct } from '../act-compat';
import { NativeTestEvent } from '../lib/events';
import { configure as configureNTL } from '../lib';

// Make this global for convenience, just like browser events
global.NativeTestEvent = NativeTestEvent;

configureNTL({
asyncWrapper: async cb => {
let result;
Expand Down
2 changes: 2 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export function render<Q extends Queries>(
options: RenderOptions<Q>,
): RenderResult<Q>;

export const cleanup: () => void;

export const act: (callback: () => void) => void;

export { queries, queryHelpers, within };
Expand Down