@codyswann/lisa 1.47.1 → 1.48.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.
Files changed (210) hide show
  1. package/all/copy-overwrite/.claude/rules/lisa.md +23 -10
  2. package/all/copy-overwrite/.claude/settings.json +10 -252
  3. package/all/deletions.json +67 -1
  4. package/cdk/copy-overwrite/.claude/settings.json +80 -0
  5. package/cdk/create-only/.github/workflows/ci.yml +1 -1
  6. package/cdk/create-only/.github/workflows/deploy.yml +1 -1
  7. package/dist/core/lisa.d.ts +14 -0
  8. package/dist/core/lisa.d.ts.map +1 -1
  9. package/dist/core/lisa.js +47 -0
  10. package/dist/core/lisa.js.map +1 -1
  11. package/expo/copy-overwrite/.claude/settings.json +80 -0
  12. package/expo/copy-overwrite/eslint.expo.ts +2 -2
  13. package/expo/create-only/.github/workflows/ci.yml +1 -1
  14. package/expo/create-only/.github/workflows/deploy.yml +1 -1
  15. package/expo/deletions.json +33 -0
  16. package/expo/package-lisa/package.lisa.json +2 -2
  17. package/nestjs/copy-overwrite/.claude/settings.json +80 -0
  18. package/nestjs/create-only/.github/workflows/ci.yml +1 -1
  19. package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
  20. package/nestjs/deletions.json +8 -0
  21. package/package.json +8 -4
  22. package/rails/copy-overwrite/.claude/settings.json +80 -0
  23. package/rails/create-only/.github/workflows/ci.yml +1 -1
  24. package/rails/deletions.json +11 -1
  25. package/typescript/copy-overwrite/.claude/settings.json +13 -253
  26. package/typescript/copy-overwrite/eslint.typescript.ts +1 -1
  27. package/typescript/create-only/.github/workflows/ci.yml +1 -1
  28. package/typescript/deletions.json +12 -1
  29. package/typescript/package-lisa/package.lisa.json +1 -1
  30. package/all/copy-overwrite/.claude/agents/agent-architect.md +0 -310
  31. package/all/copy-overwrite/.claude/agents/architecture-specialist.md +0 -53
  32. package/all/copy-overwrite/.claude/agents/debug-specialist.md +0 -204
  33. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +0 -183
  34. package/all/copy-overwrite/.claude/agents/hooks-expert.md +0 -74
  35. package/all/copy-overwrite/.claude/agents/implementer.md +0 -54
  36. package/all/copy-overwrite/.claude/agents/learner.md +0 -44
  37. package/all/copy-overwrite/.claude/agents/performance-specialist.md +0 -95
  38. package/all/copy-overwrite/.claude/agents/product-specialist.md +0 -72
  39. package/all/copy-overwrite/.claude/agents/quality-specialist.md +0 -55
  40. package/all/copy-overwrite/.claude/agents/security-specialist.md +0 -58
  41. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +0 -246
  42. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +0 -87
  43. package/all/copy-overwrite/.claude/agents/test-specialist.md +0 -64
  44. package/all/copy-overwrite/.claude/agents/verification-specialist.md +0 -189
  45. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +0 -112
  46. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +0 -7
  47. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-and-verify.md +0 -7
  48. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-deploy-and-verify.md +0 -7
  49. package/all/copy-overwrite/.claude/commands/git/commit.md +0 -7
  50. package/all/copy-overwrite/.claude/commands/git/prune.md +0 -6
  51. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +0 -7
  52. package/all/copy-overwrite/.claude/commands/jira/create.md +0 -7
  53. package/all/copy-overwrite/.claude/commands/jira/sync.md +0 -7
  54. package/all/copy-overwrite/.claude/commands/jira/verify.md +0 -7
  55. package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +0 -7
  56. package/all/copy-overwrite/.claude/commands/plan/add-test-coverage.md +0 -7
  57. package/all/copy-overwrite/.claude/commands/plan/create.md +0 -6
  58. package/all/copy-overwrite/.claude/commands/plan/execute.md +0 -7
  59. package/all/copy-overwrite/.claude/commands/plan/fix-linter-error.md +0 -7
  60. package/all/copy-overwrite/.claude/commands/plan/local-code-review.md +0 -6
  61. package/all/copy-overwrite/.claude/commands/plan/lower-code-complexity.md +0 -6
  62. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines-per-function.md +0 -7
  63. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines.md +0 -7
  64. package/all/copy-overwrite/.claude/commands/pull-request/review.md +0 -7
  65. package/all/copy-overwrite/.claude/commands/security/zap-scan.md +0 -6
  66. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +0 -6
  67. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +0 -6
  68. package/all/copy-overwrite/.claude/commands/tasks/load.md +0 -7
  69. package/all/copy-overwrite/.claude/commands/tasks/sync.md +0 -7
  70. package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +0 -61
  71. package/all/copy-overwrite/.claude/hooks/debug-hook.sh +0 -47
  72. package/all/copy-overwrite/.claude/hooks/enforce-plan-rules.sh +0 -15
  73. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +0 -183
  74. package/all/copy-overwrite/.claude/hooks/setup-jira-cli.sh +0 -52
  75. package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +0 -107
  76. package/all/copy-overwrite/.claude/hooks/ticket-sync-reminder.sh +0 -23
  77. package/all/copy-overwrite/.claude/hooks/track-plan-sessions.sh +0 -164
  78. package/all/copy-overwrite/.claude/hooks/verify-completion.sh +0 -77
  79. package/all/copy-overwrite/.claude/rules/coding-philosophy.md +0 -428
  80. package/all/copy-overwrite/.claude/rules/verfication.md +0 -596
  81. package/all/copy-overwrite/.claude/skills/agent-design-best-practices/SKILL.md +0 -219
  82. package/all/copy-overwrite/.claude/skills/git-commit/SKILL.md +0 -48
  83. package/all/copy-overwrite/.claude/skills/git-commit-and-submit-pr/SKILL.md +0 -8
  84. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-and-verify/SKILL.md +0 -7
  85. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-deploy-and-verify/SKILL.md +0 -7
  86. package/all/copy-overwrite/.claude/skills/git-prune/SKILL.md +0 -35
  87. package/all/copy-overwrite/.claude/skills/git-submit-pr/SKILL.md +0 -44
  88. package/all/copy-overwrite/.claude/skills/jira-create/SKILL.md +0 -41
  89. package/all/copy-overwrite/.claude/skills/jira-sync/SKILL.md +0 -63
  90. package/all/copy-overwrite/.claude/skills/jira-verify/SKILL.md +0 -29
  91. package/all/copy-overwrite/.claude/skills/lisa-review-implementation/SKILL.md +0 -209
  92. package/all/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -44
  93. package/all/copy-overwrite/.claude/skills/plan-execute/SKILL.md +0 -89
  94. package/all/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  95. package/all/copy-overwrite/.claude/skills/plan-local-code-review/SKILL.md +0 -88
  96. package/all/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -44
  97. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -45
  98. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  99. package/all/copy-overwrite/.claude/skills/pull-request-review/SKILL.md +0 -68
  100. package/all/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  101. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +0 -202
  102. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +0 -210
  103. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  104. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +0 -305
  105. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +0 -112
  106. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +0 -67
  107. package/all/copy-overwrite/.claude/skills/sonarqube-check/SKILL.md +0 -11
  108. package/all/copy-overwrite/.claude/skills/sonarqube-fix/SKILL.md +0 -8
  109. package/all/copy-overwrite/.claude/skills/tasks-load/SKILL.md +0 -88
  110. package/all/copy-overwrite/.claude/skills/tasks-sync/SKILL.md +0 -108
  111. package/eslint-plugin-code-organization/README.md +0 -149
  112. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  113. package/eslint-plugin-code-organization/index.js +0 -28
  114. package/eslint-plugin-code-organization/package.json +0 -10
  115. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
  116. package/expo/copy-overwrite/.claude/agents/ops-specialist.md +0 -124
  117. package/expo/copy-overwrite/.claude/rules/expo-verification.md +0 -261
  118. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +0 -238
  119. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +0 -360
  120. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +0 -360
  121. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +0 -417
  122. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +0 -257
  123. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +0 -233
  124. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +0 -329
  125. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +0 -299
  126. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +0 -749
  127. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +0 -318
  128. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +0 -200
  129. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +0 -209
  130. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +0 -268
  131. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +0 -619
  132. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +0 -340
  133. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +0 -276
  134. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +0 -416
  135. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +0 -202
  136. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +0 -445
  137. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +0 -309
  138. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +0 -417
  139. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +0 -431
  140. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +0 -290
  141. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +0 -171
  142. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +0 -411
  143. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +0 -343
  144. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +0 -307
  145. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +0 -300
  146. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +0 -315
  147. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +0 -362
  148. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +0 -505
  149. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +0 -711
  150. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +0 -446
  151. package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +0 -124
  152. package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +0 -211
  153. package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +0 -119
  154. package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +0 -119
  155. package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +0 -99
  156. package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +0 -165
  157. package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +0 -166
  158. package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +0 -101
  159. package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +0 -56
  160. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +0 -223
  161. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +0 -314
  162. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +0 -420
  163. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +0 -556
  164. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +0 -590
  165. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +0 -291
  166. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +0 -234
  167. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +0 -89
  168. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +0 -201
  169. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +0 -294
  170. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +0 -37
  171. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +0 -10
  172. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +0 -235
  173. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +0 -96
  174. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +0 -183
  175. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +0 -243
  176. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -192
  177. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +0 -31
  178. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +0 -10
  179. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +0 -56
  180. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +0 -60
  181. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +0 -176
  182. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +0 -527
  183. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +0 -483
  184. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +0 -257
  185. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +0 -413
  186. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +0 -513
  187. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +0 -536
  188. package/nestjs/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  189. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +0 -275
  190. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +0 -487
  191. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +0 -450
  192. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +0 -536
  193. package/rails/copy-overwrite/.claude/skills/action-controller-best-practices/SKILL.md +0 -374
  194. package/rails/copy-overwrite/.claude/skills/action-view-best-practices/SKILL.md +0 -335
  195. package/rails/copy-overwrite/.claude/skills/active-record-model-best-practices/SKILL.md +0 -166
  196. package/rails/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -45
  197. package/rails/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  198. package/rails/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -48
  199. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -46
  200. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  201. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +0 -76
  202. package/typescript/copy-overwrite/.claude/hooks/install-pkgs.sh +0 -64
  203. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +0 -81
  204. package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +0 -68
  205. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +0 -432
  206. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +0 -149
  207. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  208. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +0 -28
  209. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +0 -10
  210. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
