Skip to content

Commit 7a498fe

Browse files
MattAgnthymikee
authored andcommitted
feat: use makeQueries for byText
1 parent 68c19a8 commit 7a498fe

File tree

5 files changed

+98
-125
lines changed

5 files changed

+98
-125
lines changed

src/__tests__/render.test.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ test('getByText, queryByText', () => {
108108

109109
expect(sameButton.props.children).toBe('not fresh');
110110
expect(() => getByText('InExistent')).toThrow(
111-
'No instances found with text "InExistent"'
111+
'Unable to find an element with text: InExistent'
112112
);
113113

114114
const zeroText = getByText('0');
115115

116116
expect(queryByText(/change/i)).toBe(button);
117117
expect(queryByText('InExistent')).toBeNull();
118-
expect(() => queryByText(/fresh/)).toThrow('Expected 1 but found 3');
118+
expect(() => queryByText(/fresh/)).toThrow(
119+
'Found multiple elements with text: /fresh/'
120+
);
119121
expect(queryByText('0')).toBe(zeroText);
120122
});
121123

@@ -147,7 +149,9 @@ test('getAllByText, queryAllByText', () => {
147149
const buttons = getAllByText(/fresh/i);
148150

149151
expect(buttons).toHaveLength(3);
150-
expect(() => getAllByText('InExistent')).toThrow('No instances found');
152+
expect(() => getAllByText('InExistent')).toThrow(
153+
'Unable to find an element with text: InExistent'
154+
);
151155

152156
expect(queryAllByText(/fresh/i)).toEqual(buttons);
153157
expect(queryAllByText('InExistent')).toHaveLength(0);

src/helpers/byText.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// @flow
2+
import * as React from 'react';
3+
import { makeQueries } from './makeQueries';
4+
import type { Queries } from './makeQueries';
5+
import { filterNodeByType } from './filterNodeByType';
6+
import { createLibraryNotSupportedError } from './errors';
7+
8+
const getChildrenAsText = (children, TextComponent, textContent = []) => {
9+
React.Children.forEach(children, (child) => {
10+
if (typeof child === 'string') {
11+
textContent.push(child);
12+
return;
13+
}
14+
15+
if (typeof child === 'number') {
16+
textContent.push(child.toString());
17+
return;
18+
}
19+
20+
if (child?.props?.children) {
21+
// Bail on traversing text children down the tree if current node (child)
22+
// has no text. In such situations, react-test-renderer will traverse down
23+
// this tree in a separate call and run this query again. As a result, the
24+
// query will match the deepest text node that matches requested text.
25+
if (filterNodeByType(child, TextComponent) && textContent.length === 0) {
26+
return;
27+
}
28+
29+
getChildrenAsText(child.props.children, TextComponent, textContent);
30+
}
31+
});
32+
33+
return textContent;
34+
};
35+
36+
const getNodeByText = (node, text: string | RegExp) => {
37+
try {
38+
const { Text } = require('react-native');
39+
const isTextComponent = filterNodeByType(node, Text);
40+
if (isTextComponent) {
41+
const textChildren = getChildrenAsText(node.props.children, Text);
42+
if (textChildren) {
43+
const textToTest = textChildren.join('');
44+
return typeof text === 'string'
45+
? text === textToTest
46+
: text.test(textToTest);
47+
}
48+
}
49+
return false;
50+
} catch (error) {
51+
throw createLibraryNotSupportedError(error);
52+
}
53+
};
54+
55+
const queryAllByText = (
56+
instance: ReactTestInstance
57+
): ((text: string | RegExp) => Array<ReactTestInstance>) =>
58+
function queryAllByTextFn(text) {
59+
const results = instance.findAll((node) => getNodeByText(node, text));
60+
61+
return results;
62+
};
63+
64+
const getMultipleError = (text: string | RegExp) =>
65+
`Found multiple elements with text: ${String(text)}`;
66+
const getMissingError = (text: string | RegExp) =>
67+
`Unable to find an element with text: ${String(text)}`;
68+
69+
const {
70+
getBy: getByText,
71+
getAllBy: getAllByText,
72+
queryBy: queryByText,
73+
findBy: findByText,
74+
findAllBy: findAllByText,
75+
}: Queries<string | RegExp> = makeQueries(
76+
queryAllByText,
77+
getMissingError,
78+
getMultipleError
79+
);
80+
81+
export {
82+
getByText,
83+
getAllByText,
84+
queryByText,
85+
findByText,
86+
findAllByText,
87+
queryAllByText,
88+
};

src/helpers/findByAPI.js

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
import waitFor from '../waitFor';
33
import type { WaitForOptions } from '../waitFor';
44
import {
5-
getByText,
6-
getAllByText,
75
getByPlaceholderText,
86
getAllByPlaceholderText,
97
getByDisplayValue,
108
getAllByDisplayValue,
119
} from './getByAPI';
1210
import { findAllByTestId, findByTestId } from './byTestId';
11+
import { findAllByText, findByText } from './byText';
1312
import { throwRenamedFunctionError } from './errors';
1413

1514
export type FindByAPI = {|
@@ -56,26 +55,6 @@ const makeFindQuery = <Text, Result>(
5655
waitForOptions: WaitForOptions
5756
): Promise<Result> => waitFor(() => getQuery(instance)(text), waitForOptions);
5857

59-
export const findByText = (
60-
instance: ReactTestInstance
61-
): ((
62-
text: string | RegExp,
63-
waitForOptions?: WaitForOptions
64-
) => Promise<ReactTestInstance>) => (
65-
text: string | RegExp,
66-
waitForOptions: WaitForOptions = {}
67-
) => makeFindQuery(instance, getByText, text, waitForOptions);
68-
69-
export const findAllByText = (
70-
instance: ReactTestInstance
71-
): ((
72-
text: string | RegExp,
73-
waitForOptions?: WaitForOptions
74-
) => Promise<Array<ReactTestInstance>>) => (
75-
text: string | RegExp,
76-
waitForOptions: WaitForOptions = {}
77-
) => makeFindQuery(instance, getAllByText, text, waitForOptions);
78-
7958
export const findByPlaceholderText = (
8059
instance: ReactTestInstance
8160
): ((

src/helpers/getByAPI.js

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
throwRenamedFunctionError,
1111
} from './errors';
1212
import { getAllByTestId, getByTestId } from './byTestId';
13+
import { getAllByText, getByText } from './byText';
1314

1415
export type GetByAPI = {|
1516
getByText: (text: string | RegExp) => ReactTestInstance,
@@ -42,53 +43,6 @@ export type GetByAPI = {|
4243
getAllByPlaceholder: () => void,
4344
|};
4445

45-
const getNodeByText = (node, text) => {
46-
try {
47-
const { Text } = require('react-native');
48-
const isTextComponent = filterNodeByType(node, Text);
49-
if (isTextComponent) {
50-
const textChildren = getChildrenAsText(node.props.children, Text);
51-
if (textChildren) {
52-
const textToTest = textChildren.join('');
53-
return typeof text === 'string'
54-
? text === textToTest
55-
: text.test(textToTest);
56-
}
57-
}
58-
return false;
59-
} catch (error) {
60-
throw createLibraryNotSupportedError(error);
61-
}
62-
};
63-
64-
const getChildrenAsText = (children, TextComponent, textContent = []) => {
65-
React.Children.forEach(children, (child) => {
66-
if (typeof child === 'string') {
67-
textContent.push(child);
68-
return;
69-
}
70-
71-
if (typeof child === 'number') {
72-
textContent.push(child.toString());
73-
return;
74-
}
75-
76-
if (child?.props?.children) {
77-
// Bail on traversing text children down the tree if current node (child)
78-
// has no text. In such situations, react-test-renderer will traverse down
79-
// this tree in a separate call and run this query again. As a result, the
80-
// query will match the deepest text node that matches requested text.
81-
if (filterNodeByType(child, TextComponent) && textContent.length === 0) {
82-
return;
83-
}
84-
85-
getChildrenAsText(child.props.children, TextComponent, textContent);
86-
}
87-
});
88-
89-
return textContent;
90-
};
91-
9246
const getTextInputNodeByPlaceholderText = (node, placeholder) => {
9347
try {
9448
const { TextInput } = require('react-native');
@@ -119,20 +73,6 @@ const getTextInputNodeByDisplayValue = (node, value) => {
11973
}
12074
};
12175

122-
export const getByText = (
123-
instance: ReactTestInstance
124-
): ((text: string | RegExp) => ReactTestInstance) =>
125-
function getByTextFn(text: string | RegExp) {
126-
try {
127-
return instance.find((node) => getNodeByText(node, text));
128-
} catch (error) {
129-
throw new ErrorWithStack(
130-
prepareErrorMessage(error, 'text', text),
131-
getByTextFn
132-
);
133-
}
134-
};
135-
13676
export const getByPlaceholderText = (
13777
instance: ReactTestInstance
13878
): ((placeholder: string | RegExp) => ReactTestInstance) =>
@@ -165,20 +105,6 @@ export const getByDisplayValue = (
165105
}
166106
};
167107

168-
export const getAllByText = (
169-
instance: ReactTestInstance
170-
): ((text: string | RegExp) => Array<ReactTestInstance>) =>
171-
function getAllByTextFn(text: string | RegExp) {
172-
const results = instance.findAll((node) => getNodeByText(node, text));
173-
if (results.length === 0) {
174-
throw new ErrorWithStack(
175-
`No instances found with text: ${String(text)}`,
176-
getAllByTextFn
177-
);
178-
}
179-
return results;
180-
};
181-
182108
export const getAllByPlaceholderText = (
183109
instance: ReactTestInstance
184110
): ((placeholder: string | RegExp) => Array<ReactTestInstance>) =>

src/helpers/queryByAPI.js

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// @flow
22
import * as React from 'react';
33
import {
4-
getByText,
54
getByPlaceholderText,
65
getByDisplayValue,
7-
getAllByText,
86
getAllByPlaceholderText,
97
getAllByDisplayValue,
108
UNSAFE_getByType,
@@ -13,6 +11,7 @@ import {
1311
UNSAFE_getAllByProps,
1412
} from './getByAPI';
1513
import { queryByTestId, queryAllByTestId } from './byTestId';
14+
import { queryByText, queryAllByText } from './byText';
1615
import {
1716
createQueryByError,
1817
throwRemovedFunctionError,
@@ -55,17 +54,6 @@ export type QueryByAPI = {|
5554
queryAllByPlaceholder: () => void,
5655
|};
5756

58-
export const queryByText = (
59-
instance: ReactTestInstance
60-
): ((text: string | RegExp) => ReactTestInstance | null) =>
61-
function queryByTextFn(text: string | RegExp) {
62-
try {
63-
return getByText(instance)(text);
64-
} catch (error) {
65-
return createQueryByError(error, queryByTextFn);
66-
}
67-
};
68-
6957
export const queryByPlaceholderText = (
7058
instance: ReactTestInstance
7159
): ((placeholder: string | RegExp) => ReactTestInstance | null) =>
@@ -88,18 +76,6 @@ export const queryByDisplayValue = (
8876
}
8977
};
9078

91-
export const queryAllByText = (
92-
instance: ReactTestInstance
93-
): ((text: string | RegExp) => Array<ReactTestInstance>) => (
94-
text: string | RegExp
95-
) => {
96-
try {
97-
return getAllByText(instance)(text);
98-
} catch (error) {
99-
return [];
100-
}
101-
};
102-
10379
export const queryAllByPlaceholderText = (
10480
instance: ReactTestInstance
10581
): ((placeholder: string | RegExp) => Array<ReactTestInstance>) => (

0 commit comments

Comments
 (0)