Skip to content

Commit

Permalink
feat: toHaveTextContent() matcher
Browse files Browse the repository at this point in the history
chore: fix typescript, remove legacy jest-native tests
  • Loading branch information
mdjastrzebski committed Aug 22, 2023
1 parent cf08c06 commit 19f108e
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/matchers/__tests__/to-have-text-content.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/// <reference path="../extend-expect.d.ts" />

import * as React from 'react';
import { View, Text } from 'react-native';
import { render, screen } from '../..';
import '../extend-expect';

test('toHaveTextContent() example test', () => {
render(
<View testID="view">
<Text>Hello</Text> <Text>World</Text>
</View>
);

const view = screen.getByTestId('view');
expect(view).toHaveTextContent('Hello World');
expect(view).not.toHaveTextContent('Hello there');
});

test('toHaveTextContent() handles positive test cases', () => {
render(<Text testID="text">Hello World</Text>);

const text = screen.getByTestId('text');
expect(text).toHaveTextContent('Hello World');
expect(text).toHaveTextContent('Hello', { exact: false });
expect(text).toHaveTextContent(/Hello World/);
});

test('toHaveTextContent() does exact match by default', () => {
render(<Text testID="text">Hello World</Text>);

const text = screen.getByTestId('text');
expect(text).toHaveTextContent('Hello World');
expect(text).not.toHaveTextContent('Hello');
expect(text).not.toHaveTextContent('World');
});

test('toHaveTextContent() handles nested text', () => {
render(
<Text testID="text">
Hello <Text>React</Text>
</Text>
);

const text = screen.getByTestId('text');
expect(text).toHaveTextContent('Hello React');
});

test('toHaveTextContent() negative test cases', () => {
render(<Text testID="text">Hello World</Text>);

const text = screen.getByTestId('text');
expect(text).not.toHaveTextContent(/Hello React/);
expect(() => expect(text).toHaveTextContent(/Hello React/))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveTextContent()
Expected element to have text content:
/Hello React/
Received:
Hello World"
`);

expect(text).not.toHaveTextContent('Yellow', { exact: false });
expect(() => expect(text).toHaveTextContent('Yellow', { exact: false }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveTextContent()
Expected element to have text content:
Yellow
Received:
Hello World"
`);
});

test('toHaveTextContent() on null element', () => {
expect(() => expect(null).toHaveTextContent('Hello World'))
.toThrowErrorMatchingInlineSnapshot(`
"expect(received).toHaveTextContent()
received value must be a host element.
Received has value: null"
`);
});
3 changes: 3 additions & 0 deletions src/matchers/extend-expect.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { TextMatch, TextMatchOptions } from '../matches';

export interface JestNativeMatchers<R> {
toBeOnTheScreen(): R;
toBeEmptyElement(): R;
toHaveTextContent(expectedText: TextMatch, options?: TextMatchOptions): R;
}

// Implicit Jest global `expect`.
Expand Down
2 changes: 2 additions & 0 deletions src/matchers/extend-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import { toBeOnTheScreen } from './to-be-on-the-screen';
import { toBeEmptyElement } from './to-be-empty-element';
import { toHaveTextContent } from './to-have-text-content';

expect.extend({
toBeOnTheScreen,
toBeEmptyElement,
toHaveTextContent,
});
35 changes: 35 additions & 0 deletions src/matchers/to-have-text-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ReactTestInstance } from 'react-test-renderer';
import { matcherHint } from 'jest-matcher-utils';
import { getTextContent } from '../helpers/getTextContent';
import { TextMatch, TextMatchOptions, matches } from '../matches';
import { checkHostElement, formatMessage } from './utils';

export function toHaveTextContent(
this: jest.MatcherContext,
element: ReactTestInstance,
expectedText: TextMatch,
options?: TextMatchOptions
) {
checkHostElement(element, toHaveTextContent, this);

const text = getTextContent(element);

return {
pass: matches(expectedText, text, options?.normalizer, options?.exact),
message: () => {
return [
formatMessage(
matcherHint(
`${this.isNot ? '.not' : ''}.toHaveTextContent`,
'element',
''
),
`Expected element ${this.isNot ? 'not to' : 'to'} have text content`,
expectedText,
'Received',
text
),
].join('\n');
},
};
}

0 comments on commit 19f108e

Please sign in to comment.