mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
refactor: simplify navigation
This commit is contained in:
@@ -1,12 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Text, TextInput, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { render, screen } from '../..';
|
||||
import {
|
||||
getHostChildren,
|
||||
getHostSelves,
|
||||
getHostSiblings,
|
||||
getUnsafeRootElement,
|
||||
} from '../component-tree';
|
||||
import { getHostSiblings, getUnsafeRootElement } from '../component-tree';
|
||||
|
||||
function MultipleHostChildren() {
|
||||
return (
|
||||
@@ -18,98 +13,6 @@ function MultipleHostChildren() {
|
||||
);
|
||||
}
|
||||
|
||||
describe('getHostChildren()', () => {
|
||||
it('returns host children for host component', () => {
|
||||
render(
|
||||
<View testID="grandparent">
|
||||
<View testID="parent">
|
||||
<View testID="subject" />
|
||||
<Text testID="sibling">Hello</Text>
|
||||
</View>
|
||||
</View>,
|
||||
);
|
||||
|
||||
const hostSubject = screen.getByTestId('subject');
|
||||
expect(getHostChildren(hostSubject)).toEqual([]);
|
||||
|
||||
const hostSibling = screen.getByTestId('sibling');
|
||||
expect(getHostChildren(hostSibling)).toEqual([]);
|
||||
|
||||
const hostParent = screen.getByTestId('parent');
|
||||
expect(getHostChildren(hostParent)).toEqual([hostSubject, hostSibling]);
|
||||
|
||||
const hostGrandparent = screen.getByTestId('grandparent');
|
||||
expect(getHostChildren(hostGrandparent)).toEqual([hostParent]);
|
||||
});
|
||||
|
||||
it('returns host children for composite component', () => {
|
||||
render(
|
||||
<View testID="parent">
|
||||
<MultipleHostChildren />
|
||||
<View testID="subject" />
|
||||
<View testID="sibling" />
|
||||
</View>,
|
||||
);
|
||||
|
||||
expect(getHostChildren(screen.getByTestId('parent'))).toEqual([
|
||||
screen.getByTestId('child1'),
|
||||
screen.getByTestId('child2'),
|
||||
screen.getByTestId('child3'),
|
||||
screen.getByTestId('subject'),
|
||||
screen.getByTestId('sibling'),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getHostSelves()', () => {
|
||||
it('returns passed element for host components', () => {
|
||||
render(
|
||||
<View testID="grandparent">
|
||||
<View testID="parent">
|
||||
<View testID="subject" />
|
||||
<View testID="sibling" />
|
||||
</View>
|
||||
</View>,
|
||||
);
|
||||
|
||||
const hostSubject = screen.getByTestId('subject');
|
||||
expect(getHostSelves(hostSubject)).toEqual([hostSubject]);
|
||||
|
||||
const hostSibling = screen.getByTestId('sibling');
|
||||
expect(getHostSelves(hostSibling)).toEqual([hostSibling]);
|
||||
|
||||
const hostParent = screen.getByTestId('parent');
|
||||
expect(getHostSelves(hostParent)).toEqual([hostParent]);
|
||||
|
||||
const hostGrandparent = screen.getByTestId('grandparent');
|
||||
expect(getHostSelves(hostGrandparent)).toEqual([hostGrandparent]);
|
||||
});
|
||||
|
||||
test('returns single host element for React Native composite components', () => {
|
||||
render(
|
||||
<View testID="parent">
|
||||
<Text testID="text">Text</Text>
|
||||
<TextInput
|
||||
testID="textInput"
|
||||
defaultValue="TextInputValue"
|
||||
placeholder="TextInputPlaceholder"
|
||||
/>
|
||||
</View>,
|
||||
);
|
||||
|
||||
const compositeText = screen.getByText('Text');
|
||||
const hostText = screen.getByTestId('text');
|
||||
expect(getHostSelves(compositeText)).toEqual([hostText]);
|
||||
|
||||
const compositeTextInputByValue = screen.getByDisplayValue('TextInputValue');
|
||||
const compositeTextInputByPlaceholder = screen.getByPlaceholderText('TextInputPlaceholder');
|
||||
|
||||
const hostTextInput = screen.getByTestId('textInput');
|
||||
expect(getHostSelves(compositeTextInputByValue)).toEqual([hostTextInput]);
|
||||
expect(getHostSelves(compositeTextInputByPlaceholder)).toEqual([hostTextInput]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getHostSiblings()', () => {
|
||||
it('returns host siblings for host component', () => {
|
||||
render(
|
||||
|
||||
@@ -8,51 +8,17 @@ export function isHostElement(element?: HostElement | null): element is HostElem
|
||||
return typeof element?.type === 'string' && element.type !== 'CONTAINER';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns host children for given element.
|
||||
* @param element The element start traversing from.
|
||||
*/
|
||||
export function getHostChildren(element: HostElement | null): HostElement[] {
|
||||
if (element == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const hostChildren: HostElement[] = [];
|
||||
|
||||
element.children.forEach((child) => {
|
||||
if (typeof child !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHostElement(child)) {
|
||||
hostChildren.push(child);
|
||||
} else {
|
||||
hostChildren.push(...getHostChildren(child));
|
||||
}
|
||||
});
|
||||
|
||||
return hostChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array of host elements that represent the passed element.
|
||||
*
|
||||
* @param element The element start traversing from.
|
||||
* @returns If the passed element is a host element, it will return an array containing only that element,
|
||||
* if the passed element is a composite element, it will return an array containing its host children (zero, one or many).
|
||||
*/
|
||||
export function getHostSelves(element: HostElement | null): HostElement[] {
|
||||
return isHostElement(element) ? [element] : getHostChildren(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns host siblings for given element.
|
||||
* @param element The element start traversing from.
|
||||
*/
|
||||
export function getHostSiblings(element: HostElement | null): HostElement[] {
|
||||
const hostParent = element?.parent ?? null;
|
||||
const hostSelves = getHostSelves(element);
|
||||
return getHostChildren(hostParent).filter((sibling) => !hostSelves.includes(sibling));
|
||||
return (
|
||||
hostParent?.children.filter(
|
||||
(sibling): sibling is HostElement => typeof sibling === 'object' && sibling !== element,
|
||||
) ?? []
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { matcherHint, RECEIVED_COLOR } from 'jest-matcher-utils';
|
||||
import { getHostChildren } from '../helpers/component-tree';
|
||||
import { HostElement } from '../renderer/host-element';
|
||||
import { checkHostElement, formatElementArray } from './utils';
|
||||
|
||||
export function toBeEmptyElement(this: jest.MatcherContext, element: HostElement) {
|
||||
checkHostElement(element, toBeEmptyElement, this);
|
||||
|
||||
const hostChildren = getHostChildren(element);
|
||||
const hostChildren = element.children;
|
||||
|
||||
return {
|
||||
pass: hostChildren.length === 0,
|
||||
|
||||
@@ -10,7 +10,7 @@ import prettyFormat, { plugins } from 'pretty-format';
|
||||
import redent from 'redent';
|
||||
import { isHostElement } from '../helpers/component-tree';
|
||||
import { defaultMapProps } from '../helpers/format-default';
|
||||
import { HostElement } from '../renderer/host-element';
|
||||
import { HostElement, HostNode } from '../renderer/host-element';
|
||||
|
||||
class HostElementTypeError extends Error {
|
||||
constructor(received: unknown, matcherFn: jest.CustomMatcher, context: jest.MatcherContext) {
|
||||
@@ -60,11 +60,15 @@ export function checkHostElement(
|
||||
*
|
||||
* @param element Element to format.
|
||||
*/
|
||||
export function formatElement(element: HostElement | null) {
|
||||
export function formatElement(element: HostNode | null) {
|
||||
if (element == null) {
|
||||
return ' null';
|
||||
}
|
||||
|
||||
if (typeof element === 'string') {
|
||||
return element;
|
||||
}
|
||||
|
||||
const { children, ...props } = element.props;
|
||||
const childrenToDisplay = typeof children === 'string' ? [children] : undefined;
|
||||
|
||||
@@ -89,7 +93,7 @@ export function formatElement(element: HostElement | null) {
|
||||
);
|
||||
}
|
||||
|
||||
export function formatElementArray(elements: HostElement[]) {
|
||||
export function formatElementArray(elements: HostNode[]) {
|
||||
if (elements.length === 0) {
|
||||
return ' (no elements)';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user