@testing-library/react-native 8.0.0-rc.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,14 +2,19 @@
2
2
  import waitFor from '../waitFor';
3
3
  import type { WaitForOptions } from '../waitFor';
4
4
  import { ErrorWithStack } from './errors';
5
+ import type { TextMatchOptions } from './byText';
5
6
 
6
7
  type QueryFunction<ArgType, ReturnType> = (
7
8
  instance: ReactTestInstance
8
- ) => (args: ArgType) => ReturnType;
9
+ ) => (args: ArgType, queryOptions?: TextMatchOptions) => ReturnType;
9
10
 
10
11
  type FindQueryFunction<ArgType, ReturnType> = (
11
12
  instance: ReactTestInstance
12
- ) => (args: ArgType, waitForOptions?: WaitForOptions) => Promise<ReturnType>;
13
+ ) => (
14
+ args: ArgType,
15
+ queryOptions?: TextMatchOptions & WaitForOptions,
16
+ waitForOptions?: WaitForOptions
17
+ ) => Promise<ReturnType>;
13
18
 
14
19
  type QueryAllByQuery<QueryArg> = QueryFunction<
15
20
  QueryArg,
@@ -37,14 +42,43 @@ export type Queries<QueryArg> = {
37
42
  findAllBy: FindAllByQuery<QueryArg>,
38
43
  };
39
44
 
