diff --git a/package.json b/package.json
index f8b5fe97f..d2b11be9f 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
"@babel/preset-typescript": "^7.18.6",
"@callstack/eslint-config": "^13.0.1",
"@relmify/jest-serializer-strip-ansi": "^1.0.2",
- "@testing-library/jest-native": "^5.4.0",
"@types/jest": "^29.2.3",
"@types/react": "^18.2.15",
"@types/react-test-renderer": "^18.0.0",
diff --git a/src/__tests__/jest-native.test.tsx b/src/__tests__/jest-native.test.tsx
deleted file mode 100644
index 64601f47e..000000000
--- a/src/__tests__/jest-native.test.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import * as React from 'react';
-import { StyleSheet, View, Button, Text, TextInput } from 'react-native';
-import { render } from '..';
-import '@testing-library/jest-native/extend-expect';
-
-const style = StyleSheet.create({
- style1: {
- color: 'red',
- backgroundColor: 'green',
- },
-});
-
-test('jest-native matchers work correctly', () => {
- const { getByText, getByA11yHint } = render(
-
-
-
-
- Not empty
-
-
-
-
-
-
- Second-Level Child
-
-
-
-
- );
-
- expect(getByText('Enabled Button')).toBeEnabled();
- expect(getByText('Disabled Button')).not.toBeEnabled();
- expect(getByText('Disabled Button')).toBeDisabled();
- expect(getByText('Enabled Button')).not.toBeDisabled();
-
- expect(getByA11yHint('Empty Text')).toBeEmptyElement();
- expect(getByA11yHint('Empty View')).toBeEmptyElement();
- expect(getByA11yHint('Not Empty Text')).not.toBeEmptyElement();
- expect(getByA11yHint('Not Empty View')).not.toBeEmptyElement();
-
- expect(getByA11yHint('Container View')).toContainElement(
- // $FlowFixMe - TODO: fix @testing-library/jest-native flow typings
- getByA11yHint('First-Level Child')
- );
- expect(getByA11yHint('Container View')).toContainElement(
- // $FlowFixMe - TODO: fix @testing-library/jest-native flow typings
- getByText('Second-Level Child')
- );
- expect(getByA11yHint('Container View')).not.toContainElement(
- // $FlowFixMe - TODO: fix @testing-library/jest-native flow typings
- getByText('Enabled Button')
- );
-
- expect(getByA11yHint('Not Empty Text')).toHaveTextContent('Not empty');
- expect(getByA11yHint('Not Empty Text')).toHaveTextContent(/Not empty/);
- expect(getByA11yHint('Not Empty Text')).not.toHaveTextContent('Is empty');
-
- expect(getByA11yHint('Empty Text')).toHaveStyle({ color: 'red' });
- expect(getByA11yHint('Empty Text')).toHaveStyle({
- color: 'red',
- backgroundColor: 'green',
- });
- expect(getByA11yHint('Empty Text')).not.toHaveStyle({ color: 'green' });
- expect(getByA11yHint('Empty Text')).not.toHaveStyle({
- color: 'green',
- backgroundColor: 'green',
- });
-
- const textInput = getByA11yHint('Text Input');
- expect(textInput).toBeTruthy();
- expect(textInput).toHaveProp('allowFontScaling');
- expect(textInput).toHaveProp('allowFontScaling', false);
- expect(textInput).toHaveProp('secureTextEntry');
- expect(textInput).toHaveProp('secureTextEntry', true);
- expect(textInput).toHaveProp('defaultValue');
- expect(textInput).toHaveProp('defaultValue', '111');
-});
diff --git a/src/matchers/extend-expect.d.ts b/src/matchers/extend-expect.d.ts
new file mode 100644
index 000000000..0fcec96c9
--- /dev/null
+++ b/src/matchers/extend-expect.d.ts
@@ -0,0 +1,20 @@
+import { TextMatch, TextMatchOptions } from '../matches';
+
+export interface JestNativeMatchers {
+ toBeOnTheScreen(): R;
+ toHaveTextContent(text: TextMatch, options?: TextMatchOptions): R;
+}
+
+// Implicit Jest global `expect`.
+declare global {
+ namespace jest {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ interface Matchers extends JestNativeMatchers {}
+ }
+}
+
+// Explicit `@jest/globals` `expect` matchers.
+declare module '@jest/expect' {
+ interface Matchers>
+ extends JestNativeMatchers {}
+}
diff --git a/src/matchers/extend-expect.ts b/src/matchers/extend-expect.ts
index 4eb7b373f..1a998d336 100644
--- a/src/matchers/extend-expect.ts
+++ b/src/matchers/extend-expect.ts
@@ -1,3 +1,5 @@
+///
+
import { toBeOnTheScreen } from './to-be-on-the-screen';
expect.extend({
diff --git a/src/matchers/utils.tsx b/src/matchers/utils.tsx
index 51d9f7d1f..ef5b10f91 100644
--- a/src/matchers/utils.tsx
+++ b/src/matchers/utils.tsx
@@ -1,9 +1,11 @@
import { ReactTestInstance } from 'react-test-renderer';
import {
+ EXPECTED_COLOR,
RECEIVED_COLOR,
matcherHint,
printWithType,
printReceived,
+ stringify,
} from 'jest-matcher-utils';
import prettyFormat, { plugins } from 'pretty-format';
import redent from 'redent';
@@ -89,3 +91,25 @@ export function formatElement(element: ReactTestInstance | null) {
2
);
}
+
+export function formatMessage(
+ matcher: string,
+ expectedLabel: string,
+ expectedValue: string | RegExp,
+ receivedLabel: string,
+ receivedValue: string | null
+) {
+ return [
+ `${matcher}\n`,
+ `${expectedLabel}:\n${EXPECTED_COLOR(
+ redent(formatValue(expectedValue), 2)
+ )}`,
+ `${receivedLabel}:\n${RECEIVED_COLOR(
+ redent(formatValue(receivedValue), 2)
+ )}`,
+ ].join('\n');
+}
+
+function formatValue(value: unknown) {
+ return typeof value === 'string' ? value : stringify(value);
+}
diff --git a/yarn.lock b/yarn.lock
index 86e8789dd..c7be757de 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1832,17 +1832,6 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
-"@testing-library/jest-native@^5.4.0":
- version "5.4.2"
- resolved "https://registry.yarnpkg.com/@testing-library/jest-native/-/jest-native-5.4.2.tgz#6b0c987cc57f8d900763e763025d00d26ccbc85f"
- integrity sha512-Vo/CE1uvCVH1H8YPoOEXLXVsm+BjzSQTq35+wkri1fr0O5D+A2WZ+m3ni5g6f1OCzNKNGIAHmisBEWkDs1P1mw==
- dependencies:
- chalk "^4.1.2"
- jest-diff "^29.0.1"
- jest-matcher-utils "^29.0.1"
- pretty-format "^29.0.3"
- redent "^3.0.0"
-
"@types/babel__core@^7.1.14":
version "7.20.1"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b"
@@ -4654,7 +4643,7 @@ jest-config@^29.6.1:
slash "^3.0.0"
strip-json-comments "^3.1.1"
-jest-diff@^29.0.1, jest-diff@^29.6.1:
+jest-diff@^29.6.1:
version "29.6.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.1.tgz#13df6db0a89ee6ad93c747c75c85c70ba941e545"
integrity sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==
@@ -4741,7 +4730,7 @@ jest-leak-detector@^29.6.1:
jest-get-type "^29.4.3"
pretty-format "^29.6.1"
-jest-matcher-utils@^29.0.1, jest-matcher-utils@^29.6.1:
+jest-matcher-utils@^29.6.1:
version "29.6.1"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz#6c60075d84655d6300c5d5128f46531848160b53"
integrity sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==
@@ -6290,7 +6279,7 @@ pretty-format@^26.5.2, pretty-format@^26.6.2:
ansi-styles "^4.0.0"
react-is "^17.0.1"
-pretty-format@^29.0.0, pretty-format@^29.0.3, pretty-format@^29.6.1:
+pretty-format@^29.0.0, pretty-format@^29.6.1:
version "29.6.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.1.tgz#ec838c288850b7c4f9090b867c2d4f4edbfb0f3e"
integrity sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==