@testing-library/react-native 12.1.2 → 12.1.3

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.
Files changed (363) hide show
  1. package/.DS_Store +0 -0
  2. package/.codecov.yml +9 -0
  3. package/.eslintcache +1 -0
  4. package/.eslintignore +2 -0
  5. package/.eslintrc +19 -0
  6. package/.flowconfig +63 -0
  7. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
  9. package/.github/ISSUE_TEMPLATE/question.md +9 -0
  10. package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
  11. package/.github/actions/setup-deps/action.yml +22 -0
  12. package/.github/actions/setup-website-deps/action.yml +22 -0
  13. package/.github/dependabot.yml +10 -0
  14. package/.github/workflows/deploy-website.yml +36 -0
  15. package/.github/workflows/example-apps.yml +25 -0
  16. package/.github/workflows/main.yml +103 -0
  17. package/.gitignore +11 -0
  18. package/.prettierrc.js +5 -0
  19. package/CODE_OF_CONDUCT.md +73 -0
  20. package/CONTRIBUTING.md +64 -0
  21. package/README.md +8 -7
  22. package/babel.config.js +22 -0
  23. package/build/act.js.map +1 -1
  24. package/build/cleanup.js.map +1 -1
  25. package/build/fireEvent.d.ts +9 -1
  26. package/build/fireEvent.js +9 -15
  27. package/build/fireEvent.js.map +1 -1
  28. package/build/flush-micro-tasks.d.ts +19 -0
  29. package/build/flush-micro-tasks.js +36 -0
  30. package/build/flush-micro-tasks.js.map +1 -0
  31. package/build/helpers/accessiblity.js +2 -2
  32. package/build/helpers/accessiblity.js.map +1 -1
  33. package/build/helpers/component-tree.js.map +1 -1
  34. package/build/helpers/deprecation.js.map +1 -1
  35. package/build/helpers/errors.js.map +1 -1
  36. package/build/helpers/findAll.js.map +1 -1
  37. package/build/helpers/format-default.js.map +1 -1
  38. package/build/helpers/format.js.map +1 -1
  39. package/build/helpers/host-component-names.js.map +1 -1
  40. package/build/helpers/matchers/matchLabelText.js.map +1 -1
  41. package/build/helpers/pointer-events.d.ts +9 -0
  42. package/build/helpers/pointer-events.js +25 -0
  43. package/build/helpers/pointer-events.js.map +1 -0
  44. package/build/helpers/stringValidation.js.map +1 -1
  45. package/build/helpers/timers.js.map +1 -1
  46. package/build/index.js +2 -2
  47. package/build/index.js.map +1 -1
  48. package/build/matches.js.map +1 -1
  49. package/build/pure.d.ts +1 -1
  50. package/build/pure.js.map +1 -1
  51. package/build/queries/a11yState.js.map +1 -1
  52. package/build/queries/a11yValue.js.map +1 -1
  53. package/build/queries/displayValue.js.map +1 -1
  54. package/build/queries/hintText.js.map +1 -1
  55. package/build/queries/labelText.js.map +1 -1
  56. package/build/queries/makeQueries.js.map +1 -1
  57. package/build/queries/placeholderText.js.map +1 -1
  58. package/build/queries/role.js.map +1 -1
  59. package/build/queries/testId.js.map +1 -1
  60. package/build/queries/text.js.map +1 -1
  61. package/build/queries/unsafeProps.js.map +1 -1
  62. package/build/render.d.ts +171 -12
  63. package/build/render.js +11 -4
  64. package/build/render.js.map +1 -1
  65. package/build/renderHook.d.ts +3 -6
  66. package/build/renderHook.js +4 -3
  67. package/build/renderHook.js.map +1 -1
  68. package/build/shallow.js.map +1 -1
  69. package/build/test-utils/events.d.ts +10 -0
  70. package/build/test-utils/events.js +27 -0
  71. package/build/test-utils/events.js.map +1 -0
  72. package/build/test-utils/index.d.ts +1 -0
  73. package/build/test-utils/index.js +17 -0
  74. package/build/test-utils/index.js.map +1 -0
  75. package/build/user-event/event-builder/common.d.ts +45 -0
  76. package/build/user-event/event-builder/common.js +58 -0
  77. package/build/user-event/event-builder/common.js.map +1 -0
  78. package/build/user-event/event-builder/index.d.ts +32 -0
  79. package/build/user-event/event-builder/index.js +12 -0
  80. package/build/user-event/event-builder/index.js.map +1 -0
  81. package/build/user-event/index.d.ts +9 -0
  82. package/build/user-event/index.js +16 -0
  83. package/build/user-event/index.js.map +1 -0
  84. package/build/user-event/press/constants.d.ts +2 -0
  85. package/build/user-event/press/constants.js +16 -0
  86. package/build/user-event/press/constants.js.map +1 -0
  87. package/build/user-event/press/index.d.ts +1 -0
  88. package/build/user-event/press/index.js +19 -0
  89. package/build/user-event/press/index.js.map +1 -0
  90. package/build/user-event/press/press.d.ts +7 -0
  91. package/build/user-event/press/press.js +106 -0
  92. package/build/user-event/press/press.js.map +1 -0
  93. package/build/user-event/press/utils/warnAboutRealTimers.d.ts +1 -0
  94. package/build/user-event/press/utils/warnAboutRealTimers.js +14 -0
  95. package/build/user-event/press/utils/warnAboutRealTimers.js.map +1 -0
  96. package/build/user-event/setup/index.d.ts +2 -0
  97. package/build/user-event/setup/index.js +13 -0
  98. package/build/user-event/setup/index.js.map +1 -0
  99. package/build/user-event/setup/setup.d.ts +39 -0
  100. package/build/user-event/setup/setup.js +56 -0
  101. package/build/user-event/setup/setup.js.map +1 -0
  102. package/build/user-event/type/index.d.ts +1 -0
  103. package/build/user-event/type/index.js +13 -0
  104. package/build/user-event/type/index.js.map +1 -0
  105. package/build/user-event/type/type.d.ts +3 -0
  106. package/build/user-event/type/type.js +18 -0
  107. package/build/user-event/type/type.js.map +1 -0
  108. package/build/user-event/utils/events.d.ts +9 -0
  109. package/build/user-event/utils/events.js +44 -0
  110. package/build/user-event/utils/events.js.map +1 -0
  111. package/build/user-event/utils/index.d.ts +2 -0
  112. package/build/user-event/utils/index.js +28 -0
  113. package/build/user-event/utils/index.js.map +1 -0
  114. package/build/user-event/utils/wait.d.ts +2 -0
  115. package/build/user-event/utils/wait.js +14 -0
  116. package/build/user-event/utils/wait.js.map +1 -0
  117. package/build/waitFor.js +3 -3
  118. package/build/waitFor.js.map +1 -1
  119. package/build/waitForElementToBeRemoved.js.map +1 -1
  120. package/examples/basic/.expo-shared/assets.json +4 -0
  121. package/examples/basic/.gitignore +14 -0
  122. package/examples/basic/App.tsx +20 -0
  123. package/examples/basic/README.md +11 -0
  124. package/examples/basic/__tests__/App.test.tsx +119 -0
  125. package/examples/basic/app.json +31 -0
  126. package/examples/basic/assets/adaptive-icon.png +0 -0
  127. package/examples/basic/assets/favicon.png +0 -0
  128. package/examples/basic/assets/icon.png +0 -0
  129. package/examples/basic/assets/splash.png +0 -0
  130. package/examples/basic/babel.config.js +6 -0
  131. package/examples/basic/components/Home.tsx +28 -0
  132. package/examples/basic/components/LoginForm.tsx +138 -0
  133. package/examples/basic/jest-setup.ts +7 -0
  134. package/examples/basic/jest.config.js +5 -0
  135. package/examples/basic/package.json +30 -0
  136. package/examples/basic/tsconfig.json +7 -0
  137. package/examples/react-navigation/README.md +14 -0
  138. package/examples/react-navigation/babel.config.js +4 -0
  139. package/examples/react-navigation/jest-setup.js +11 -0
  140. package/examples/react-navigation/jest.config.js +10 -0
  141. package/examples/react-navigation/package.json +31 -0
  142. package/examples/react-navigation/src/App.js +21 -0
  143. package/examples/react-navigation/src/DrawerNavigator.js +15 -0
  144. package/examples/react-navigation/src/DrawerNavigator.test.js +42 -0
  145. package/examples/react-navigation/src/NativeStackNavigator.js +15 -0
  146. package/examples/react-navigation/src/NativeStackNavigator.test.js +34 -0
  147. package/examples/react-navigation/src/StackNavigator.js +15 -0
  148. package/examples/react-navigation/src/StackNavigator.test.js +34 -0
  149. package/examples/react-navigation/src/TabNavigator.js +15 -0
  150. package/examples/react-navigation/src/TabNavigator.test.js +21 -0
  151. package/examples/react-navigation/src/screens/DetailsScreen.js +43 -0
  152. package/examples/react-navigation/src/screens/DetailsScreen.test.js +27 -0
  153. package/examples/react-navigation/src/screens/DrawerHomeScreen.js +26 -0
  154. package/examples/react-navigation/src/screens/HomeScreen.js +48 -0
  155. package/examples/react-navigation/src/screens/SettingsScreen.js +20 -0
  156. package/examples/react-navigation/src/test-utils.js +12 -0
  157. package/examples/redux/App.js +27 -0
  158. package/examples/redux/actions/todoActions.js +25 -0
  159. package/examples/redux/babel.config.js +6 -0
  160. package/examples/redux/components/AddTodo.js +73 -0
  161. package/examples/redux/components/AddTodo.test.js +27 -0
  162. package/examples/redux/components/TodoElem.js +25 -0
  163. package/examples/redux/components/TodoList.js +29 -0
  164. package/examples/redux/components/TodoList.test.js +34 -0
  165. package/examples/redux/index.js +8 -0
  166. package/examples/redux/jest-setup.js +2 -0
  167. package/examples/redux/jest.config.js +4 -0
  168. package/examples/redux/package.json +23 -0
  169. package/examples/redux/reducers/index.js +6 -0
  170. package/examples/redux/reducers/todoReducer.js +27 -0
  171. package/examples/redux/store.js +10 -0
  172. package/examples/redux/test-utils.js +11 -0
  173. package/experiments-app/.expo/README.md +15 -0
  174. package/experiments-app/.expo/devices.json +3 -0
  175. package/experiments-app/.expo/packager-info.json +9 -0
  176. package/experiments-app/.expo/settings.json +9 -0
  177. package/experiments-app/.gitignore +17 -0
  178. package/experiments-app/.prettierrc.js +5 -0
  179. package/experiments-app/app.json +30 -0
  180. package/experiments-app/assets/adaptive-icon.png +0 -0
  181. package/experiments-app/assets/favicon.png +0 -0
  182. package/experiments-app/assets/icon.png +0 -0
  183. package/experiments-app/assets/splash.png +0 -0
  184. package/experiments-app/babel.config.js +6 -0
  185. package/experiments-app/index.js +4 -0
  186. package/experiments-app/package.json +31 -0
  187. package/experiments-app/src/App.tsx +31 -0
  188. package/experiments-app/src/MainScreen.tsx +51 -0
  189. package/experiments-app/src/experiments.ts +17 -0
  190. package/experiments-app/src/screens/TextInputEventPropagation.tsx +54 -0
  191. package/experiments-app/src/screens/TextInputEvents.tsx +50 -0
  192. package/experiments-app/src/utils/helpers.ts +8 -0
  193. package/experiments-app/tsconfig.json +6 -0
  194. package/experiments-app/yarn.lock +6913 -0
  195. package/flow-typed/npm/jest_v26.x.x.js +1218 -0
  196. package/flow-typed/npm/react-test-renderer_v16.x.x.js +81 -0
  197. package/jest-setup.ts +10 -0
  198. package/package.json +6 -6
  199. package/renovate.json +19 -0
  200. package/scripts/test_react_17 +12 -0
  201. package/src/__tests__/__snapshots__/render-debug.test.tsx.snap +548 -0
  202. package/src/__tests__/__snapshots__/render.test.tsx.snap +39 -0
  203. package/src/__tests__/act.test.tsx +52 -0
  204. package/src/__tests__/auto-cleanup-skip.test.tsx +39 -0
  205. package/src/__tests__/auto-cleanup.test.tsx +50 -0
  206. package/src/__tests__/cleanup.test.tsx +26 -0
  207. package/src/__tests__/config.test.ts +55 -0
  208. package/src/__tests__/fireEvent-textInput.test.tsx +154 -0
  209. package/src/__tests__/fireEvent.test.tsx +485 -0
  210. package/src/__tests__/host-component-names.test.tsx +109 -0
  211. package/src/__tests__/host-text-nesting.test.tsx +90 -0
  212. package/src/__tests__/jest-native.test.tsx +84 -0
  213. package/src/__tests__/questionsBoard.test.tsx +62 -0
  214. package/src/__tests__/react-native-api.test.tsx +126 -0
  215. package/src/__tests__/render-debug.test.tsx +207 -0
  216. package/src/__tests__/render-stringValidation.test.tsx +157 -0
  217. package/src/__tests__/render.test.tsx +256 -0
  218. package/src/__tests__/renderHook.test.tsx +114 -0
  219. package/src/__tests__/screen.test.tsx +66 -0
  220. package/src/__tests__/timerUtils.ts +7 -0
  221. package/src/__tests__/timers.test.ts +27 -0
  222. package/src/__tests__/waitFor.test.tsx +327 -0
  223. package/src/__tests__/waitForElementToBeRemoved.test.tsx +151 -0
  224. package/src/__tests__/within.test.tsx +96 -0
  225. package/src/act.ts +86 -0
  226. package/src/cleanup.ts +15 -0
  227. package/src/config.ts +72 -0
  228. package/src/fireEvent.ts +163 -0
  229. package/src/flush-micro-tasks.ts +30 -0
  230. package/src/helpers/__tests__/accessiblity.test.tsx +373 -0
  231. package/src/helpers/__tests__/component-tree.test.tsx +226 -0
  232. package/src/helpers/__tests__/format-default.tsx +114 -0
  233. package/src/helpers/__tests__/getTextContent.test.tsx +49 -0
  234. package/src/helpers/__tests__/includeHiddenElements.test.tsx +39 -0
  235. package/src/helpers/__tests__/query-name.test.ts +10 -0
  236. package/src/helpers/__tests__/timers.test.ts +8 -0
  237. package/src/helpers/accessiblity.ts +108 -0
  238. package/src/helpers/component-tree.ts +89 -0
  239. package/src/helpers/debugDeep.ts +27 -0
  240. package/src/helpers/debugShallow.ts +22 -0
  241. package/src/helpers/deprecation.ts +53 -0
  242. package/src/helpers/errors.ts +66 -0
  243. package/src/helpers/filterNodeByType.ts +7 -0
  244. package/src/helpers/findAll.ts +68 -0
  245. package/src/helpers/format-default.ts +72 -0
  246. package/src/helpers/format.ts +47 -0
  247. package/src/helpers/getTextContent.ts +20 -0
  248. package/src/helpers/host-component-names.tsx +67 -0
  249. package/src/helpers/matchers/__tests__/matchArrayValue.test.ts +34 -0
  250. package/src/helpers/matchers/__tests__/matchObject.test.ts +37 -0
  251. package/src/helpers/matchers/__tests__/matchStringValue.test.ts +15 -0
  252. package/src/helpers/matchers/accessibilityState.ts +48 -0
  253. package/src/helpers/matchers/accessibilityValue.ts +24 -0
  254. package/src/helpers/matchers/matchArrayProp.ts +21 -0
  255. package/src/helpers/matchers/matchLabelText.ts +51 -0
  256. package/src/helpers/matchers/matchObjectProp.ts +25 -0
  257. package/src/helpers/matchers/matchStringProp.ts +23 -0
  258. package/src/helpers/matchers/matchTextContent.ts +20 -0
  259. package/src/helpers/pointer-events.ts +27 -0
  260. package/src/helpers/query-name.ts +4 -0
  261. package/src/helpers/stringValidation.ts +36 -0
  262. package/src/helpers/timers.ts +98 -0
  263. package/src/index.ts +33 -0
  264. package/src/matches.ts +49 -0
  265. package/src/pure.ts +25 -0
  266. package/src/queries/__tests__/a11yState.test.tsx +439 -0
  267. package/src/queries/__tests__/a11yValue.test.tsx +309 -0
  268. package/src/queries/__tests__/displayValue.test.tsx +221 -0
  269. package/src/queries/__tests__/hintText.test.tsx +177 -0
  270. package/src/queries/__tests__/labelText.test.tsx +242 -0
  271. package/src/queries/__tests__/makeQueries.test.tsx +235 -0
  272. package/src/queries/__tests__/placeholderText.test.tsx +136 -0
  273. package/src/queries/__tests__/role-value.test.tsx +176 -0
  274. package/src/queries/__tests__/role.test.tsx +824 -0
  275. package/src/queries/__tests__/testId.test.tsx +200 -0
  276. package/src/queries/__tests__/text.test.tsx +556 -0
  277. package/src/queries/a11yState.ts +131 -0
  278. package/src/queries/a11yValue.ts +131 -0
  279. package/src/queries/displayValue.ts +78 -0
  280. package/src/queries/hintText.ts +112 -0
  281. package/src/queries/labelText.ts +59 -0
  282. package/src/queries/makeQueries.ts +255 -0
  283. package/src/queries/options.ts +14 -0
  284. package/src/queries/placeholderText.ts +79 -0
  285. package/src/queries/role.ts +132 -0
  286. package/src/queries/testId.ts +71 -0
  287. package/src/queries/text.ts +66 -0
  288. package/src/queries/unsafeProps.ts +76 -0
  289. package/src/queries/unsafeType.ts +73 -0
  290. package/src/react-versions.ts +11 -0
  291. package/src/render-act.ts +19 -0
  292. package/src/render.tsx +183 -0
  293. package/src/renderHook.tsx +56 -0
  294. package/src/screen.ts +123 -0
  295. package/src/shallow.ts +18 -0
  296. package/src/test-utils/events.ts +24 -0
  297. package/src/test-utils/index.ts +1 -0
  298. package/src/user-event/event-builder/common.ts +50 -0
  299. package/src/user-event/event-builder/index.ts +5 -0
  300. package/src/user-event/index.ts +14 -0
  301. package/src/user-event/press/__tests__/longPress.real-timers.test.tsx +115 -0
  302. package/src/user-event/press/__tests__/longPress.test.tsx +157 -0
  303. package/src/user-event/press/__tests__/press.real-timers.test.tsx +318 -0
  304. package/src/user-event/press/__tests__/press.test.tsx +422 -0
  305. package/src/user-event/press/constants.ts +7 -0
  306. package/src/user-event/press/index.ts +1 -0
  307. package/src/user-event/press/press.ts +134 -0
  308. package/src/user-event/press/utils/warnAboutRealTimers.ts +6 -0
  309. package/src/user-event/setup/index.ts +2 -0
  310. package/src/user-event/setup/setup.ts +93 -0
  311. package/src/user-event/type/__tests__/__snapshots__/type.test.tsx.snap +26 -0
  312. package/src/user-event/type/__tests__/type.test.tsx +63 -0
  313. package/src/user-event/type/index.ts +1 -0
  314. package/src/user-event/type/type.ts +20 -0
  315. package/src/user-event/utils/__tests__/wait.test.ts +63 -0
  316. package/src/user-event/utils/events.ts +54 -0
  317. package/src/user-event/utils/index.ts +2 -0
  318. package/src/user-event/utils/wait.ts +15 -0
  319. package/src/waitFor.ts +228 -0
  320. package/src/waitForElementToBeRemoved.ts +42 -0
  321. package/src/within.ts +30 -0
  322. package/tsconfig.json +17 -0
  323. package/tsconfig.release.json +8 -0
  324. package/website/.gitignore +20 -0
  325. package/website/README.md +33 -0
  326. package/website/docker/.dockerignore +3 -0
  327. package/website/docker/Dockerfile +9 -0
  328. package/website/docker/docker-compose.yml +11 -0
  329. package/website/docs/API.md +946 -0
  330. package/website/docs/EslintPLluginTestingLibrary.md +28 -0
  331. package/website/docs/FAQ.md +44 -0
  332. package/website/docs/GettingStarted.md +100 -0
  333. package/website/docs/HowShouldIQuery.md +21 -0
  334. package/website/docs/MigrationV11.md +64 -0
  335. package/website/docs/MigrationV12.md +67 -0
  336. package/website/docs/MigrationV2.md +126 -0
  337. package/website/docs/MigrationV7.md +119 -0
  338. package/website/docs/MigrationV9.md +67 -0
  339. package/website/docs/Queries.md +567 -0
  340. package/website/docs/ReactNavigation.md +371 -0
  341. package/website/docs/ReduxIntegration.md +137 -0
  342. package/website/docs/TestingEnvironment.md +154 -0
  343. package/website/docs/Troubleshooting.md +44 -0
  344. package/website/docs/UnderstandingAct.md +227 -0
  345. package/website/docs/UserEvent.md +66 -0
  346. package/website/docusaurus.config.js +114 -0
  347. package/website/package.json +31 -0
  348. package/website/sidebars.js +20 -0
  349. package/website/src/components/Feature.js +31 -0
  350. package/website/src/css/custom.css +13 -0
  351. package/website/src/css/index.module.css +77 -0
  352. package/website/src/pages/index.js +82 -0
  353. package/website/static/.nojekyll +0 -0
  354. package/website/static/css/custom.css +28 -0
  355. package/website/static/img/hit.png +0 -0
  356. package/website/static/img/locomotive.png +0 -0
  357. package/website/static/img/owl.png +0 -0
  358. package/website/static/img/tools.png +0 -0
  359. package/website/yarn.lock +7669 -0
  360. package/yarn.lock +7765 -0
  361. package/build/flushMicroTasks.d.ts +0 -5
  362. package/build/flushMicroTasks.js +0 -17
  363. package/build/flushMicroTasks.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import { FlatList, Text } from 'react-native';
