From cc10e54048afed6201369e1672cf3c175fefc78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 15 Nov 2018 21:45:52 +0100 Subject: [PATCH 1/3] fix(breaking): correct faulty implementation of finding by name --- package.json | 2 +- .../__snapshots__/shallow.test.js.snap | 8 +- src/__tests__/render.test.js | 19 +- src/__tests__/renderRNComponents.test.js | 55 +++++ src/debug.js | 2 +- src/helpers/getByAPI.js | 64 ++++-- yarn.lock | 200 ++++++------------ 7 files changed, 187 insertions(+), 163 deletions(-) create mode 100644 src/__tests__/renderRNComponents.test.js diff --git a/package.json b/package.json index 861d2a35e..2b11bd44d 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "jest": "^23.6.0", "metro-react-native-babel-preset": "^0.49.0", "react": "16.6.1", - "react-native": "^0.57.3", + "react-native": "^0.57.5", "react-test-renderer": "16.6.1", "release-it": "^7.6.2", "strip-ansi": "^5.0.0", diff --git a/src/__tests__/__snapshots__/shallow.test.js.snap b/src/__tests__/__snapshots__/shallow.test.js.snap index 6d5844e26..ec845ddca 100644 --- a/src/__tests__/__snapshots__/shallow.test.js.snap +++ b/src/__tests__/__snapshots__/shallow.test.js.snap @@ -13,11 +13,11 @@ exports[`shallow rendering React Test Instance 1`] = ` `; exports[`shallow rendering React elements 1`] = ` - - + Press me - - + + `; diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index eb0f98f6a..91365fffe 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -57,7 +57,7 @@ test('getByTestId, queryByTestId', () => { const component = getByTestId('bananaFresh'); expect(component.props.children).toBe('not fresh'); - expect(() => getByTestId('InExistent')).toThrow(); + expect(() => getByTestId('InExistent')).toThrow('No instances found'); expect(getByTestId('bananaFresh')).toBe(component); expect(queryByTestId('InExistent')).toBeNull(); @@ -76,7 +76,8 @@ test('getByName, queryByName', () => { sameButton.props.onPress(); expect(bananaFresh.props.children).toBe('not fresh'); - expect(() => getByName('InExistent')).toThrow(); + expect(() => getByName('InExistent')).toThrow('No instances found'); + expect(() => getByName(Text)).toThrow('Expected 1 but found 3'); expect(queryByName('Button')).toBe(button); expect(queryByName('InExistent')).toBeNull(); @@ -89,7 +90,7 @@ test('getAllByName, queryAllByName', () => { expect(text.props.children).toBe('Is the banana fresh?'); expect(status.props.children).toBe('not fresh'); expect(button.props.children).toBe('Change freshness!'); - expect(() => getAllByName('InExistent')).toThrow(); + expect(() => getAllByName('InExistent')).toThrow('No instances found'); expect(queryAllByName('Text')[1]).toBe(status); expect(queryAllByName('InExistent')).toHaveLength(0); @@ -104,7 +105,7 @@ test('getByText, queryByText', () => { const sameButton = getByText('not fresh'); expect(sameButton.props.children).toBe('not fresh'); - expect(() => getByText('InExistent')).toThrow(); + expect(() => getByText('InExistent')).toThrow('No instances found'); expect(queryByText(/change/i)).toBe(button); expect(queryByText('InExistent')).toBeNull(); @@ -115,7 +116,7 @@ test('getAllByText, queryAllByText', () => { const buttons = getAllByText(/fresh/i); expect(buttons).toHaveLength(3); - expect(() => getAllByText('InExistent')).toThrow(); + expect(() => getAllByText('InExistent')).toThrow('No instances found'); expect(queryAllByText(/fresh/i)).toEqual(buttons); expect(queryAllByText('InExistent')).toHaveLength(0); @@ -126,7 +127,9 @@ test('getByProps, queryByProps', () => { const primaryType = getByProps({ type: 'primary' }); expect(primaryType.props.children).toBe('Change freshness!'); - expect(() => getByProps({ type: 'inexistent' })).toThrow(); + expect(() => getByProps({ type: 'inexistent' })).toThrow( + 'No instances found' + ); expect(queryByProps({ type: 'primary' })).toBe(primaryType); expect(queryByProps({ type: 'inexistent' })).toBeNull(); @@ -137,7 +140,9 @@ test('getAllByProp, queryAllByProps', () => { const primaryTypes = getAllByProps({ type: 'primary' }); expect(primaryTypes).toHaveLength(1); - expect(() => getAllByProps({ type: 'inexistent' })).toThrow(); + expect(() => getAllByProps({ type: 'inexistent' })).toThrow( + 'No instances found' + ); expect(queryAllByProps({ type: 'primary' })).toEqual(primaryTypes); expect(queryAllByProps({ type: 'inexistent' })).toHaveLength(0); diff --git a/src/__tests__/renderRNComponents.test.js b/src/__tests__/renderRNComponents.test.js new file mode 100644 index 000000000..4efc1bc19 --- /dev/null +++ b/src/__tests__/renderRNComponents.test.js @@ -0,0 +1,55 @@ +// @flow +import React from 'react'; +import { + Image, + Text, + TextInput, + Modal, + View, + ScrollView, + ActivityIndicator, + TouchableOpacity, +} from 'react-native'; + +import { render } from '..'; + +class RNComponents extends React.Component<*> { + render() { + return ( + + + + + + {}}> + t1 + t2 + t3 + + + + + + ); + } +} + +test('getByName smoke test to see how unstable it gets', () => { + const { getByName } = render(); + expect(() => getByName('Image')).toThrow(); // – doesn't have displayName set properly + getByName('TextInput'); + expect(() => getByName('Modal')).toThrow(); // – doesn't have displayName set properly + getByName('View'); + getByName('ScrollView'); + expect(() => getByName('ActivityIndicator')).toThrow(); // – doesn't have displayName set properly + getByName('TouchableOpacity'); +}); + +test('getAllByName smoke test to see how unstable it gets', () => { + const { getAllByName } = render(); + + const [t1, t2, t3] = getAllByName('Text'); + expect(t1.props.children).toBe('t1'); + expect(t2.props.children).toBe('t2'); + expect(t3.props.children).toBe('t3'); +}); diff --git a/src/debug.js b/src/debug.js index 29320bf68..6aa050d49 100644 --- a/src/debug.js +++ b/src/debug.js @@ -1,7 +1,7 @@ // @flow /* eslint-disable no-console */ import * as React from 'react'; -import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies +import prettyFormat, { plugins } from 'pretty-format'; import shallow from './shallow'; import render from './render'; diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index 5fc2380ca..9c51d9d6a 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -1,24 +1,44 @@ // @flow import * as React from 'react'; +import prettyFormat from 'pretty-format'; import ErrorWithStack from './errorWithStack'; +const getNodeByType = (node, type) => node.type === type; + const getNodeByName = (node, name) => - node.type.name === name || - node.type.displayName === name || - node.type === name; + typeof node.type !== 'string' && + (node.type.displayName === name || node.type.name === name); + +const getNodeByText = (node, text) => { + try { + // eslint-disable-next-line + const { Text, TextInput } = require('react-native'); + return ( + (getNodeByType(node, Text) || getNodeByType(node, TextInput)) && + (typeof text === 'string' + ? text === node.props.children + : text.test(node.props.children)) + ); + } catch (error) { + throw new Error( + `Currently the only supported library to search by text is \`react-native\`.\n\n${error}` + ); + } +}; -const getNodeByText = (node, text) => - (getNodeByName(node, 'Text') || getNodeByName(node, 'TextInput')) && - (typeof text === 'string' - ? text === node.props.children - : text.test(node.props.children)); +const prepareErrorMessage = error => + // Strip info about custom predicate + error.message.replace(/ matching custom predicate[^]*/gm, ''); +// TODO: deprecate getByName(string | type) in favor of getByType(type) export const getByName = (instance: ReactTestInstance) => function getByNameFn(name: string | React.ComponentType<*>) { try { - return instance.find(node => getNodeByName(node, name)); + return typeof name === 'string' + ? instance.find(node => getNodeByName(node, name)) + : instance.findByType(name); } catch (error) { - throw new ErrorWithStack(`Component not found.`, getByNameFn); + throw new ErrorWithStack(prepareErrorMessage(error), getByNameFn); } }; @@ -27,7 +47,7 @@ export const getByText = (instance: ReactTestInstance) => try { return instance.find(node => getNodeByText(node, text)); } catch (error) { - throw new ErrorWithStack(`Component not found.`, getByTextFn); + throw new ErrorWithStack(prepareErrorMessage(error), getByTextFn); } }; @@ -36,7 +56,7 @@ export const getByProps = (instance: ReactTestInstance) => try { return instance.findByProps(props); } catch (error) { - throw new ErrorWithStack(`Component not found.`, getByPropsFn); + throw new ErrorWithStack(prepareErrorMessage(error), getByPropsFn); } }; @@ -45,15 +65,19 @@ export const getByTestId = (instance: ReactTestInstance) => try { return instance.findByProps({ testID }); } catch (error) { - throw new ErrorWithStack(`Component not found.`, getByTestIdFn); + throw new ErrorWithStack(prepareErrorMessage(error), getByTestIdFn); } }; +// TODO: deprecate getAllByName(string | type) in favor of getAllByType(type) export const getAllByName = (instance: ReactTestInstance) => function getAllByNameFn(name: string | React.ComponentType<*>) { - const results = instance.findAll(node => getNodeByName(node, name)); + const results = + typeof name === 'string' + ? instance.findAll(node => getNodeByName(node, name)) + : instance.findAllByType(name); if (results.length === 0) { - throw new ErrorWithStack(`Components not found.`, getAllByNameFn); + throw new ErrorWithStack('No instances found', getAllByNameFn); } return results; }; @@ -62,7 +86,10 @@ export const getAllByText = (instance: ReactTestInstance) => function getAllByTextFn(text: string | RegExp) { const results = instance.findAll(node => getNodeByText(node, text)); if (results.length === 0) { - throw new ErrorWithStack(`Components not found.`, getAllByTextFn); + throw new ErrorWithStack( + `No instances found with text: ${String(text)}`, + getAllByTextFn + ); } return results; }; @@ -71,7 +98,10 @@ export const getAllByProps = (instance: ReactTestInstance) => function getAllByPropsFn(props: { [propName: string]: any }) { const results = instance.findAllByProps(props); if (results.length === 0) { - throw new ErrorWithStack(`Components not found.`, getAllByPropsFn); + throw new ErrorWithStack( + `No instances found with props:\n${prettyFormat(props)}`, + getAllByPropsFn + ); } return results; }; diff --git a/yarn.lock b/yarn.lock index e6b91faba..a9ec9b0e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1014,7 +1014,7 @@ babel-core@7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" -babel-core@^6.0.0, babel-core@^6.26.0, babel-core@^6.7.2: +babel-core@^6.0.0, babel-core@^6.26.0: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" dependencies: @@ -1070,14 +1070,6 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - esutils "^2.0.2" - babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -1184,7 +1176,7 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.8.0: +babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" dependencies: @@ -1207,27 +1199,15 @@ babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - -babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - -babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: +babel-plugin-syntax-object-rest-spread@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" -babel-plugin-syntax-trailing-function-commas@^6.22.0, babel-plugin-syntax-trailing-function-commas@^6.8.0: +babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" @@ -1243,28 +1223,19 @@ babel-plugin-transform-async-to-generator@^6.22.0: babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-properties@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - dependencies: - babel-helper-function-name "^6.24.1" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0, babel-plugin-transform-es2015-arrow-functions@^6.8.0: +babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0, babel-plugin-transform-es2015-block-scoped-functions@^6.8.0: +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.8.0: +babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" dependencies: @@ -1274,7 +1245,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es20 babel-types "^6.26.0" lodash "^4.17.4" -babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.8.0: +babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" dependencies: @@ -1288,14 +1259,14 @@ babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-cla babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.8.0: +babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-destructuring@^6.23.0, babel-plugin-transform-es2015-destructuring@^6.8.0: +babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: @@ -1308,13 +1279,13 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-es2015-for-of@^6.23.0, babel-plugin-transform-es2015-for-of@^6.8.0: +babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.8.0: +babel-plugin-transform-es2015-function-name@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" dependencies: @@ -1322,7 +1293,7 @@ babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es20 babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-es2015-literals@^6.22.0, babel-plugin-transform-es2015-literals@^6.8.0: +babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" dependencies: @@ -1336,7 +1307,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.8.0: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" dependencies: @@ -1361,14 +1332,14 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.8.0: +babel-plugin-transform-es2015-object-super@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.8.0: +babel-plugin-transform-es2015-parameters@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" dependencies: @@ -1379,14 +1350,14 @@ babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015- babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.8.0: +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: +babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" dependencies: @@ -1400,7 +1371,7 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-es2015-template-literals@^6.22.0, babel-plugin-transform-es2015-template-literals@^6.8.0: +babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" dependencies: @@ -1420,18 +1391,6 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-runtime "^6.22.0" regexpu-core "^2.0.0" -babel-plugin-transform-es3-member-expression-literals@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-member-expression-literals/-/babel-plugin-transform-es3-member-expression-literals-6.22.0.tgz#733d3444f3ecc41bef8ed1a6a4e09657b8969ebb" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es3-property-literals@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-property-literals/-/babel-plugin-transform-es3-property-literals-6.22.0.tgz#b2078d5842e22abf40f73e8cde9cd3711abd5758" - dependencies: - babel-runtime "^6.22.0" - babel-plugin-transform-exponentiation-operator@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" @@ -1440,34 +1399,6 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-flow-strip-types@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-object-rest-spread@^6.8.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - -babel-plugin-transform-react-display-name@^6.8.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" - dependencies: - babel-helper-builder-react-jsx "^6.24.1" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" @@ -1516,38 +1447,38 @@ babel-preset-env@1.7.0: invariant "^2.2.2" semver "^5.3.0" -babel-preset-fbjs@^2.1.2: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-2.3.0.tgz#92ff81307c18b926895114f9828ae1674c097f80" - dependencies: - babel-plugin-check-es2015-constants "^6.8.0" - babel-plugin-syntax-class-properties "^6.8.0" - babel-plugin-syntax-flow "^6.8.0" - babel-plugin-syntax-jsx "^6.8.0" - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-plugin-syntax-trailing-function-commas "^6.8.0" - babel-plugin-transform-class-properties "^6.8.0" - babel-plugin-transform-es2015-arrow-functions "^6.8.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.8.0" - babel-plugin-transform-es2015-block-scoping "^6.8.0" - babel-plugin-transform-es2015-classes "^6.8.0" - babel-plugin-transform-es2015-computed-properties "^6.8.0" - babel-plugin-transform-es2015-destructuring "^6.8.0" - babel-plugin-transform-es2015-for-of "^6.8.0" - babel-plugin-transform-es2015-function-name "^6.8.0" - babel-plugin-transform-es2015-literals "^6.8.0" - babel-plugin-transform-es2015-modules-commonjs "^6.8.0" - babel-plugin-transform-es2015-object-super "^6.8.0" - babel-plugin-transform-es2015-parameters "^6.8.0" - babel-plugin-transform-es2015-shorthand-properties "^6.8.0" - babel-plugin-transform-es2015-spread "^6.8.0" - babel-plugin-transform-es2015-template-literals "^6.8.0" - babel-plugin-transform-es3-member-expression-literals "^6.8.0" - babel-plugin-transform-es3-property-literals "^6.8.0" - babel-plugin-transform-flow-strip-types "^6.8.0" - babel-plugin-transform-object-rest-spread "^6.8.0" - babel-plugin-transform-react-display-name "^6.8.0" - babel-plugin-transform-react-jsx "^6.8.0" +babel-preset-fbjs@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.1.0.tgz#6d1438207369d96384d09257b01602dd0dda6608" + integrity sha512-j+B9xZsnqWFxHaqt3B8aFYftSgrcgbO5NF3mTtHYd6R442NJW2aBk3k+XvxXwIia98UuZxCg8psZY79bXbhwew== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-member-expression-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-property-literals" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" babel-preset-fbjs@^3.0.1: version "3.0.1" @@ -3180,13 +3111,14 @@ fbjs-css-vars@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.1.tgz#836d876e887d702f45610f5ebd2fbeef649527fc" -fbjs-scripts@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz#b854de7a11e62a37f72dab9aaf4d9b53c4a03174" +fbjs-scripts@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.0.1.tgz#7d8d09d76e83308bf3b1fc7b4c9c6fd081c5ef64" + integrity sha512-x8bfX7k0z5B24Ue0YqjZq/2QxxaKZUNbkGdX//zbQDElMJFqBRrvRi8O3qds7UNNzs78jYqIYCS32Sk/wu5UJg== dependencies: + "@babel/core" "^7.0.0" ansi-colors "^1.0.1" - babel-core "^6.7.2" - babel-preset-fbjs "^2.1.2" + babel-preset-fbjs "^3.0.0" core-js "^2.4.1" cross-spawn "^5.1.0" fancy-log "^1.3.2" @@ -5975,9 +5907,10 @@ react-is@^16.6.1: version "16.6.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.6.1.tgz#f77b1c3d901be300abe8d58645b7a59e794e5982" -react-native@^0.57.3: - version "0.57.3" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.57.3.tgz#ba395bc139f13430caa41614ac6197f8446e106e" +react-native@^0.57.5: + version "0.57.5" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.57.5.tgz#f1dbcbf1f889845fba954f3e0d47e61cf89d41d9" + integrity sha512-b/RNXcifPr4CrYZEAWmyD+W//KWZkEO4p6/TOZmLPP4M+vkqWqt0wmSW6JWn1bTEeZmRjx1JJZeVtYmtIVl/KA== dependencies: "@babel/runtime" "^7.0.0" absolute-path "^0.0.0" @@ -5995,7 +5928,7 @@ react-native@^0.57.3: escape-string-regexp "^1.0.5" event-target-shim "^1.0.5" fbjs "^1.0.0" - fbjs-scripts "^0.8.1" + fbjs-scripts "^1.0.0" fs-extra "^1.0.0" glob "^7.1.1" graceful-fs "^4.1.3" @@ -6028,7 +5961,7 @@ react-native@^0.57.3: shell-quote "1.6.1" stacktrace-parser "^0.1.3" ws "^1.1.0" - xcode "^0.9.1" + xcode "^1.0.0" xmldoc "^0.4.0" yargs "^9.0.0" @@ -7405,9 +7338,10 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -xcode@^0.9.1: - version "0.9.3" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-0.9.3.tgz#910a89c16aee6cc0b42ca805a6d0b4cf87211cf3" +xcode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-1.0.0.tgz#e1f5b1443245ded38c180796df1a10fdeda084ec" + integrity sha1-4fWxRDJF3tOMGAeW3xoQ/e2ghOw= dependencies: pegjs "^0.10.0" simple-plist "^0.2.1" From 3a84eed757d4d719cb66767f81bc0b0eda312c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 15 Nov 2018 22:04:15 +0100 Subject: [PATCH 2/3] chore: update docs --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 381a246d9..586658ca5 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This library is a replacement for [Enzyme](http://airbnb.io/enzyme/). ```jsx import { render, fireEvent } from 'react-native-testing-library'; import { QuestionsBoard } from '../QuestionsBoard'; +import { Question } from '../Question'; function setAnswer(question, answer) { fireEvent.changeText(question, answer); @@ -37,7 +38,7 @@ function setAnswer(question, answer) { test('should verify two questions', () => { const { getAllByName, getByText } = render(); - const allQuestions = getAllByName('Question'); + const allQuestions = getAllByName(Question); setAnswer(allQuestions[0], 'a1'); setAnswer(allQuestions[1], 'a2'); @@ -84,7 +85,7 @@ Deeply render given React element and returns helpers to query the output. ```jsx import { render } from 'react-native-testing-library'; -const { getByTestId, getByName /*...*/ } = render(); +const { getByTestId, getByText /*...*/ } = render(); ``` Returns a `RenderResult` object with following properties: @@ -104,13 +105,13 @@ type ReactTestInstance = { }; ``` -### `getByName: (name: string | React.ComponentType<*>)` +### `getByName: (name: React.ComponentType<*>)` -A method returning a `ReactTestInstance` with matching name – may be a string or React Element. Throws when no matches. +A method returning a `ReactTestInstance` with matching a React component type. Throws when no matches. -### `getAllByName: (name: string | React.ComponentType<*>)` +### `getAllByName: (name: React.ComponentType<*>)` -A method returning an array of `ReactTestInstance`s with matching name – may be a string or React Element. +A method returning an array of `ReactTestInstance`s with matching a React component type. ### `getByText: (text: string | RegExp)` From 17fcf398633599bc1aa8e7164066537e1bc35f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sat, 17 Nov 2018 18:16:39 +0100 Subject: [PATCH 3/3] refactor: code review --- src/fireEvent.js | 2 +- src/helpers/errorWithStack.js | 9 --------- src/helpers/errors.js | 16 ++++++++++++++++ src/helpers/getByAPI.js | 16 +++++++--------- 4 files changed, 24 insertions(+), 19 deletions(-) delete mode 100644 src/helpers/errorWithStack.js create mode 100644 src/helpers/errors.js diff --git a/src/fireEvent.js b/src/fireEvent.js index c97ccab86..8386ecd6a 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -1,5 +1,5 @@ // @flow -import ErrorWithStack from './helpers/errorWithStack'; +import { ErrorWithStack } from './helpers/errors'; const findEventHandler = (element: ReactTestInstance, eventName: string) => { const eventHandler = toEventHandlerName(eventName); diff --git a/src/helpers/errorWithStack.js b/src/helpers/errorWithStack.js deleted file mode 100644 index 1ee1cb3c2..000000000 --- a/src/helpers/errorWithStack.js +++ /dev/null @@ -1,9 +0,0 @@ -// @flow -export default class ErrorWithStack extends Error { - constructor(message: ?string, callsite: Function) { - super(message); - if (Error.captureStackTrace) { - Error.captureStackTrace(this, callsite); - } - } -} diff --git a/src/helpers/errors.js b/src/helpers/errors.js new file mode 100644 index 000000000..a0e998e60 --- /dev/null +++ b/src/helpers/errors.js @@ -0,0 +1,16 @@ +// @flow +export class ErrorWithStack extends Error { + constructor(message: ?string, callsite: Function) { + super(message); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, callsite); + } + } +} + +export const createLibraryNotSupportedError = (error: Error) => + new Error( + `Currently the only supported library to search by text is "react-native".\n\n${ + error.message + }` + ); diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index 9c51d9d6a..8af8fa860 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -1,11 +1,11 @@ // @flow import * as React from 'react'; import prettyFormat from 'pretty-format'; -import ErrorWithStack from './errorWithStack'; +import { ErrorWithStack, createLibraryNotSupportedError } from './errors'; -const getNodeByType = (node, type) => node.type === type; +const filterNodeByType = (node, type) => node.type === type; -const getNodeByName = (node, name) => +const filterNodeByName = (node, name) => typeof node.type !== 'string' && (node.type.displayName === name || node.type.name === name); @@ -14,15 +14,13 @@ const getNodeByText = (node, text) => { // eslint-disable-next-line const { Text, TextInput } = require('react-native'); return ( - (getNodeByType(node, Text) || getNodeByType(node, TextInput)) && + (filterNodeByType(node, Text) || filterNodeByType(node, TextInput)) && (typeof text === 'string' ? text === node.props.children : text.test(node.props.children)) ); } catch (error) { - throw new Error( - `Currently the only supported library to search by text is \`react-native\`.\n\n${error}` - ); + throw createLibraryNotSupportedError(error); } }; @@ -35,7 +33,7 @@ export const getByName = (instance: ReactTestInstance) => function getByNameFn(name: string | React.ComponentType<*>) { try { return typeof name === 'string' - ? instance.find(node => getNodeByName(node, name)) + ? instance.find(node => filterNodeByName(node, name)) : instance.findByType(name); } catch (error) { throw new ErrorWithStack(prepareErrorMessage(error), getByNameFn); @@ -74,7 +72,7 @@ export const getAllByName = (instance: ReactTestInstance) => function getAllByNameFn(name: string | React.ComponentType<*>) { const results = typeof name === 'string' - ? instance.findAll(node => getNodeByName(node, name)) + ? instance.findAll(node => filterNodeByName(node, name)) : instance.findAllByType(name); if (results.length === 0) { throw new ErrorWithStack('No instances found', getAllByNameFn);