Skip to content

Commit a84542e

Browse files
committed
feat: toHaveTextContent() matcher
chore: fix typescript, remove legacy jest-native tests
1 parent 344e9b3 commit a84542e

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/// <reference path="../extend-expect.d.ts" />
2+
3+
import * as React from 'react';
4+
import { View, Text } from 'react-native';
5+
import { render, screen } from '../..';
6+
import '../extend-expect';
7+
8+
test('toHaveTextContent() example test', () => {
9+
render(
10+
<View testID="view">
11+
<Text>Hello</Text> <Text>World</Text>
12+
</View>
13+
);
14+
15+
const view = screen.getByTestId('view');
16+
expect(view).toHaveTextContent('Hello World');
17+
expect(view).not.toHaveTextContent('Hello there');
18+
});
19+
20+
test('toHaveTextContent() handles positive test cases', () => {
21+
render(<Text testID="text">Hello World</Text>);
22+
23+
const text = screen.getByTestId('text');
24+
expect(text).toHaveTextContent('Hello World');
25+
expect(text).toHaveTextContent('Hello', { exact: false });
26+
expect(text).toHaveTextContent(/Hello World/);
27+
});
28+
29+
test('toHaveTextContent() does exact match by default', () => {
30+
render(<Text testID="text">Hello World</Text>);
31+
32+
const text = screen.getByTestId('text');
33+
expect(text).toHaveTextContent('Hello World');
34+
expect(text).not.toHaveTextContent('Hello');
35+
expect(text).not.toHaveTextContent('World');
36+
});
37+
38+
test('toHaveTextContent() handles nested text', () => {
39+
render(
40+
<Text testID="text">
41+
Hello <Text>React</Text>
42+
</Text>
43+
);
44+
45+
const text = screen.getByTestId('text');
46+
expect(text).toHaveTextContent('Hello React');
47+
});
48+
49+
test('toHaveTextContent() negative test cases', () => {
50+
render(<Text testID="text">Hello World</Text>);
51+
52+
const text = screen.getByTestId('text');
53+
expect(text).not.toHaveTextContent(/Hello React/);
54+
expect(() => expect(text).toHaveTextContent(/Hello React/))
55+
.toThrowErrorMatchingInlineSnapshot(`
56+
"expect(element).toHaveTextContent()
57+
58+
Expected element to have text content:
59+
/Hello React/
60+
Received:
61+
Hello World"
62+
`);
63+
64+
expect(text).not.toHaveTextContent('Yellow', { exact: false });
65+
expect(() => expect(text).toHaveTextContent('Yellow', { exact: false }))
66+
.toThrowErrorMatchingInlineSnapshot(`
67+
"expect(element).toHaveTextContent()
68+
69+
Expected element to have text content:
70+
Yellow
71+
Received:
72+
Hello World"
73+
`);
74+
});
75+
76+
test('toHaveTextContent() on null element', () => {
77+
expect(() => expect(null).toHaveTextContent('Hello World'))
78+
.toThrowErrorMatchingInlineSnapshot(`
79+
"expect(received).toHaveTextContent()
80+
81+
received value must be a host element.
82+
Received has value: null"
83+
`);
84+
});

src/matchers/extend-expect.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { TextMatch, TextMatchOptions } from '../matches';
1+
import type { TextMatch, TextMatchOptions } from '../matches';
22

33
export interface JestNativeMatchers<R> {
44
toBeOnTheScreen(): R;
55
toBeEmptyElement(): R;
66
toHaveDisplayValue(expectedValue: TextMatch, options?: TextMatchOptions): R;
7+
toHaveTextContent(expectedText: TextMatch, options?: TextMatchOptions): R;
78
}
89

910
// Implicit Jest global `expect`.

src/matchers/extend-expect.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import { toBeOnTheScreen } from './to-be-on-the-screen';
44
import { toBeEmptyElement } from './to-be-empty-element';
55
import { toHaveDisplayValue } from './to-have-display-value';
6+
import { toHaveTextContent } from './to-have-text-content';
67

78
expect.extend({
89
toBeOnTheScreen,
910
toBeEmptyElement,
1011
toHaveDisplayValue,
12+
toHaveTextContent,
1113
});

src/matchers/to-have-text-content.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { ReactTestInstance } from 'react-test-renderer';
2+
import { matcherHint } from 'jest-matcher-utils';
3+
import { getTextContent } from '../helpers/getTextContent';
4+
import { TextMatch, TextMatchOptions, matches } from '../matches';
5+
import { checkHostElement, formatMessage } from './utils';
6+
7+
export function toHaveTextContent(
8+
this: jest.MatcherContext,
9+
element: ReactTestInstance,
10+
expectedText: TextMatch,
11+
options?: TextMatchOptions
12+
) {
13+
checkHostElement(element, toHaveTextContent, this);
14+
15+
const text = getTextContent(element);
16+
17+
return {
18+
pass: matches(expectedText, text, options?.normalizer, options?.exact),
19+
message: () => {
20+
return [
21+
formatMessage(
22+
matcherHint(
23+
`${this.isNot ? '.not' : ''}.toHaveTextContent`,
24+
'element',
25+
''
26+
),
27+
`Expected element ${this.isNot ? 'not to' : 'to'} have text content`,
28+
expectedText,
29+
'Received',
30+
text
31+
),
32+
].join('\n');
33+
},
34+
};
35+
}

0 commit comments

Comments
 (0)