3
+ import { connect } from 'react-redux';
4
+ import { bindActionCreators } from 'redux';
5
+ import { removeTodo } from '../actions/todoActions';
6
+ import TodoElem from './TodoElem';
7
+
8
+ export function TodoList(props) {
9
+ const onDeleteTodo = (id) => props.removeTodo(id);
10
+
11
+ return (
12
+ <FlatList
13
+ data={props.todos}
14
+ keyExtractor={(todo) => todo.id.toString()}
15
+ renderItem={({ item }) => (
16
+ <TodoElem todo={item} onDelete={onDeleteTodo} />
17
+ )}
18
+ />
19
+ );
20
+ }
21
+
22
+ const mapStateToProps = (state) => ({
23
+ todos: state.todos,
24
+ });
25
+
26
+ const mapDispatchToProps = (dispatch) =>
27
+ bindActionCreators({ removeTodo }, dispatch);
28
+
29
+ export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import { screen, fireEvent } from '@testing-library/react-native';
3
+ import { renderWithRedux } from '../test-utils';
4
+ import TodoList from './TodoList';
5
+
6
+ const initialState = {
7
+ todos: [
8
+ { id: 1, text: 'Sing something', date: new Date() },
9
+ { id: 2, text: 'Dance something', date: new Date() },
10
+ { id: 3, text: 'Sleep something', date: new Date() },
11
+ { id: 4, text: 'Sleep something', date: new Date() },
12
+ ],
13
+ };
14
+
15
+ test('it should execute with a store with 4 elements', () => {
16
+ renderWithRedux(<TodoList />, { initialState });
17
+
18
+ const todoElems = screen.getAllByText(/something/i);
19
+ expect(todoElems).toHaveLength(4);
20
+ });
21
+
22
+ test('should display 4 elements and end up with 3 after delete', () => {
23
+ renderWithRedux(<TodoList />, { initialState });
24
+
25
+ const todoElems = screen.getAllByText(/something/i);
26
+ expect(todoElems.length).toBe(4);
27
+
28
+ const buttons = screen.getAllByText('Delete');
29
+ expect(buttons).toHaveLength(4);
30
+ fireEvent.press(buttons[0]);
31
+
32
+ const buttonsAfterDelete = screen.getAllByText('Delete');
33
+ expect(buttonsAfterDelete).toHaveLength(3);
34
+ });
@@ -0,0 +1,8 @@
1
+ import { registerRootComponent } from 'expo';
2
+
3
+ import App from './App';
4
+
5
+ // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6
+ // It also ensures that whether you load the app in the Expo client or in a native build,
7
+ // the environment is set up appropriately
8
+ registerRootComponent(App);
@@ -0,0 +1,2 @@
1
+ // Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
2
+ jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ preset: '@testing-library/react-native',
3
+ setupFiles: ['./jest-setup.js'],
4
+ };
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "redux-example",
3
+ "description": "Testing Redux interactions with RNTL",
4
+ "version": "0.0.1",
5
+ "private": true,
6
+ "scripts": {
7
+ "test": "jest"
8
+ },
9
+ "dependencies": {
10
+ "react": "~18.0.0",
11
+ "react-native": "~0.69.2",
12
+ "react-redux": "^7.2.0",
13
+ "redux": "^4.0.5"
14
+ },
15
+ "devDependencies": {
16
+ "@babel/core": "^7.9.0",
17
+ "@testing-library/react-native": "^11.0.0",
18
+ "@types/jest": "^28.0.0",
19
+ "jest": "^28.0.0",
20
+ "metro-react-native-babel-preset": "^0.70.0",
21
+ "react-test-renderer": "^18.0.0"
22
+ }
23
+ }
@@ -0,0 +1,6 @@
1
+ import { combineReducers } from 'redux';
2
+ import todos from './todoReducer';
3
+
4
+ export default combineReducers({
5
+ todos,
6
+ });
@@ -0,0 +1,27 @@
1
+ import { actions } from '../actions/todoActions.js';
2
+
3
+ export default function todoReducer(state = [], action) {
4
+ switch (action.type) {
5
+ case actions.ADD:
6
+ return state.concat(action.payload);
7
+
8
+ case actions.REMOVE:
9
+ return state.filter((todo) => todo.id !== action.payload.id);
10
+
11
+ case actions.MODIFY:
12
+ return state.map((todo) => {
13
+ if (todo.id === action.payload.id) {
14
+ return {
15
+ ...todo,
16
+ ...action.payload,
17
+ };
18
+ }
19
+ });
20
+
21
+ case actions.CLEAR:
22
+ return [];
23
+
24
+ default:
25
+ return state;
26
+ }
27
+ }
@@ -0,0 +1,10 @@
1
+ import { createStore } from 'redux';
2
+ import reducers from './reducers';
3
+
4
+ const initialStore = {
5
+ todos: [],
6
+ };
7
+
8
+ export default function configureStore(initialState = initialStore) {
9
+ return createStore(reducers, initialState);
10
+ }
@@ -0,0 +1,11 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import * as React from 'react';
3
+ import { Provider } from 'react-redux';
4
+ import { render } from '@testing-library/react-native';
5
+ import configureStore from './store';
6
+
7
+ export function renderWithRedux(ui, options) {
8
+ const store = options?.store ?? configureStore(options?.initialState);
9
+ const queries = render(<Provider store={store}>{ui}</Provider>);
10
+ return { ...queries, store };
11
+ }
@@ -0,0 +1,15 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+
3
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
4
+
5
+ > What do the files contain?
6
+
7
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
8
+ - "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
9
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
10
+
11
+ > Should I commit the ".expo" folder?
12
+
13
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
14
+
15
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -0,0 +1,3 @@
1
+ {
2
+ "devices": []
3
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "expoServerPort": 19000,
3
+ "packagerPort": 19000,
4
+ "packagerPid": null,
5
+ "expoServerNgrokUrl": null,
6
+ "packagerNgrokUrl": null,
7
+ "ngrokPid": null,
8
+ "webpackServerPort": null
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "hostType": "lan",
3
+ "lanType": "ip",
4
+ "dev": true,
5
+ "minify": false,
6
+ "urlRandomness": null,
7
+ "https": false,
8
+ "scheme": null
9
+ }
@@ -0,0 +1,17 @@
1
+ node_modules/
2
+ .expo/
3
+ dist/
4
+ npm-debug.*
5
+ *.jks
6
+ *.p8
7
+ *.p12
8
+ *.key
9
+ *.mobileprovision
10
+ *.orig.*
11
+ web-build/
12
+
13
+ # macOS
14
+ .DS_Store
15
+
16
+ # Temporary files created by Metro to check the health of the file watcher
17
+ .metro-health-check*
@@ -0,0 +1,5 @@
1
+ // added for Jest inline snapshots to not use default Prettier config
2
+ module.exports = {
3
+ singleQuote: true,
4
+ trailingComma: "es5"
5
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "expo": {
3
+ "name": "experiments-app",
4
+ "slug": "experiments-app",
5
+ "version": "1.0.0",
6
+ "orientation": "portrait",
7
+ "icon": "./assets/icon.png",
8
+ "userInterfaceStyle": "light",
9
+ "splash": {
10
+ "image": "./assets/splash.png",
11
+ "resizeMode": "contain",
12
+ "backgroundColor": "#ffffff"
13
+ },
14
+ "assetBundlePatterns": [
15
+ "**/*"
16
+ ],
17
+ "ios": {
18
+ "supportsTablet": true
19
+ },
20
+ "android": {
21
+ "adaptiveIcon": {
22
+ "foregroundImage": "./assets/adaptive-icon.png",
23
+ "backgroundColor": "#ffffff"
24
+ }
25
+ },
26
+ "web": {
27
+ "favicon": "./assets/favicon.png"
28
+ }
29
+ }
30
+ }
Binary file
@@ -0,0 +1,6 @@
1
+ module.exports = function(api) {
2
+ api.cache(true);
3
+ return {
4
+ presets: ['babel-preset-expo'],
5
+ };
6
+ };
@@ -0,0 +1,4 @@
1
+ import registerRootComponent from 'expo/build/launch/registerRootComponent';
2
+ import App from './src/App';
3
+
4
+ registerRootComponent(App);
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "experiments-app",
3
+ "private": true,
4
+ "description": "Expo app for conducting experiments of React Native behaviour.",
5
+ "version": "1.0.0",
6
+ "main": "index.js",
7
+ "scripts": {
8
+ "typecheck": "tsc -noEmit",
9
+ "start": "expo start",
10
+ "android": "expo start --android",
11
+ "ios": "expo start --ios",
12
+ "web": "expo start --web"
13
+ },
14
+ "dependencies": {
15
+ "@react-navigation/native": "^6.1.6",
16
+ "@react-navigation/native-stack": "^6.9.12",
17
+ "add": "^2.0.6",
18
+ "expo": "~48.0.11",
19
+ "expo-status-bar": "~1.4.4",
20
+ "react": "18.2.0",
21
+ "react-native": "0.71.6",
22
+ "react-native-safe-area-context": "4.5.0",
23
+ "react-native-screens": "~3.20.0",
24
+ "yarn": "^1.22.19"
25
+ },
26
+ "devDependencies": {
27
+ "@babel/core": "^7.20.0",
28
+ "@types/react": "~18.0.14",
29
+ "typescript": "^4.9.4"
30
+ }
31
+ }
@@ -0,0 +1,31 @@
1
+ import * as React from 'react';
2
+ import { StatusBar } from 'expo-status-bar';
3
+ import { NavigationContainer } from '@react-navigation/native';
4
+ import { createNativeStackNavigator } from '@react-navigation/native-stack';
5
+ import { MainScreen } from './MainScreen';
6
+ import { experiments } from './experiments';
7
+
8
+ const Stack = createNativeStackNavigator();
9
+
10
+ export default function App() {
11
+ return (
12
+ <NavigationContainer>
13
+ <Stack.Navigator>
14
+ <Stack.Screen
15
+ name="main"
16
+ component={MainScreen}
17
+ options={{ title: 'Experiments' }}
18
+ />
19
+ {experiments.map((exp) => (
20
+ <Stack.Screen
21
+ key={exp.key}
22
+ name={exp.key}
23
+ component={exp.component}
24
+ options={{ title: exp.title }}
25
+ />
26
+ ))}
27
+ </Stack.Navigator>
28
+ <StatusBar style="auto" />
29
+ </NavigationContainer>
30
+ );
31
+ }
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import {
3
+ StyleSheet,
4
+ SafeAreaView,
5
+ Text,
6
+ FlatList,
7
+ Pressable,
8
+ } from 'react-native';
9
+ import { useNavigation } from '@react-navigation/native';
10
+ import { Experiment, experiments } from './experiments';
11
+
12
+ export function MainScreen() {
13
+ return (
14
+ <SafeAreaView style={styles.container}>
15
+ <FlatList
16
+ data={experiments}
17
+ renderItem={({ item }) => <ListItem item={item} />}
18
+ />
19
+ </SafeAreaView>
20
+ );
21
+ }
22
+
23
+ interface ListItemProps {
24
+ item: Experiment;
25
+ }
26
+
27
+ function ListItem({ item }: ListItemProps) {
28
+ const navigation = useNavigation();
29
+
30
+ const handlePress = () => {
31
+ navigation.navigate(item.key);
32
+ };
33
+
34
+ return (
35
+ <Pressable style={styles.item} onPress={handlePress}>
36
+ <Text style={styles.itemTitle}>{item.title}</Text>
37
+ </Pressable>
38
+ );
39
+ }
40
+
41
+ const styles = StyleSheet.create({
42
+ container: {
43
+ flex: 1,
44
+ },
45
+ item: {
46
+ padding: 20,
47
+ },
48
+ itemTitle: {
49
+ fontSize: 20,
50
+ },
51
+ });
@@ -0,0 +1,17 @@
1
+ import { TextInputEventPropagation } from './screens/TextInputEventPropagation';
2
+ import { TextInputEvents } from './screens/TextInputEvents';
3
+
4
+ export type Experiment = (typeof experiments)[number];
5
+
6
+ export const experiments = [
7
+ {
8
+ key: 'textInputEvents',
9
+ title: 'TextInput Events',
10
+ component: TextInputEvents,
11
+ },
12
+ {
13
+ key: 'textInputEventPropagation',
14
+ title: 'TextInput Event Propagation',
15
+ component: TextInputEventPropagation,
16
+ },
17
+ ];
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { StyleSheet, SafeAreaView, TextInput, Pressable } from 'react-native';
3
+ import { buildEventLogger } from '../utils/helpers';
4
+
5
+ const handlePressIn = buildEventLogger('TextInput.pressIn');
6
+ const handlePressOut = buildEventLogger('TextInput.pressOut');
7
+ const handleFocus = buildEventLogger('TextInput.focus');
8
+ const handleBlur = buildEventLogger('TextInput.blur');
9
+ const handleChange = buildEventLogger('TextInput.change');
10
+ const handleSubmitEditing = buildEventLogger('TextInput.submitEditing');
11
+
12
+ const handlePressablePress = buildEventLogger('Pressable.press');
13
+
14
+ export function TextInputEventPropagation() {
15
+ const [value, setValue] = React.useState('');
16
+
17
+ const handleChangeText = (value: string) => {
18
+ setValue(value);
19
+ console.log(`Event: changeText`, value);
20
+ };
21
+
22
+ return (
23
+ <SafeAreaView style={styles.container}>
24
+ <Pressable onPress={handlePressablePress}>
25
+ <TextInput
26
+ style={styles.textInput}
27
+ value={value}
28
+ editable={true}
29
+ onChangeText={handleChangeText}
30
+ onPressIn={handlePressIn}
31
+ onPressOut={handlePressOut}
32
+ onFocus={handleFocus}
33
+ onBlur={handleBlur}
34
+ onChange={handleChange}
35
+ onSubmitEditing={handleSubmitEditing}
36
+ />
37
+ </Pressable>
38
+ </SafeAreaView>
39
+ );
40
+ }
41
+
42
+ const styles = StyleSheet.create({
43
+ container: {
44
+ flex: 1,
45
+ },
46
+ textInput: {
47
+ backgroundColor: 'white',
48
+ margin: 20,
49
+ padding: 8,
50
+ fontSize: 18,
51
+ borderWidth: 1,
52
+ borderColor: 'grey',
53
+ },
54
+ });
@@ -0,0 +1,50 @@
1
+ import * as React from 'react';
2
+ import { StyleSheet, SafeAreaView, TextInput } from 'react-native';
3
+ import { buildEventLogger } from '../utils/helpers';
4
+
5
+ const handlePressIn = buildEventLogger('pressIn');
6
+ const handlePressOut = buildEventLogger('pressOut');
7
+ const handleFocus = buildEventLogger('focus');
8
+ const handleBlur = buildEventLogger('blur');
9
+ const handleChange = buildEventLogger('change');
10
+ const handleSubmitEditing = buildEventLogger('submitEditing');
11
+
12
+ export function TextInputEvents() {
13
+ const [value, setValue] = React.useState('');
14
+
15
+ const handleChangeText = (value: string) => {
16
+ setValue(value);
17
+ console.log(`Event: changeText`, value);
18
+ };
19
+
20
+ return (
21
+ <SafeAreaView style={styles.container}>
22
+ <TextInput
23
+ style={styles.textInput}
24
+ value={value}
25
+ editable={true}
26
+ onChangeText={handleChangeText}
27
+ onPressIn={handlePressIn}
28
+ onPressOut={handlePressOut}
29
+ onFocus={handleFocus}
30
+ onBlur={handleBlur}
31
+ onChange={handleChange}
32
+ onSubmitEditing={handleSubmitEditing}
33
+ />
34
+ </SafeAreaView>
35
+ );
36
+ }
37
+
38
+ const styles = StyleSheet.create({
39
+ container: {
40
+ flex: 1,
41
+ },
42
+ textInput: {
43
+ backgroundColor: 'white',
44
+ margin: 20,
45
+ padding: 8,
46
+ fontSize: 18,
47
+ borderWidth: 1,
48
+ borderColor: 'grey',
49
+ },
50
+ });
@@ -0,0 +1,8 @@
1
+ import { NativeSyntheticEvent } from 'react-native/types';
2
+
3
+ export function buildEventLogger(name: string) {
4
+ return (event: NativeSyntheticEvent<unknown>) => {
5
+ const eventData = event?.nativeEvent ?? event;
6
+ console.log(`Event: ${name}`, eventData);
7
+ };
8
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": {
4
+ "strict": true
5
+ }
6
+ }