Skip to content

Commit aa182d1

Browse files
committed
refactor: use HostElement type in place of ReactTestInstance
1 parent 5295332 commit aa182d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+279
-332
lines changed

src/__tests__/host-component-names.test.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from 'react';
22
import { View } from 'react-native';
3-
import TestRenderer from 'react-test-renderer';
43
import { configureInternal, getConfig } from '../config';
54
import {
65
getHostComponentNames,

src/__tests__/render-hook.test.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* eslint-disable jest/no-conditional-expect */
22
import React, { ReactNode } from 'react';
3-
import TestRenderer from 'react-test-renderer';
43
import * as internalRenderer from '../renderer/renderer';
54
import { renderHook } from '../pure';
6-
import { getConfig } from '../config';
75

86
test('gives committed result', () => {
97
const { result } = renderHook(() => {

src/fire-event.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ReactTestInstance } from 'react-test-renderer';
21
import {
32
ViewProps,
43
TextProps,
@@ -13,11 +12,12 @@ import { isPointerEventEnabled } from './helpers/pointer-events';
1312
import { isTextInputEditable } from './helpers/text-input';
1413
import { Point, StringWithAutocomplete } from './types';
1514
import { nativeState } from './native-state';
15+
import { HostElement } from './renderer/host-element';
1616
import { EventBuilder } from './user-event/event-builder';
1717

1818
type EventHandler = (...args: unknown[]) => unknown;
1919

20-
export function isTouchResponder(element: ReactTestInstance) {
20+
export function isTouchResponder(element: HostElement) {
2121
if (!isHostElement(element)) {
2222
return false;
2323
}
@@ -57,9 +57,9 @@ const textInputEventsIgnoringEditableProp = new Set([
5757
]);
5858

5959
export function isEventEnabled(
60-
element: ReactTestInstance,
60+
element: HostElement,
6161
eventName: string,
62-
nearestTouchResponder?: ReactTestInstance,
62+
nearestTouchResponder?: HostElement,
6363
) {
6464
if (isHostTextInput(nearestTouchResponder)) {
6565
return (
@@ -82,9 +82,9 @@ export function isEventEnabled(
8282
}
8383

8484
function findEventHandler(
85-
element: ReactTestInstance,
85+
element: HostElement,
8686
eventName: string,
87-
nearestTouchResponder?: ReactTestInstance,
87+
nearestTouchResponder?: HostElement,
8888
): EventHandler | null {
8989
const touchResponder = isTouchResponder(element) ? element : nearestTouchResponder;
9090

@@ -101,7 +101,7 @@ function findEventHandler(
101101
return findEventHandler(element.parent, eventName, touchResponder);
102102
}
103103

104-
function getEventHandler(element: ReactTestInstance, eventName: string) {
104+
function getEventHandler(element: HostElement, eventName: string) {
105105
const eventHandlerName = getEventHandlerName(eventName);
106106
if (typeof element.props[eventHandlerName] === 'function') {
107107
return element.props[eventHandlerName];
@@ -131,7 +131,7 @@ type EventName = StringWithAutocomplete<
131131
| EventNameExtractor<ScrollViewProps>
132132
>;
133133

134-
function fireEvent(element: ReactTestInstance, eventName: EventName, ...data: unknown[]) {
134+
function fireEvent(element: HostElement, eventName: EventName, ...data: unknown[]) {
135135
setNativeStateIfNeeded(element, eventName, data[0]);
136136

137137
const handler = findEventHandler(element, eventName);
@@ -147,7 +147,7 @@ function fireEvent(element: ReactTestInstance, eventName: EventName, ...data: un
147147
return returnValue;
148148
}
149149

150-
fireEvent.press = (element: ReactTestInstance, ...data: unknown[]) => {
150+
fireEvent.press = (element: HostElement, ...data: unknown[]) => {
151151
const nativeData =
152152
data.length === 1 &&
153153
typeof data[0] === 'object' &&
@@ -178,10 +178,10 @@ fireEvent.press = (element: ReactTestInstance, ...data: unknown[]) => {
178178
fireEvent(element, 'responderRelease', responderReleaseEvent);
179179
};
180180

181-
fireEvent.changeText = (element: ReactTestInstance, ...data: unknown[]) =>
181+
fireEvent.changeText = (element: HostElement, ...data: unknown[]) =>
182182
fireEvent(element, 'changeText', ...data);
183183

184-
fireEvent.scroll = (element: ReactTestInstance, ...data: unknown[]) =>
184+
fireEvent.scroll = (element: HostElement, ...data: unknown[]) =>
185185
fireEvent(element, 'scroll', ...data);
186186

187187
export default fireEvent;
@@ -194,7 +194,7 @@ const scrollEventNames = new Set([
194194
'momentumScrollEnd',
195195
]);
196196

197-
function setNativeStateIfNeeded(element: ReactTestInstance, eventName: string, value: unknown) {
197+
function setNativeStateIfNeeded(element: HostElement, eventName: string, value: unknown) {
198198
if (
199199
eventName === 'changeText' &&
200200
typeof value === 'string' &&

src/helpers/__tests__/component-tree.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('getHostParent()', () => {
3636
const hostGrandparent = getHostParent(hostParent);
3737
expect(hostGrandparent).toBe(screen.getByTestId('grandparent'));
3838

39-
expect(getHostParent(hostGrandparent)).toBe(null);
39+
expect(getHostParent(hostGrandparent)).toBe(screen.UNSAFE_root);
4040
});
4141

4242
it('returns host parent for null', () => {

src/helpers/accessibility.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
Role,
66
StyleSheet,
77
} from 'react-native';
8-
import { ReactTestInstance } from 'react-test-renderer';
8+
import { HostElement } from '../renderer/host-element';
99
import { getHostSiblings, getUnsafeRootElement } from './component-tree';
1010
import {
1111
getHostComponentNames,
@@ -19,7 +19,7 @@ import { isTextInputEditable } from './text-input';
1919
import { findAllByProps } from './find-all';
2020

2121
type IsInaccessibleOptions = {
22-
cache?: WeakMap<ReactTestInstance, boolean>;
22+
cache?: WeakMap<HostElement, boolean>;
2323
};
2424

2525
export const accessibilityStateKeys: (keyof AccessibilityState)[] = [
@@ -33,14 +33,14 @@ export const accessibilityStateKeys: (keyof AccessibilityState)[] = [
3333
export const accessibilityValueKeys: (keyof AccessibilityValue)[] = ['min', 'max', 'now', 'text'];
3434

3535
export function isHiddenFromAccessibility(
36-
element: ReactTestInstance | null,
36+
element: HostElement | null,
3737
{ cache }: IsInaccessibleOptions = {},
3838
): boolean {
3939
if (element == null) {
4040
return true;
4141
}
4242

43-
let current: ReactTestInstance | null = element;
43+
let current: HostElement | null = element;
4444
while (current) {
4545
let isCurrentSubtreeInaccessible = cache?.get(current);
4646

@@ -62,7 +62,7 @@ export function isHiddenFromAccessibility(
6262
/** RTL-compatibility alias for `isHiddenFromAccessibility` */
6363
export const isInaccessible = isHiddenFromAccessibility;
6464

65-
function isSubtreeInaccessible(element: ReactTestInstance): boolean {
65+
function isSubtreeInaccessible(element: HostElement): boolean {
6666
// Null props can happen for React.Fragments
6767
if (element.props == null) {
6868
return false;
@@ -99,7 +99,7 @@ function isSubtreeInaccessible(element: ReactTestInstance): boolean {
9999
return false;
100100
}
101101

102-
export function isAccessibilityElement(element: ReactTestInstance | null): boolean {
102+
export function isAccessibilityElement(element: HostElement | null): boolean {
103103
if (element == null) {
104104
return false;
105105
}
@@ -134,7 +134,7 @@ export function isAccessibilityElement(element: ReactTestInstance | null): boole
134134
* @param element
135135
* @returns
136136
*/
137-
export function getRole(element: ReactTestInstance): Role | AccessibilityRole {
137+
export function getRole(element: HostElement): Role | AccessibilityRole {
138138
const explicitRole = element.props.role ?? element.props.accessibilityRole;
139139
if (explicitRole) {
140140
return normalizeRole(explicitRole);
@@ -165,11 +165,11 @@ export function normalizeRole(role: string): Role | AccessibilityRole {
165165
return role as Role | AccessibilityRole;
166166
}
167167

168-
export function computeAriaModal(element: ReactTestInstance): boolean | undefined {
168+
export function computeAriaModal(element: HostElement): boolean | undefined {
169169
return element.props['aria-modal'] ?? element.props.accessibilityViewIsModal;
170170
}
171171

172-
export function computeAriaLabel(element: ReactTestInstance): string | undefined {
172+
export function computeAriaLabel(element: HostElement): string | undefined {
173173
const explicitLabel = element.props['aria-label'] ?? element.props.accessibilityLabel;
174174
if (explicitLabel) {
175175
return explicitLabel;
@@ -183,17 +183,17 @@ export function computeAriaLabel(element: ReactTestInstance): string | undefined
183183
return undefined;
184184
}
185185

186-
export function computeAriaLabelledBy(element: ReactTestInstance): string | undefined {
186+
export function computeAriaLabelledBy(element: HostElement): string | undefined {
187187
return element.props['aria-labelledby'] ?? element.props.accessibilityLabelledBy;
188188
}
189189

190190
// See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#busy-state
191-
export function computeAriaBusy({ props }: ReactTestInstance): boolean {
191+
export function computeAriaBusy({ props }: HostElement): boolean {
192192
return props['aria-busy'] ?? props.accessibilityState?.busy ?? false;
193193
}
194194

195195
// See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#checked-state
196-
export function computeAriaChecked(element: ReactTestInstance): AccessibilityState['checked'] {
196+
export function computeAriaChecked(element: HostElement): AccessibilityState['checked'] {
197197
const { props } = element;
198198

199199
if (isHostSwitch(element)) {
@@ -209,7 +209,7 @@ export function computeAriaChecked(element: ReactTestInstance): AccessibilitySta
209209
}
210210

211211
// See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#disabled-state
212-
export function computeAriaDisabled(element: ReactTestInstance): boolean {
212+
export function computeAriaDisabled(element: HostElement): boolean {
213213
if (isHostTextInput(element) && !isTextInputEditable(element)) {
214214
return true;
215215
}
@@ -219,16 +219,16 @@ export function computeAriaDisabled(element: ReactTestInstance): boolean {
219219
}
220220

221221
// See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#expanded-state
222-
export function computeAriaExpanded({ props }: ReactTestInstance): boolean | undefined {
222+
export function computeAriaExpanded({ props }: HostElement): boolean | undefined {
223223
return props['aria-expanded'] ?? props.accessibilityState?.expanded;
224224
}
225225

226226
// See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#selected-state
227-
export function computeAriaSelected({ props }: ReactTestInstance): boolean {
227+
export function computeAriaSelected({ props }: HostElement): boolean {
228228
return props['aria-selected'] ?? props.accessibilityState?.selected ?? false;
229229
}
230230

231-
export function computeAriaValue(element: ReactTestInstance): AccessibilityValue {
231+
export function computeAriaValue(element: HostElement): AccessibilityValue {
232232
const {
233233
accessibilityValue,
234234
'aria-valuemax': ariaValueMax,
@@ -245,7 +245,7 @@ export function computeAriaValue(element: ReactTestInstance): AccessibilityValue
245245
};
246246
}
247247

248-
export function computeAccessibleName(element: ReactTestInstance): string | undefined {
248+
export function computeAccessibleName(element: HostElement): string | undefined {
249249
const label = computeAriaLabel(element);
250250
if (label) {
251251
return label;

src/helpers/component-tree.ts

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,35 @@
1-
import { ReactTestInstance } from 'react-test-renderer';
2-
3-
/**
4-
* ReactTestInstance referring to host element.
5-
*/
6-
export type HostTestInstance = ReactTestInstance & { type: string };
1+
import { HostElement } from '../renderer/host-element';
72

83
/**
94
* Checks if the given element is a host element.
105
* @param element The element to check.
116
*/
12-
export function isHostElement(element?: ReactTestInstance | null): element is HostTestInstance {
13-
// @ts-expect-error element.type has incorrectly narrowed type.
7+
export function isHostElement(element?: HostElement | null): element is HostElement {
148
return typeof element?.type === 'string' && element.type !== 'CONTAINER';
159
}
1610

1711
/**
1812
* Returns first host ancestor for given element.
1913
* @param element The element start traversing from.
2014
*/
21-
export function getHostParent(element: ReactTestInstance | null): HostTestInstance | null {
15+
export function getHostParent(element: HostElement | null): HostElement | null {
2216
if (element == null) {
2317
return null;
2418
}
2519

26-
let current = element.parent;
27-
while (current) {
28-
if (isHostElement(current)) {
29-
return current;
30-
}
31-
32-
current = current.parent;
33-
}
34-
35-
return null;
20+
return element.parent;
3621
}
3722

3823
/**
3924
* Returns host children for given element.
4025
* @param element The element start traversing from.
4126
*/
42-
export function getHostChildren(element: ReactTestInstance | null): HostTestInstance[] {
27+
export function getHostChildren(element: HostElement | null): HostElement[] {
4328
if (element == null) {
4429
return [];
4530
}
4631

47-
const hostChildren: HostTestInstance[] = [];
32+
const hostChildren: HostElement[] = [];
4833

4934
element.children.forEach((child) => {
5035
if (typeof child !== 'object') {
@@ -68,15 +53,15 @@ export function getHostChildren(element: ReactTestInstance | null): HostTestInst
6853
* @returns If the passed element is a host element, it will return an array containing only that element,
6954
* if the passed element is a composite element, it will return an array containing its host children (zero, one or many).
7055
*/
71-
export function getHostSelves(element: ReactTestInstance | null): HostTestInstance[] {
56+
export function getHostSelves(element: HostElement | null): HostElement[] {
7257
return isHostElement(element) ? [element] : getHostChildren(element);
7358
}
7459

7560
/**
7661
* Returns host siblings for given element.
7762
* @param element The element start traversing from.
7863
*/
79-
export function getHostSiblings(element: ReactTestInstance | null): HostTestInstance[] {
64+
export function getHostSiblings(element: HostElement | null): HostElement[] {
8065
const hostParent = getHostParent(element);
8166
const hostSelves = getHostSelves(element);
8267
return getHostChildren(hostParent).filter((sibling) => !hostSelves.includes(sibling));
@@ -88,8 +73,8 @@ export function getHostSiblings(element: ReactTestInstance | null): HostTestInst
8873
* @param element The element start traversing from.
8974
* @returns The root element of the tree (host or composite).
9075
*/
91-
export function getUnsafeRootElement(element: ReactTestInstance) {
92-
let current: ReactTestInstance | null = element;
76+
export function getUnsafeRootElement(element: HostElement) {
77+
let current: HostElement | null = element;
9378
while (current?.parent) {
9479
current = current.parent;
9580
}

src/helpers/debug-deep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ReactTestRendererJSON } from 'react-test-renderer';
1+
import type { JsonNode } from '../renderer/render-to-json';
22
import format, { FormatOptions } from './format';
33

44
export type DebugOptions = {
@@ -9,7 +9,7 @@ export type DebugOptions = {
99
* Log pretty-printed deep test component instance
1010
*/
1111
export default function debugDeep(
12-
instance: ReactTestRendererJSON | ReactTestRendererJSON[],
12+
instance: JsonNode | JsonNode[],
1313
options?: DebugOptions | string,
1414
) {
1515
const message = typeof options === 'string' ? options : options?.message;

src/helpers/debug-shallow.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as React from 'react';
2-
import type { ReactTestInstance } from 'react-test-renderer';
2+
import { HostElement } from '../renderer/host-element';
33
import { shallowInternal } from '../shallow';
44
import format from './format';
55

66
/**
77
* Log pretty-printed shallow test component instance
88
*/
99
export default function debugShallow(
10-
instance: ReactTestInstance | React.ReactElement<any>,
10+
instance: HostElement | React.ReactElement<any>,
1111
message?: string,
1212
) {
1313
const { output } = shallowInternal(instance);

0 commit comments

Comments
 (0)