Skip to content

Commit eaf3e1c

Browse files
committed
feat: support more tests
1 parent ef086f4 commit eaf3e1c

25 files changed

+343
-130
lines changed

src/__tests__/auto-cleanup.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import * as React from 'react';
22
import { View } from 'react-native';
3-
import { render } from '..';
3+
import { configure, render } from '..';
4+
5+
beforeEach(() => {
6+
configure({ renderer: 'internal' });
7+
});
48

59
let isMounted = false;
610

@@ -26,14 +30,14 @@ afterEach(() => {
2630

2731
// This just verifies that by importing RNTL in an environment which supports afterEach (like jest)
2832
// we'll get automatic cleanup between tests.
29-
test('component is mounted, but not umounted before test ends', () => {
33+
test('component is mounted, but not unmounted before test ends', () => {
3034
const fn = jest.fn();
3135
render(<Test onUnmount={fn} />);
3236
expect(isMounted).toEqual(true);
3337
expect(fn).not.toHaveBeenCalled();
3438
});
3539

36-
test('component is automatically umounted after first test ends', () => {
40+
test('component is automatically unmounted after first test ends', () => {
3741
expect(isMounted).toEqual(false);
3842
});
3943

src/__tests__/screen.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import * as React from 'react';
22
import { View, Text } from 'react-native';
3-
import { render, screen } from '..';
3+
import { configure, render, screen } from '..';
4+
5+
beforeEach(() => {
6+
configure({ renderer: 'internal' });
7+
});
48

59
test('screen has the same queries as render result', () => {
610
const result = render(<Text>Mt. Everest</Text>);

src/helpers/component-tree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type HostTestInstance = ReactTestInstance & { type: string };
1010
* @param element The element to check.
1111
*/
1212
export function isHostElement(element?: ReactTestInstance | null): element is HostTestInstance {
13-
return typeof element?.type === 'string';
13+
return typeof element?.type === 'string' && element.type !== 'CONTAINER';
1414
}
1515

1616
/**

src/helpers/find-all.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,31 @@ export function findAll(
3535
// Extracted from React Test Renderer
3636
// src: https://github.com/facebook/react/blob/8e2bde6f2751aa6335f3cef488c05c3ea08e074a/packages/react-test-renderer/src/ReactTestRenderer.js#L402
3737
function findAllInternal(
38-
root: ReactTestInstance,
38+
node: ReactTestInstance,
3939
predicate: (element: ReactTestInstance) => boolean,
4040
options?: FindAllOptions,
41+
indent: string = '',
4142
): HostTestInstance[] {
4243
const results: HostTestInstance[] = [];
4344

45+
//console.log(`${indent} 🟢 findAllInternal`, node.type, node.props);
46+
4447
// Match descendants first but do not add them to results yet.
4548
const matchingDescendants: HostTestInstance[] = [];
46-
root.children.forEach((child) => {
49+
node.children.forEach((child) => {
4750
if (typeof child === 'string') {
4851
return;
4952
}
50-
matchingDescendants.push(...findAllInternal(child, predicate, options));
53+
matchingDescendants.push(...findAllInternal(child, predicate, options, indent + ' '));
5154
});
5255

5356
if (
5457
// When matchDeepestOnly = true: add current element only if no descendants match
5558
(!options?.matchDeepestOnly || matchingDescendants.length === 0) &&
56-
isHostElement(root) &&
57-
predicate(root)
59+
isHostElement(node) &&
60+
predicate(node)
5861
) {
59-
results.push(root);
62+
results.push(node);
6063
}
6164

6265
// Add matching descendants after element to preserve original tree walk order.

src/matchers/__tests__/extend-expect.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import * as React from 'react';
22
import { View } from 'react-native';
33

44
// Note: that must point to root of the /src to reliably replicate default import.
5-
import { render } from '../..';
5+
import { configure, render } from '../..';
6+
7+
beforeEach(() => {
8+
configure({ renderer: 'internal' });
9+
});
610

711
// This is check that RNTL does not extend "expect" by default, until we actually want to expose Jest matchers publically.
812
test('does not extend "expect" by default', () => {

src/matchers/__tests__/to-be-busy.test.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import * as React from 'react';
22
import { View } from 'react-native';
3-
import { render, screen } from '../..';
3+
import { configure, render, screen } from '../..';
44
import '../extend-expect';
55

6-
test('toBeBusy() basic case', () => {
6+
beforeEach(() => {
7+
configure({ renderer: 'internal' });
8+
});
9+
10+
test.only('toBeBusy() basic case', () => {
711
render(
812
<>
913
<View testID="busy" accessibilityState={{ busy: true }} />

src/matchers/__tests__/to-have-display-value.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import * as React from 'react';
22
import { TextInput, View } from 'react-native';
3-
import { render, screen } from '../..';
3+
import { configure, render, screen } from '../..';
44
import '../extend-expect';
55

6+
beforeEach(() => {
7+
configure({ renderer: 'internal' });
8+
});
9+
610
test('toHaveDisplayValue() example test', () => {
711
render(<TextInput testID="text-input" value="test" />);
812

src/matchers/to-be-busy.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { checkHostElement, formatElement } from './utils';
66
export function toBeBusy(this: jest.MatcherContext, element: ReactTestInstance) {
77
checkHostElement(element, toBeBusy, this);
88

9+
console.log('🔴 toBeBusy', element.type, element.props);
10+
console.log('🔴 - computeAriaBusy', computeAriaBusy(element));
11+
912
return {
1013
pass: computeAriaBusy(element),
1114
message: () => {

src/queries/__tests__/accessibility-state.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/* eslint-disable no-console */
22
import * as React from 'react';
33
import { View, Text, Pressable, TouchableOpacity } from 'react-native';
4-
import { render, screen } from '../..';
4+
import { configure, render, screen } from '../..';
55

66
type ConsoleLogMock = jest.Mock<typeof console.log>;
77

88
beforeEach(() => {
9+
configure({ renderer: 'internal' });
910
jest.spyOn(console, 'warn').mockImplementation(() => {});
1011
});
1112

@@ -148,6 +149,10 @@ describe('disabled state matching', () => {
148149
render(<View accessibilityState={{ disabled: true }} />);
149150

150151
expect(screen.getByA11yState({ disabled: true })).toBeTruthy();
152+
expect(screen.queryByA11yState({ disabled: true })).toBeTruthy();
153+
154+
const x = screen.queryByA11yState({ disabled: false });
155+
expect(x).toMatchInlineSnapshot(`null`);
151156
expect(screen.queryByA11yState({ disabled: false })).toBeFalsy();
152157
});
153158

src/queries/__tests__/accessibility-value.test.tsx

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/* eslint-disable no-console */
22
import * as React from 'react';
33
import { Text, TouchableOpacity, View } from 'react-native';
4-
import { render, screen } from '../..';
4+
import { configure, render, screen } from '../..';
55

66
type ConsoleLogMock = jest.Mock<typeof console.log>;
77

88
beforeEach(() => {
9+
configure({ renderer: 'internal' });
910
jest.spyOn(console, 'warn').mockImplementation(() => {});
1011
});
1112

@@ -30,6 +31,64 @@ const Section = () => (
3031

3132
test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => {
3233
render(<Section />);
34+
expect(screen.toJSON()).toMatchInlineSnapshot(`
35+
[
36+
<Text
37+
accessibilityValue={
38+
{
39+
"max": 60,
40+
}
41+
}
42+
>
43+
Title
44+
</Text>,
45+
<View
46+
accessibilityState={
47+
{
48+
"busy": undefined,
49+
"checked": undefined,
50+
"disabled": undefined,
51+
"expanded": undefined,
52+
"selected": undefined,
53+
}
54+
}
55+
accessibilityValue={
56+
{
57+
"max": undefined,
58+
"min": undefined,
59+
"now": undefined,
60+
"text": undefined,
61+
}
62+
}
63+
accessible={true}
64+
collapsable={false}
65+
focusable={false}
66+
onClick={[Function]}
67+
onResponderGrant={[Function]}
68+
onResponderMove={[Function]}
69+
onResponderRelease={[Function]}
70+
onResponderTerminate={[Function]}
71+
onResponderTerminationRequest={[Function]}
72+
onStartShouldSetResponder={[Function]}
73+
style={
74+
{
75+
"opacity": 1,
76+
}
77+
}
78+
>
79+
<Text
80+
accessibilityValue={
81+
{
82+
"max": 60,
83+
"min": 40,
84+
}
85+
}
86+
>
87+
cool text
88+
</Text>
89+
</View>,
90+
]
91+
`);
3392

3493
expect(screen.getByA11yValue({ min: 40 }).props.accessibilityValue).toEqual({
3594
min: 40,

0 commit comments

Comments
 (0)