Skip to content

Commit fcaca52

Browse files
fix: add prop to render to skip configureHostComponentNamesIfNeeded (#1425)
* Add prop to render to skip componentnamesconfig * refactor: render internal with extra options * refactor: apply renderInternal to renderHook * chore: add tests to check for single render * refactor: simplify code * refactor: finishing touches * chore: fix lint --------- Co-authored-by: Maciej Jastrzębski <[email protected]>
1 parent 7587e69 commit fcaca52

File tree

5 files changed

+55
-12
lines changed

5 files changed

+55
-12
lines changed

src/__tests__/render.test.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable no-console */
22
import * as React from 'react';
33
import { View, Text, TextInput, Pressable } from 'react-native';
4+
import { getConfig, resetToDefaults } from '../config';
45
import { render, screen, fireEvent, RenderAPI } from '..';
56

67
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
@@ -242,6 +243,14 @@ test('RenderAPI type', () => {
242243
test('returned output can be spread using rest operator', () => {
243244
// Next line should not throw
244245
// eslint-disable-next-line @typescript-eslint/no-unused-vars
245-
const { rerender, ...rest } = render(<View testID="inner" />);
246+
const { rerender, ...rest } = render(<View testID="test" />);
246247
expect(rest).toBeTruthy();
247248
});
249+
250+
test('render calls detects host component names', () => {
251+
resetToDefaults();
252+
expect(getConfig().hostComponentNames).toBeUndefined();
253+
254+
render(<View testID="test" />);
255+
expect(getConfig().hostComponentNames).not.toBeUndefined();
256+
});

src/__tests__/renderHook.test.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { ReactNode } from 'react';
2+
import TestRenderer from 'react-test-renderer';
23
import { renderHook } from '../pure';
34

45
test('gives comitted result', () => {
@@ -94,3 +95,20 @@ test('props type is inferred correctly when initial props is explicitly undefine
9495

9596
expect(result.current).toBe(6);
9697
});
98+
99+
/**
100+
* This test makes sure that calling renderHook does
101+
* not try to detect host component names in any form.
102+
* But since there are numerous methods that could trigger that
103+
* we check the count of renders using React Test Renderers.
104+
*/
105+
test('does render only once', () => {
106+
jest.spyOn(TestRenderer, 'create');
107+
108+
renderHook(() => {
109+
const [state, setState] = React.useState(1);
110+
return [state, setState];
111+
});
112+
113+
expect(TestRenderer.create).toHaveBeenCalledTimes(1);
114+
});

src/helpers/accessiblity.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import {
44
StyleSheet,
55
} from 'react-native';
66
import { ReactTestInstance } from 'react-test-renderer';
7-
import { getConfig } from '../config';
87
import { getHostSiblings } from './component-tree';
8+
import { getHostComponentNames } from './host-component-names';
99

1010
type IsInaccessibleOptions = {
1111
cache?: WeakMap<ReactTestInstance, boolean>;
@@ -99,8 +99,7 @@ export function isAccessibilityElement(
9999
return element.props.accessible;
100100
}
101101

102-
const hostComponentNames = getConfig().hostComponentNames;
103-
102+
const hostComponentNames = getHostComponentNames();
104103
return (
105104
element?.type === hostComponentNames?.text ||
106105
element?.type === hostComponentNames?.textInput ||

src/render.tsx

+19-5
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,41 @@ import { renderWithAct } from './render-act';
1313
import { setRenderResult, screen } from './screen';
1414
import { getQueriesForElement } from './within';
1515

16-
export type RenderOptions = {
16+
export interface RenderOptions {
1717
wrapper?: React.ComponentType<any>;
1818
createNodeMock?: (element: React.ReactElement) => any;
1919
unstable_validateStringsRenderedWithinText?: boolean;
20-
};
20+
}
2121

2222
export type RenderResult = ReturnType<typeof render>;
2323

2424
/**
25-
* Renders test component deeply using react-test-renderer and exposes helpers
25+
* Renders test component deeply using React Test Renderer and exposes helpers
2626
* to assert on the output.
2727
*/
2828
export default function render<T>(
29+
component: React.ReactElement<T>,
30+
options: RenderOptions = {}
31+
) {
32+
return renderInternal(component, options);
33+
}
34+
35+
export interface RenderInternalOptions extends RenderOptions {
36+
detectHostComponentNames?: boolean;
37+
}
38+
39+
export function renderInternal<T>(
2940
component: React.ReactElement<T>,
3041
{
3142
wrapper: Wrapper,
3243
createNodeMock,
3344
unstable_validateStringsRenderedWithinText,
34-
}: RenderOptions = {}
45+
detectHostComponentNames = true,
46+
}: RenderInternalOptions = {}
3547
) {
36-
configureHostComponentNamesIfNeeded();
48+
if (detectHostComponentNames) {
49+
configureHostComponentNamesIfNeeded();
50+
}
3751

3852
if (unstable_validateStringsRenderedWithinText) {
3953
return renderWithStringValidation(component, {

src/renderHook.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import type { ComponentType } from 'react';
3-
import render from './render';
3+
import { renderInternal } from './render';
44

55
export type RenderHookResult<Result, Props> = {
66
rerender: (props: Props) => void;
@@ -36,10 +36,13 @@ export function renderHook<Result, Props>(
3636
return null;
3737
}
3838

39-
const { rerender: baseRerender, unmount } = render(
39+
const { rerender: baseRerender, unmount } = renderInternal(
4040
// @ts-expect-error since option can be undefined, initialProps can be undefined when it should'nt
4141
<TestComponent renderCallbackProps={initialProps} />,
42-
{ wrapper }
42+
{
43+
wrapper,
44+
detectHostComponentNames: false,
45+
}
4346
);
4447

4548
function rerender(rerenderCallbackProps: Props) {

0 commit comments

Comments
 (0)