diff --git a/src/__tests__/render.test.tsx b/src/__tests__/render.test.tsx index 61010e565..1546b42b9 100644 --- a/src/__tests__/render.test.tsx +++ b/src/__tests__/render.test.tsx @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import * as React from 'react'; import { View, Text, TextInput, Pressable } from 'react-native'; +import { getConfig, resetToDefaults } from '../config'; import { render, screen, fireEvent, RenderAPI } from '..'; const PLACEHOLDER_FRESHNESS = 'Add custom freshness'; @@ -242,6 +243,14 @@ test('RenderAPI type', () => { test('returned output can be spread using rest operator', () => { // Next line should not throw // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { rerender, ...rest } = render(); + const { rerender, ...rest } = render(); expect(rest).toBeTruthy(); }); + +test('render calls detects host component names', () => { + resetToDefaults(); + expect(getConfig().hostComponentNames).toBeUndefined(); + + render(); + expect(getConfig().hostComponentNames).not.toBeUndefined(); +}); diff --git a/src/__tests__/renderHook.test.tsx b/src/__tests__/renderHook.test.tsx index 6e9f231a5..51c4e2696 100644 --- a/src/__tests__/renderHook.test.tsx +++ b/src/__tests__/renderHook.test.tsx @@ -1,4 +1,5 @@ import React, { ReactNode } from 'react'; +import TestRenderer from 'react-test-renderer'; import { renderHook } from '../pure'; test('gives comitted result', () => { @@ -94,3 +95,20 @@ test('props type is inferred correctly when initial props is explicitly undefine expect(result.current).toBe(6); }); + +/** + * This test makes sure that calling renderHook does + * not try to detect host component names in any form. + * But since there are numerous methods that could trigger that + * we check the count of renders using React Test Renderers. + */ +test('does render only once', () => { + jest.spyOn(TestRenderer, 'create'); + + renderHook(() => { + const [state, setState] = React.useState(1); + return [state, setState]; + }); + + expect(TestRenderer.create).toHaveBeenCalledTimes(1); +}); diff --git a/src/helpers/accessiblity.ts b/src/helpers/accessiblity.ts index 6fa73f49f..99a4af60e 100644 --- a/src/helpers/accessiblity.ts +++ b/src/helpers/accessiblity.ts @@ -4,8 +4,8 @@ import { StyleSheet, } from 'react-native'; import { ReactTestInstance } from 'react-test-renderer'; -import { getConfig } from '../config'; import { getHostSiblings } from './component-tree'; +import { getHostComponentNames } from './host-component-names'; type IsInaccessibleOptions = { cache?: WeakMap; @@ -99,8 +99,7 @@ export function isAccessibilityElement( return element.props.accessible; } - const hostComponentNames = getConfig().hostComponentNames; - + const hostComponentNames = getHostComponentNames(); return ( element?.type === hostComponentNames?.text || element?.type === hostComponentNames?.textInput || diff --git a/src/render.tsx b/src/render.tsx index de8a41600..05c6e0671 100644 --- a/src/render.tsx +++ b/src/render.tsx @@ -13,27 +13,41 @@ import { renderWithAct } from './render-act'; import { setRenderResult, screen } from './screen'; import { getQueriesForElement } from './within'; -export type RenderOptions = { +export interface RenderOptions { wrapper?: React.ComponentType; createNodeMock?: (element: React.ReactElement) => any; unstable_validateStringsRenderedWithinText?: boolean; -}; +} export type RenderResult = ReturnType; /** - * Renders test component deeply using react-test-renderer and exposes helpers + * Renders test component deeply using React Test Renderer and exposes helpers * to assert on the output. */ export default function render( + component: React.ReactElement, + options: RenderOptions = {} +) { + return renderInternal(component, options); +} + +export interface RenderInternalOptions extends RenderOptions { + detectHostComponentNames?: boolean; +} + +export function renderInternal( component: React.ReactElement, { wrapper: Wrapper, createNodeMock, unstable_validateStringsRenderedWithinText, - }: RenderOptions = {} + detectHostComponentNames = true, + }: RenderInternalOptions = {} ) { - configureHostComponentNamesIfNeeded(); + if (detectHostComponentNames) { + configureHostComponentNamesIfNeeded(); + } if (unstable_validateStringsRenderedWithinText) { return renderWithStringValidation(component, { diff --git a/src/renderHook.tsx b/src/renderHook.tsx index ada485dc4..f50973e25 100644 --- a/src/renderHook.tsx +++ b/src/renderHook.tsx @@ -1,6 +1,6 @@ import React from 'react'; import type { ComponentType } from 'react'; -import render from './render'; +import { renderInternal } from './render'; export type RenderHookResult = { rerender: (props: Props) => void; @@ -36,10 +36,13 @@ export function renderHook( return null; } - const { rerender: baseRerender, unmount } = render( + const { rerender: baseRerender, unmount } = renderInternal( // @ts-expect-error since option can be undefined, initialProps can be undefined when it should'nt , - { wrapper } + { + wrapper, + detectHostComponentNames: false, + } ); function rerender(rerenderCallbackProps: Props) {