From 96b6b3f90e0bbd2e83791780170a7f701ae7673f Mon Sep 17 00:00:00 2001 From: daveols <10344370+daveols@users.noreply.github.com> Date: Mon, 13 Jul 2020 18:18:04 +1000 Subject: [PATCH 1/5] update react-navigation test example to use v4 --- examples/__tests__/react-navigation.js | 3 ++- package.json | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/__tests__/react-navigation.js b/examples/__tests__/react-navigation.js index 1be2baa..9bd4b31 100644 --- a/examples/__tests__/react-navigation.js +++ b/examples/__tests__/react-navigation.js @@ -1,7 +1,8 @@ import '@testing-library/jest-native/extend-expect'; import React from 'react'; import { Button, Text, View } from 'react-native'; -import { createStackNavigator, createAppContainer, withNavigation } from 'react-navigation'; +import { createStackNavigator } from 'react-navigation-stack'; +import { createAppContainer, withNavigation } from 'react-navigation'; import { render, fireEvent } from '../../src'; diff --git a/package.json b/package.json index 8a3e201..c5e7265 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,9 @@ "react-intl-native": "^2.1.2", "react-native": "^0.61.1", "react-native-gesture-handler": "^1.1.0", - "react-navigation": "^3.5.1", + "react-native-screens": "^2.9.0", + "react-navigation": "^4.4.0", + "react-navigation-stack": "^1.7.3", "react-redux": "^7.0.3", "react-test-renderer": "16.9.0", "redux": "^4.0.1", From f4866e0645497f816899d02eb232aaf36f95f619 Mon Sep 17 00:00:00 2001 From: daveols <10344370+daveols@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:42:27 +1000 Subject: [PATCH 2/5] support react-native 0.63.0 --- examples/__tests__/react-navigation.js | 4 +- package.json | 14 +-- src/__tests__/__snapshots__/fetch.js.snap | 4 +- src/__tests__/events.js | 27 ++--- src/__tests__/misc.js | 122 +++++++++++++++++++++- src/index.js | 2 +- src/lib/__tests__/queries.find.js | 2 +- src/lib/events.js | 5 +- src/preset/configure.js | 1 + src/preset/mock-component.js | 8 +- src/preset/mock-modules.js | 64 +++++++++--- src/preset/mock-refresh-control.js | 19 ++++ src/preset/mock-scroll-view.js | 23 ++++ 13 files changed, 251 insertions(+), 44 deletions(-) create mode 100644 src/preset/mock-refresh-control.js create mode 100644 src/preset/mock-scroll-view.js diff --git a/examples/__tests__/react-navigation.js b/examples/__tests__/react-navigation.js index 9bd4b31..86e0040 100644 --- a/examples/__tests__/react-navigation.js +++ b/examples/__tests__/react-navigation.js @@ -4,7 +4,7 @@ import { Button, Text, View } from 'react-native'; import { createStackNavigator } from 'react-navigation-stack'; import { createAppContainer, withNavigation } from 'react-navigation'; -import { render, fireEvent } from '../../src'; +import { render, fireEvent, cleanup } from '../../src'; jest .mock('react-native/Libraries/Animated/src/NativeAnimatedHelper') @@ -57,6 +57,8 @@ function renderWithNavigation({ screens = {}, navigatorConfig = {} } = {}) { return { ...render(), navigationTestRenderer: App }; } +afterEach(cleanup); + test('full app rendering/navigating', async () => { const { findByText, getByTestId, getByTitle } = renderWithNavigation(); diff --git a/package.json b/package.json index c5e7265..ce6fb92 100644 --- a/package.json +++ b/package.json @@ -44,30 +44,30 @@ }, "devDependencies": { "@babel/cli": "7.2.3", - "@babel/core": "7.4.0", + "@babel/core": "7.8.4", "@babel/runtime": "7.4.0", - "@testing-library/jest-native": "^3.0.0", + "@testing-library/jest-native": "^3.1.0", "commitizen": "^3.0.7", "cz-conventional-changelog": "^2.1.0", "husky": "^1.3.1", "intl": "^1.2.5", - "jest": "24.5.0", + "jest": "25.1.0", "jest-fetch-mock": "^2.1.1", "jest-in-case": "^1.0.2", - "metro-react-native-babel-preset": "^0.52.0", + "metro-react-native-babel-preset": "^0.59.0", "prettier": "^1.16.4", "pretty-quick": "^1.10.0", - "react": "16.9.0", + "react": "16.13.1", "react-hooks-testing-library": "^0.5.0", "react-intl": "^2.8.0", "react-intl-native": "^2.1.2", - "react-native": "^0.61.1", + "react-native": "^0.63.0", "react-native-gesture-handler": "^1.1.0", "react-native-screens": "^2.9.0", "react-navigation": "^4.4.0", "react-navigation-stack": "^1.7.3", "react-redux": "^7.0.3", - "react-test-renderer": "16.9.0", + "react-test-renderer": "16.13.1", "redux": "^4.0.1", "semantic-release": "^15.13.3", "snapshot-diff": "0.5.1" diff --git a/src/__tests__/__snapshots__/fetch.js.snap b/src/__tests__/__snapshots__/fetch.js.snap index bfa83cf..13a7104 100644 --- a/src/__tests__/__snapshots__/fetch.js.snap +++ b/src/__tests__/__snapshots__/fetch.js.snap @@ -11,9 +11,7 @@ exports[`Fetch makes an API call and displays the greeting when load-greeting is } > - + Fetch diff --git a/src/__tests__/events.js b/src/__tests__/events.js index 78dd80f..85e40f8 100644 --- a/src/__tests__/events.js +++ b/src/__tests__/events.js @@ -1,6 +1,17 @@ import React from 'react'; import '@testing-library/jest-native/extend-expect'; -import { Button, Image, Text, TextInput, TouchableHighlight } from 'react-native'; +import { + ActivityIndicator, + Button, + Image, + Pressable, + Text, + TextInput, + TouchableNativeFeedback, + TouchableHighlight, + TouchableOpacity, + TouchableWithoutFeedback, +} from 'react-native'; import { render, fireEvent, eventMap, getEventHandlerName, wait, cleanup } from '../'; @@ -117,20 +128,10 @@ test('calling a handler if a Button is disabled does not work', () => { expect(handleEvent).toBeCalledTimes(0); }); -test('calling a handler if a Touchable is disabled does not work', () => { - const handleEvent = jest.fn(); - const { getByText } = render( - - touchable - , - ); - expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); - expect(handleEvent).toBeCalledTimes(0); -}); - test('calling an event that has no defined handler throws', () => { const { getByText } = render(test); - expect(() => fireEvent.press(getByText('test'))).not.toThrow(); + const text = getByText('test'); + expect(() => fireEvent.changeText(text).toThrow()); }); test('calling an event sets nativeEvent properly', () => { diff --git a/src/__tests__/misc.js b/src/__tests__/misc.js index cc59f72..c0937a6 100644 --- a/src/__tests__/misc.js +++ b/src/__tests__/misc.js @@ -1,11 +1,40 @@ -import React from 'react'; -import { Button, Picker, Switch, Text, View, TextInput } from 'react-native'; +import React, { useEffect, useRef } from 'react'; +import { + Button, + Picker, + Pressable, + ScrollView, + Switch, + Text, + TextInput, + TouchableHighlight, + TouchableNativeFeedback, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native'; import { toMatchDiffSnapshot } from 'snapshot-diff'; import { cleanup, fireEvent, render } from '../'; afterEach(cleanup); +test(' works', () => { + const fireZeMissiles = jest.fn(); + + function Wrapper() { + return ( + + missiles + + ); + } + const { getByText } = render(); + + fireEvent.press(getByText('missiles')); + expect(fireZeMissiles).toBeCalledTimes(1); +}); + test(' works', () => { function Wrapper() { const [value, setValue] = React.useState('js'); @@ -23,6 +52,95 @@ test(' works', () => { expect(() => findByDisplayValue('js')).not.toThrow(); }); +test(' instance methods are mocked', () => { + function Wrapper() { + const ref = useRef(); + + useEffect(() => { + ref.current.scrollTo(0); + }, []); + + return ( + + Some content + + ); + } + const { getByText, debug } = render(); + + expect(() => getByText('Some content')).not.toThrow(); +}); + +test(' instance methods are mocked', () => { + function Wrapper() { + const ref = useRef(); + + useEffect(() => { + ref.current.clear(); + }, []); + + return ; + } + const { getByDisplayValue } = render(); + + expect(() => getByDisplayValue('yo')).not.toThrow(); +}); + +test('calling a handler if a Touchable is disabled does not work', () => { + const handleEvent = jest.fn(); + const { getByText } = render( + + touchable + , + ); + expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); + expect(handleEvent).toBeCalledTimes(0); +}); + +test('calling a TouchableHighlight handler works', () => { + const handleEvent = jest.fn(); + const { getByText } = render( + + touchable + , + ); + expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); + expect(handleEvent).toBeCalledTimes(1); +}); + +test('calling a TouchableNativeFeedback handler works', () => { + const handleEvent = jest.fn(); + const { getByText } = render( + + touchable + , + ); + expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); + expect(handleEvent).toBeCalledTimes(1); +}); + +test('calling a TouchableOpacity handler works', () => { + const handleEvent = jest.fn(); + const { getByText } = render( + + touchable + , + ); + expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); + expect(handleEvent).toBeCalledTimes(1); +}); + +test('calling a TouchableWithoutFeedback handler works ', () => { + const handleEvent = jest.fn(); + const { getByText } = render( + + touchable + , + ); + expect(() => fireEvent.press(getByText('touchable'))).not.toThrow(); + expect(handleEvent).toBeCalledTimes(1); +}); + test('fragments can show diffs', () => { function TestComponent() { const [count, setCount] = React.useState(0); diff --git a/src/index.js b/src/index.js index 6f7ac4e..0b62fe3 100644 --- a/src/index.js +++ b/src/index.js @@ -35,7 +35,7 @@ function render(ui, { options = {}, wrapper: WrapperComponent, queries } = {}) { renderers.add(testRenderer); const wrappers = proxyElement(testRenderer.root).findAll(n => n.type === 'View'); - const baseElement = wrappers[0]; // Includes YellowBox and your render + const baseElement = wrappers[0]; const container = wrappers[1]; // Includes only your render return { diff --git a/src/lib/__tests__/queries.find.js b/src/lib/__tests__/queries.find.js index f92aba8..6bbebd6 100644 --- a/src/lib/__tests__/queries.find.js +++ b/src/lib/__tests__/queries.find.js @@ -33,7 +33,7 @@ test('find asynchronously finds elements', async () => {