@@ -1,314 +0,0 @@
1
- ---
2
- name: testing-library
3
- description: Enforces best practices for unit testing with Jest, @testing-library/react-native, and jest-expo in Expo projects. This skill should be used when writing, reviewing, or debugging unit tests to ensure tests are accessible, maintainable, and follow Testing Library guiding principles. Use this skill for test file creation, query selection, async handling, mocking patterns, and Expo Router testing.
4
- ---
5
-
6
- # Testing Library Best Practices
7
-
8
- ## Overview
9
-
10
- This skill enforces best practices for unit testing in Expo applications using Jest, `@testing-library/react-native`, and `jest-expo`. Tests should be **user-centric**, **accessible**, and **behavior-focused** rather than implementation-focused.
11
-
12
- ## Core Principles
13
-
14
- ### 1. Test User Behavior, Not Implementation
15
-
16
- Focus on what the component does from a user's perspective, not how it achieves it internally.
17
-
18
- ```typescript
19
- // Correct - tests visible behavior
20
- expect(screen.getByRole("button", { name: "Submit" })).toBeEnabled();
21
-
22
- // Incorrect - tests implementation details
23
- expect(component.state.isSubmitting).toBe(false);
24
- ```
25
-
26
- ### 2. Use Accessible Queries
27
-
28
- Queries should reflect how users and assistive technologies interact with the UI.
29
-
30
- ```typescript
31
- // Correct - uses accessible role and name
32
- screen.getByRole("button", { name: /save changes/i });
33
-
34
- // Incorrect - relies on implementation detail
35
- screen.getByTestId("save-btn");
36
- ```
37
-
38
- ### 3. One Assertion Per Behavior
39
-
40
- Each test should verify one behavior. Multiple assertions are acceptable when verifying different aspects of the same behavior.
41
-
42
- ```typescript
43
- // Correct - focused test
44
- test("displays error message when submission fails", async () => {
45
- render(<Form />);
46
- await userEvent.press(screen.getByRole("button", { name: "Submit" }));
47
- expect(await screen.findByRole("alert")).toHaveTextContent("Failed");
48
- });
49
-
50
- // Incorrect - testing multiple behaviors
51
- test("form works correctly", async () => {
52
- // Tests validation, submission, success, and error handling...
53
- });
54
- ```
55
-
56
- ### 4. Prefer userEvent Over fireEvent
57
-
58
- `userEvent` simulates realistic user interactions including the full event sequence.
59
-
60
- ```typescript
61
- // Correct - realistic interaction
62
- const user = userEvent.setup();
63
- await user.press(screen.getByRole("button", { name: "Submit" }));
64
-
65
- // Less ideal - simplified event
66
- fireEvent.press(screen.getByRole("button", { name: "Submit" }));
67
- ```
68
-
69
- ## Query Priority
70
-
71
- Choose queries based on accessibility, following this priority order:
72
-
73
- | Priority | Query | When to Use |
74
- | -------- | ---------------- | --------------------------------------- |
75
- | 1 | `getByRole` | Interactive elements, headings, buttons |
76
- | 2 | `getByLabelText` | Form fields with labels |
77
- | 3 | `getByText` | Non-interactive content, static text |
78
- | 4 | `getByTestId` | Last resort when semantic queries fail |
79
-
80
- For detailed query patterns, see [references/query-priority.md](references/query-priority.md).
81
-
82
- ## Async Testing Patterns
83
-
84
- ### Use findBy for Async Assertions
85
-
86
- ```typescript
87
- // Correct - waits for element to appear
88
- expect(await screen.findByRole("alert")).toBeOnTheScreen();
89
-
90
- // Incorrect - may fail if element appears async
91
- expect(screen.getByRole("alert")).toBeOnTheScreen();
92
- ```
93
-
94
- ### Use waitFor for Side Effects
95
-
96
- ```typescript
97
- // Correct - assertion inside waitFor
98
- await waitFor(() => {
99
- expect(mockCallback).toHaveBeenCalledWith("success");
100
- });
101
-
102
- // Incorrect - side effect inside waitFor
103
- await waitFor(() => {
104
- fireEvent.press(button); // Never do this
105
- });
106
- ```
107
-
108
- For comprehensive async patterns, see [references/async-patterns.md](references/async-patterns.md).
109
-
110
- ## Mocking Patterns
111
-
112
- ### Required Global Mocks
113
-
114
- These must be configured in `jest/setup-jest.ts`:
115
-
116
- ```typescript
117
- // AsyncStorage
118
- jest.mock("@react-native-async-storage/async-storage", () =>
119
- require("@react-native-async-storage/async-storage/jest/async-storage-mock")
120
- );
121
-
122
- // Expo Fonts (to avoid async icon assertions)
123
- jest.mock("expo-font", () => ({
124
- ...jest.requireActual("expo-font"),
125
- isLoaded: jest.fn(() => true),
126
- }));
127
- ```
128
-
129
- For complete mocking patterns, see [references/mocking-patterns.md](references/mocking-patterns.md).
130
-
131
- ## Expo Router Testing
132
-
133
- Use `renderRouter` from `expo-router/testing-library` instead of `render` when testing components that use Expo Router.
134
-
135
- ```typescript
136
- import { renderRouter, screen } from "expo-router/testing-library";
137
-
138
- test("navigates to player detail", async () => {
139
- renderRouter({
140
- index: () => <PlayerList />,
141
- "players/[id]": () => <PlayerDetail />,
142
- });
143
-
144
- await userEvent.press(screen.getByRole("button", { name: "View Player" }));
145
- expect(screen).toHavePathname("/players/123");
146
- });
147
- ```
148
-
149
- For Expo Router testing details, see [references/expo-router-testing.md](references/expo-router-testing.md).
150
-
151
- ## Test Structure
152
-
153
- ### File Organization
154
-
155
- - Place test files in `__tests__/` directories, not alongside source files
156
- - Never place tests inside the `app/` directory (Expo Router constraint)
157
- - Use `.test.ts` or `.test.tsx` extensions
158
-
159
- ### AAA Pattern
160
-
161
- Structure every test with Arrange-Act-Assert:
162
-
163
- ```typescript
164
- test("increments counter when button pressed", async () => {
165
- // Arrange
166
- const user = userEvent.setup();
167
- render(<Counter initialCount={0} />);
168
-
169
- // Act
170
- await user.press(screen.getByRole("button", { name: "Increment" }));
171
-
172
- // Assert
173
- expect(screen.getByRole("text", { name: "Count: 1" })).toBeOnTheScreen();
174
- });
175
- ```
176
-
177
- ### Descriptive Test Names
178
-
179
- Use descriptive names that explain the expected behavior:
180
-
181
- ```typescript
182
- // Correct - describes behavior
183
- test("displays validation error when email format is invalid", () => {});
184
- test("disables submit button while form is submitting", () => {});
185
-
186
- // Incorrect - vague or implementation-focused
187
- test("email validation works", () => {});
188
- test("sets isSubmitting to true", () => {});
189
- ```
190
-
191
- ## Jest Configuration
192
-
193
- ### Manual React Native Resolution (No Preset)
194
-
195
- Lisa configures Jest manually instead of using the `jest-expo` preset to avoid
196
- jsdom incompatibility with `react-native/jest/setup.js`. The configuration in
197
- `jest.expo.ts` provides haste, resolver, transform, and setupFiles that match
198
- the preset's behavior without redefining `window`.
199
-
200
- ### Use Fake Timers with userEvent
201
-
202
- ```typescript
203
- jest.useFakeTimers();
204
-
205
- test("handles debounced input", async () => {
206
- const user = userEvent.setup();
207
- render(<SearchInput />);
208
-
209
- await user.type(screen.getByRole("textbox"), "query");
210
- jest.runAllTimers();
211
-
212
- expect(await screen.findByText("Results")).toBeOnTheScreen();
213
- });
214
- ```
215
-
216
- ## Anti-Patterns
217
-
218
- ### Never Test Implementation Details
219
-
220
- ```typescript
221
- // Wrong - testing internal state
222
- expect(wrapper.state().isLoading).toBe(true);
223
-
224
- // Wrong - testing component methods
225
- expect(wrapper.instance().handleSubmit).toHaveBeenCalled();
226
-
227
- // Correct - testing visible behavior
228
- expect(screen.getByRole("progressbar")).toBeOnTheScreen();
229
- ```
230
-
231
- ### Never Use getByTestId as Default
232
-
233
- ```typescript
234
- // Wrong - using testID when semantic query exists
235
- screen.getByTestId("submit-button");
236
-
237
- // Correct - using accessible query
238
- screen.getByRole("button", { name: "Submit" });
239
- ```
240
-
241
- ### Never Wrap render or fireEvent in act()
242
-
243
- ```typescript
244
- // Wrong - unnecessary act wrapper
245
- await act(async () => {
246
- render(<Component />);
247
- });
248
-
249
- // Correct - render already wraps in act
250
- render(<Component />);
251
- ```
252
-
253
- ### Never Put Side Effects in waitFor
254
-
255
- ```typescript
256
- // Wrong - side effect in waitFor
257
- await waitFor(() => {
258
- fireEvent.press(button);
259
- expect(result).toBeOnTheScreen();
260
- });
261
-
262
- // Correct - side effect before waitFor
263
- fireEvent.press(button);
264
- await waitFor(() => {
265
- expect(result).toBeOnTheScreen();
266
- });
267
- ```
268
-
269
- ### Never Use Multiple Assertions in waitFor
270
-
271
- ```typescript
272
- // Wrong - multiple assertions
273
- await waitFor(() => {
274
- expect(title).toBeOnTheScreen();
275
- expect(subtitle).toBeOnTheScreen();
276
- expect(button).toBeEnabled();
277
- });
278
-
279
- // Correct - single assertion, chain with findBy
280
- expect(await screen.findByRole("heading")).toBeOnTheScreen();
281
- expect(screen.getByText("Subtitle")).toBeOnTheScreen();
282
- expect(screen.getByRole("button")).toBeEnabled();
283
- ```
284
-
285
- ## Quick Reference
286
-
287
- ### Common Matchers
288
-
289
- | Matcher | Purpose |
290
- | --------------------- | ------------------------------- |
291
- | `toBeOnTheScreen()` | Element is currently rendered |
292
- | `toBeEnabled()` | Interactive element is enabled |
293
- | `toBeDisabled()` | Interactive element is disabled |
294
- | `toHaveTextContent()` | Element contains text |
295
- | `toBeVisible()` | Element is visible to user |
296
- | `toBeChecked()` | Checkbox/radio is checked |
297
-
298
- ### Query Variants
299
-
300
- | Prefix | Returns | Throws on 0 | Throws on >1 | Async |
301
- | ---------- | -------------------- | ----------- | ------------ | ----- |
302
- | getBy | Element | Yes | Yes | No |
303
- | queryBy | Element \| null | No | Yes | No |
304
- | findBy | Promise\<Element\> | Yes | Yes | Yes |
305
- | getAllBy | Element[] | Yes | No | No |
306
- | queryAllBy | Element[] | No | No | No |
307
- | findAllBy | Promise\<Element[]\> | Yes | No | Yes |
308
-
309
- ## References
310
-
311
- - [Query Priority](references/query-priority.md) - Detailed query selection guidance
312
- - [Async Patterns](references/async-patterns.md) - Comprehensive async testing patterns
313
- - [Mocking Patterns](references/mocking-patterns.md) - Common mocking configurations
314
- - [Expo Router Testing](references/expo-router-testing.md) - Testing with Expo Router