45
+ // The WaitForOptions has been moved to the second option param of findBy* methods with the adding of TextMatchOptions
46
+ // To make the migration easier and avoid a breaking change, keep reading this options from the first param but warn
47
+ const deprecatedKeys: $Keys<WaitForOptions>[] = [
48
+ 'timeout',
49
+ 'interval',
50
+ 'stackTraceError',
51
+ ];
52
+ const extractDeprecatedWaitForOptionUsage = (queryOptions?: WaitForOptions) => {
53
+ if (queryOptions) {
54
+ const waitForOptions: WaitForOptions = {
55
+ timeout: queryOptions.timeout,
56
+ interval: queryOptions.interval,
57
+ stackTraceError: queryOptions.stackTraceError,
58
+ };
59
+ deprecatedKeys.forEach((key) => {
60
+ if (queryOptions[key]) {
61
+ // eslint-disable-next-line no-console
62
+ console.warn(
63
+ `Use of option "${key}" in a findBy* query's second parameter, TextMatchOptions, is deprecated. Please pass this option in the third, WaitForOptions, parameter.
64
+ Example:
65
+
66
+ findByText(text, {}, { ${key}: ${queryOptions[key].toString()} })`
67
+ );
68
+ }
69
+ });
70
+ return waitForOptions;
71
+ }
72
+ };
73
+
40
74
  export function makeQueries<QueryArg>(
41
75
  queryAllByQuery: QueryAllByQuery<QueryArg>,
42
76
  getMissingError: (args: QueryArg) => string,
43
77
  getMultipleError: (args: QueryArg) => string
44
78
  ): Queries<QueryArg> {
45
79
  function getAllByQuery(instance: ReactTestInstance) {
46
- return function getAllFn(args: QueryArg) {
47
- const results = queryAllByQuery(instance)(args);
80
+ return function getAllFn(args: QueryArg, queryOptions?: TextMatchOptions) {
81
+ const results = queryAllByQuery(instance)(args, queryOptions);
48
82
 
49
83
  if (results.length === 0) {
50
84
  throw new ErrorWithStack(getMissingError(args), getAllFn);
@@ -55,8 +89,11 @@ export function makeQueries<QueryArg>(
55
89
  }
56
90
 
57
91
  function queryByQuery(instance: ReactTestInstance) {
58
- return function singleQueryFn(args: QueryArg) {
59
- const results = queryAllByQuery(instance)(args);
92
+ return function singleQueryFn(
93
+ args: QueryArg,
94
+ queryOptions?: TextMatchOptions
95
+ ) {
96
+ const results = queryAllByQuery(instance)(args, queryOptions);
60
97
 
61
98
  if (results.length > 1) {
62
99
  throw new ErrorWithStack(getMultipleError(args), singleQueryFn);
@@ -71,8 +108,8 @@ export function makeQueries<QueryArg>(
71
108
  }
72
109
 
73
110
  function getByQuery(instance: ReactTestInstance) {
74
- return function getFn(args: QueryArg) {
75
- const results = queryAllByQuery(instance)(args);
111
+ return function getFn(args: QueryArg, queryOptions?: TextMatchOptions) {
112
+ const results = queryAllByQuery(instance)(args, queryOptions);
76
113
 
77
114
  if (results.length > 1) {
78
115
  throw new ErrorWithStack(getMultipleError(args), getFn);
@@ -89,18 +126,32 @@ export function makeQueries<QueryArg>(
89
126
  function findAllByQuery(instance: ReactTestInstance) {
90
127
  return function findAllFn(
91
128
  args: QueryArg,
129
+ queryOptions?: TextMatchOptions & WaitForOptions,
92
130
  waitForOptions?: WaitForOptions = {}
93
131
  ) {
94
- return waitFor(() => getAllByQuery(instance)(args), waitForOptions);
132
+ const deprecatedWaitForOptions = extractDeprecatedWaitForOptionUsage(
133
+ queryOptions
134
+ );
135
+ return waitFor(() => getAllByQuery(instance)(args, queryOptions), {
136
+ ...deprecatedWaitForOptions,
137
+ ...waitForOptions,
138
+ });
95
139
  };
96
140
  }
97
141
 
98
142
  function findByQuery(instance: ReactTestInstance) {
99
143
  return function findFn(
100
144
  args: QueryArg,
145
+ queryOptions?: TextMatchOptions & WaitForOptions,
101
146
  waitForOptions?: WaitForOptions = {}
102
147
  ) {
103
- return waitFor(() => getByQuery(instance)(args), waitForOptions);
148
+ const deprecatedWaitForOptions = extractDeprecatedWaitForOptionUsage(
149
+ queryOptions
150
+ );
151
+ return waitFor(() => getByQuery(instance)(args, queryOptions), {
152
+ ...deprecatedWaitForOptions,
153
+ ...waitForOptions,
154
+ });
104
155
  };
105
156
  }
106
157
 
@@ -1,5 +1,6 @@
1
1
  // @flow
2
2
  import * as React from 'react';
3
+ import type { TextMatchOptions } from './byText';
3
4
  import {
4
5
  UNSAFE_getByType,
5
6
  UNSAFE_getByProps,
@@ -20,18 +21,32 @@ import {
20
21
  } from './errors';
21
22
 
22
23
  export type QueryByAPI = {|
23
- queryByText: (name: string | RegExp) => ReactTestInstance | null,
24
+ queryByText: (
25
+ name: string | RegExp,
26
+ queryOptions?: TextMatchOptions
27
+ ) => ReactTestInstance | null,
28
+ queryAllByText: (
29
+ text: string | RegExp,
30
+ queryOptions?: TextMatchOptions
31
+ ) => Array<ReactTestInstance>,
24
32
  queryByPlaceholderText: (
25
- placeholder: string | RegExp
33
+ placeholder: string | RegExp,
34
+ queryOptions?: TextMatchOptions
26
35
  ) => ReactTestInstance | null,
27
- queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null,
28
- queryByTestId: (testID: string | RegExp) => ReactTestInstance | null,
29
- queryAllByTestId: (testID: string | RegExp) => Array<ReactTestInstance>,
30
- queryAllByText: (text: string | RegExp) => Array<ReactTestInstance>,
31
36
  queryAllByPlaceholderText: (
32
- placeholder: string | RegExp
37
+ placeholder: string | RegExp,
38
+ queryOptions?: TextMatchOptions
33
39
  ) => Array<ReactTestInstance>,
34
- queryAllByDisplayValue: (value: string | RegExp) => Array<ReactTestInstance>,
40
+ queryByDisplayValue: (
41
+ value: string | RegExp,
42
+ queryOptions?: TextMatchOptions
43
+ ) => ReactTestInstance | null,
44
+ queryAllByDisplayValue: (
45
+ value: string | RegExp,
46
+ queryOptions?: TextMatchOptions
47
+ ) => Array<ReactTestInstance>,
48
+ queryByTestId: (testID: string | RegExp) => ReactTestInstance | null,
49
+ queryAllByTestId: (testID: string | RegExp) => Array<ReactTestInstance>,
35
50
 
36
51
  // Unsafe aliases
37
52
  UNSAFE_queryByType: <P>(
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.runWithRealTimers = runWithRealTimers;
7
7
  exports.setTimeout = exports.setImmediate = exports.clearTimeout = exports.jestFakeTimersAreEnabled = void 0;
8
- // Most content of this file sourced directly from https://github.com/testing-library/dom-testing-library/blob/master/src/helpers.js
8
+ // Most content of this file sourced directly from https://github.com/testing-library/dom-testing-library/blob/main/src/helpers.js
9
9
 
10
10
  /* globals jest */
11
11
  const globalObj = typeof window === 'undefined' ? global : window; // Currently this fn only supports jest timers, but it could support other test runners in the future.
@@ -1,4 +1,4 @@
1
- // Most content of this file sourced directly from https://github.com/testing-library/dom-testing-library/blob/master/src/helpers.js
1
+ // Most content of this file sourced directly from https://github.com/testing-library/dom-testing-library/blob/main/src/helpers.js
2
2
  // @flow
3
3
  /* globals jest */
4
4
 
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.matches = matches;
7
+ exports.getDefaultNormalizer = getDefaultNormalizer;
8
+
9
+ function matches(matcher, text, normalizer = getDefaultNormalizer(), exact = true) {
10
+ if (typeof text !== 'string') {
11
+ return false;
12
+ }
13
+
14
+ const normalizedText = normalizer(text);
15
+
16
+ if (typeof matcher === 'string') {
17
+ return exact ? normalizedText === matcher : normalizedText.toLowerCase().includes(matcher.toLowerCase());
18
+ } else {
19
+ return matcher.test(normalizedText);
20
+ }
21
+ }
22
+
23
+ function getDefaultNormalizer({
24
+ trim = true,
25
+ collapseWhitespace = true
26
+ } = {}) {
27
+ return text => {
28
+ let normalizedText = text;
29
+ normalizedText = trim ? normalizedText.trim() : normalizedText;
30
+ normalizedText = collapseWhitespace ? normalizedText.replace(/\s+/g, ' ') : normalizedText;
31
+ return normalizedText;
32
+ };
33
+ }
@@ -0,0 +1,41 @@
1
+ // @flow
2
+ export type NormalizerFn = (textToNormalize: string) => string;
3
+
4
+ export function matches(
5
+ matcher: string | RegExp,
6
+ text: string,
7
+ normalizer?: NormalizerFn = getDefaultNormalizer(),
8
+ exact?: boolean = true
9
+ ): boolean {
10
+ if (typeof text !== 'string') {
11
+ return false;
12
+ }
13
+
14
+ const normalizedText = normalizer(text);
15
+ if (typeof matcher === 'string') {
16
+ return exact
17
+ ? normalizedText === matcher
18
+ : normalizedText.toLowerCase().includes(matcher.toLowerCase());
19
+ } else {
20
+ return matcher.test(normalizedText);
21
+ }
22
+ }
23
+
24
+ type NormalizerConfig = {
25
+ trim?: boolean,
26
+ collapseWhitespace?: boolean,
27
+ };
28
+
29
+ export function getDefaultNormalizer({
30
+ trim = true,
31
+ collapseWhitespace = true,
32
+ }: NormalizerConfig = {}): NormalizerFn {
33
+ return (text: string) => {
34
+ let normalizedText = text;
35
+ normalizedText = trim ? normalizedText.trim() : normalizedText;
36
+ normalizedText = collapseWhitespace
37
+ ? normalizedText.replace(/\s+/g, ' ')
38
+ : normalizedText;
39
+ return normalizedText;
40
+ };
41
+ }
package/build/pure.js CHANGED
@@ -69,6 +69,12 @@ Object.defineProperty(exports, "getQueriesForElement", {
69
69
  return _within.getQueriesForElement;
70
70
  }
71
71
  });
72
+ Object.defineProperty(exports, "getDefaultNormalizer", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _matches.getDefaultNormalizer;
76
+ }
77
+ });
72
78
 
73
79
  var _act = _interopRequireDefault(require("./act"));
74
80
 
@@ -88,6 +94,8 @@ var _waitForElementToBeRemoved = _interopRequireDefault(require("./waitForElemen
88
94
 
89
95
  var _within = require("./within");
90
96
 
97
+ var _matches = require("./matches");
98
+
91
99
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
92
100
 
93
101
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -8,6 +8,7 @@ import shallow from './shallow';
8
8
  import waitFor, { waitForElement } from './waitFor';
9
9
  import waitForElementToBeRemoved from './waitForElementToBeRemoved';
10
10
  import { within, getQueriesForElement } from './within';
11
+ import { getDefaultNormalizer } from './matches';
11
12
 
12
13
  export { act };
13
14
  export { cleanup };
@@ -18,3 +19,4 @@ export { shallow };
18
19
  export { waitFor, waitForElement };
19
20
  export { waitForElementToBeRemoved };
20
21
  export { within, getQueriesForElement };
22
+ export { getDefaultNormalizer };
package/build/render.js CHANGED
@@ -48,16 +48,23 @@ function render(component, {
48
48
  } : undefined);
49
49
  const update = updateWithAct(renderer, wrap);
50
50
  const instance = renderer.root;
51
- (0, _cleanup.addToCleanupQueue)(renderer.unmount);
51
+
52
+ const unmount = () => {
53
+ (0, _act.default)(() => {
54
+ renderer.unmount();
55
+ });
56
+ };
57
+
58
+ (0, _cleanup.addToCleanupQueue)(unmount);
52
59
  return { ...(0, _getByAPI.getByAPI)(instance),
53
60
  ...(0, _queryByAPI.queryByAPI)(instance),
54
61
  ...(0, _findByAPI.findByAPI)(instance),
55
62
  ...(0, _a11yAPI.a11yAPI)(instance),
56
63
  update,
64
+ unmount,
57
65
  container: instance,
58
66
  rerender: update,
59
67
  // alias for `update`
60
- unmount: renderer.unmount,
61
68
  toJSON: renderer.toJSON,
62
69
  debug: debug(instance, renderer)
63
70
  };
@@ -46,8 +46,13 @@ export default function render<T>(
46
46
  );
47
47
  const update = updateWithAct(renderer, wrap);
48
48
  const instance = renderer.root;
49
+ const unmount = () => {
50
+ act(() => {
51
+ renderer.unmount();
52
+ });
53
+ };
49
54
 
50
- addToCleanupQueue(renderer.unmount);
55
+ addToCleanupQueue(unmount);
51
56
 
52
57
  return {
53
58
  ...getByAPI(instance),
@@ -55,9 +60,9 @@ export default function render<T>(
55
60
  ...findByAPI(instance),
56
61
  ...a11yAPI(instance),
57
62
  update,
63
+ unmount,
58
64
  container: instance,
59
65
  rerender: update, // alias for `update`
60
- unmount: renderer.unmount,
61
66
  toJSON: renderer.toJSON,
62
67
  debug: debug(instance, renderer),
63
68
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testing-library/react-native",
3
- "version": "8.0.0-rc.0",
3
+ "version": "9.0.0",
4
4
  "description": "Simple and complete React Native testing utilities that encourage good testing practices.",
5
5
  "main": "build/index.js",
6
6
  "typings": "./typings/index.d.ts",
@@ -32,28 +32,28 @@
32
32
  "@babel/preset-env": "^7.9.6",
33
33
  "@babel/preset-flow": "^7.9.0",
34
34
  "@babel/preset-react": "^7.9.4",
35
- "@callstack/eslint-config": "^10.0.0",
35
+ "@callstack/eslint-config": "^11.0.0",
36
36
  "@release-it/conventional-changelog": "^2.0.0",
37
- "@testing-library/jest-native": "~3.4.3",
37
+ "@testing-library/jest-native": "~4.0.2",
38
38
  "@types/react": "^17.0.0",
39
- "@types/react-native": "^0.63.0",
39
+ "@types/react-native": "^0.66.5",
40
40
  "@types/react-test-renderer": "^17.0.0",
41
- "babel-jest": "^26.0.1",
41
+ "babel-jest": "^27.0.0",
42
42
  "conventional-changelog-cli": "^2.0.11",
43
43
  "dedent": "^0.7.0",
44
44
  "eslint": "^7.0.0",
45
45
  "flow-bin": "^0.141.0",
46
46
  "flow-copy-source": "^2.0.9",
47
- "jest": "^26.0.1",
48
- "react": "^17.0.1",
49
- "react-native": "^0.64.0-rc.1",
50
- "react-test-renderer": "^17.0.1",
47
+ "jest": "^27.0.0",
48
+ "react": "^17.0.2",
49
+ "react-native": "^0.66.0",
50
+ "react-test-renderer": "^17.0.2",
51
51
  "release-it": "^14.0.3",
52
52
  "strip-ansi": "^6.0.0",
53
53
  "typescript": "^4.0.2"
54
54
  },
55
55
  "dependencies": {
56
- "pretty-format": "^26.0.1"
56
+ "pretty-format": "^27.0.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "react": ">=16.0.0",
@@ -79,6 +79,7 @@
79
79
  "rootDir": "./src",
80
80
  "testPathIgnorePatterns": [
81
81
  "timerUtils"
82
- ]
82
+ ],
83
+ "testTimeout": 30000
83
84
  }
84
85
  }