Skip to content

Commit 3e0ad0d

Browse files
maximcodingclaude
andcommitted
chore: apply Biome formatting, update docs, improve test setup
- Reformat multiple screens, navigation, and storage files to satisfy Biome - Add .biomeignore to exclude generated i18n-types.d.ts from formatting - Update tsconfig.json with @assets/* path alias and include adjustments - Remove declarations.d.ts (SVG module declaration cleaned up) - AGENTS.md: add note on chaining checks and biomeignore for i18n types - ErrorBoundary tests: wrap in describe block, suppress console.error noise - jest.setup.js: filter Locize promotional console.info on i18n init - docs/TODO.md: remove "Shipped in this template" section (already in codebase) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 524a36b commit 3e0ad0d

File tree

20 files changed

+738
-297
lines changed

20 files changed

+738
-297
lines changed

.biomeignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Generated by `npm run i18n:types` — do not hand-format (Biome would fight the generator)
2+
src/i18n/i18n-types.d.ts

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ React Native 0.82 app, TypeScript strict, bare workflow. Top-level under `src/`:
1818
- **Biome:** `npm run lint``biome check .`; `npm run format``biome check . --write`
1919
- **Type-check:** `npx tsc --noEmit`
2020
- **Tests:** `npm test`
21+
- Chain checks with `&&` (e.g. `npm run lint && npx tsc --noEmit && npm test`). Do not paste a single line with middle dots (`·`) as separators—those tokens can be passed to Biome as bogus paths and cause `internalError/io`.
2122
- **Guards:** `npm run check:icons`, `npm run check:imports`
2223

23-
When changing SVGs, run `npm run gen:icons`. When changing i18n keys, run `npm run i18n:all`.
24+
When changing SVGs, run `npm run gen:icons`. When changing i18n keys, run `npm run i18n:all`. Generated [`src/i18n/i18n-types.d.ts`](src/i18n/i18n-types.d.ts) is listed in [`.biomeignore`](.biomeignore) so Biome does not reformat it on every `npm run format`.
2425

2526
## Where code lives
2627

__tests__/ErrorBoundary.test.tsx

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,56 +25,66 @@ function Harness() {
2525
)
2626
}
2727

28-
test('ErrorBoundary shows fallback when child throws', async () => {
29-
let renderer: ReactTestRenderer.ReactTestRenderer
30-
31-
await act(async () => {
32-
renderer = ReactTestRenderer.create(<Harness />)
28+
describe('ErrorBoundary', () => {
29+
beforeEach(() => {
30+
jest.spyOn(console, 'error').mockImplementation(() => {})
3331
})
3432

35-
await act(async () => {
36-
renderer!.root.findByProps({ testID: 'trigger-boom' }).props.onPress()
33+
afterEach(() => {
34+
jest.restoreAllMocks()
3735
})
3836

39-
const treeStr = JSON.stringify(renderer!.toJSON())
40-
expect(treeStr).toContain('Something went wrong')
41-
expect(treeStr).toContain('Try again')
42-
})
37+
test('ErrorBoundary shows fallback when child throws', async () => {
38+
let renderer: ReactTestRenderer.ReactTestRenderer
4339

44-
test('ErrorBoundary retry works after the throwing child is removed', async () => {
45-
function RecoveryHarness() {
46-
const [phase, setPhase] = useState<'ok' | 'error' | 'recovered'>('ok')
47-
return (
48-
<ThemeProvider>
49-
<ErrorBoundary>
50-
{phase === 'error' ? <ThrowingChild /> : <View testID="content" />}
51-
</ErrorBoundary>
52-
<Pressable testID="to-error" onPress={() => setPhase('error')} />
53-
<Pressable testID="recover" onPress={() => setPhase('recovered')} />
54-
</ThemeProvider>
55-
)
56-
}
57-
58-
let renderer: ReactTestRenderer.ReactTestRenderer
59-
await act(async () => {
60-
renderer = ReactTestRenderer.create(<RecoveryHarness />)
61-
})
40+
await act(async () => {
41+
renderer = ReactTestRenderer.create(<Harness />)
42+
})
6243

63-
await act(async () => {
64-
renderer!.root.findByProps({ testID: 'to-error' }).props.onPress()
44+
await act(async () => {
45+
renderer!.root.findByProps({ testID: 'trigger-boom' }).props.onPress()
46+
})
47+
48+
const treeStr = JSON.stringify(renderer!.toJSON())
49+
expect(treeStr).toContain('Something went wrong')
50+
expect(treeStr).toContain('Try again')
6551
})
6652

67-
expect(JSON.stringify(renderer!.toJSON())).toContain('Something went wrong')
53+
test('ErrorBoundary retry works after the throwing child is removed', async () => {
54+
function RecoveryHarness() {
55+
const [phase, setPhase] = useState<'ok' | 'error' | 'recovered'>('ok')
56+
return (
57+
<ThemeProvider>
58+
<ErrorBoundary>
59+
{phase === 'error' ? <ThrowingChild /> : <View testID="content" />}
60+
</ErrorBoundary>
61+
<Pressable testID="to-error" onPress={() => setPhase('error')} />
62+
<Pressable testID="recover" onPress={() => setPhase('recovered')} />
63+
</ThemeProvider>
64+
)
65+
}
6866

69-
await act(async () => {
70-
renderer!.root.findByProps({ testID: 'recover' }).props.onPress()
71-
})
67+
let renderer: ReactTestRenderer.ReactTestRenderer
68+
await act(async () => {
69+
renderer = ReactTestRenderer.create(<RecoveryHarness />)
70+
})
7271

73-
await act(async () => {
74-
renderer!.root
75-
.findByProps({ testID: 'error-boundary-retry' })
76-
.props.onPress()
77-
})
72+
await act(async () => {
73+
renderer!.root.findByProps({ testID: 'to-error' }).props.onPress()
74+
})
75+
76+
expect(JSON.stringify(renderer!.toJSON())).toContain('Something went wrong')
77+
78+
await act(async () => {
79+
renderer!.root.findByProps({ testID: 'recover' }).props.onPress()
80+
})
7881

79-
expect(renderer!.root.findByProps({ testID: 'content' })).toBeDefined()
82+
await act(async () => {
83+
renderer!.root
84+
.findByProps({ testID: 'error-boundary-retry' })
85+
.props.onPress()
86+
})
87+
88+
expect(renderer!.root.findByProps({ testID: 'content' })).toBeDefined()
89+
})
8090
})

declarations.d.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs/TODO.md

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,6 @@
22

33
---
44

5-
## Shipped in this template
6-
7-
These are **already in the repo** (no action required to “add” them):
8-
9-
- [x] Zustand global UI store — `src/shared/stores/`
10-
- [x] Sentry — `@sentry/react-native`, `src/shared/services/monitoring/sentry.ts`, `ErrorBoundary``captureBoundaryError`; [OPERATIONS.md § Sentry](OPERATIONS.md#sentry)
11-
- [x] OTA policy — env placeholders only; no default vendor SDK; [OPERATIONS.md § Over-the-air updates](OPERATIONS.md#over-the-air-updates)
12-
- [x] CI on push/PR — Biome, `tsc`, Jest, `check:icons`, `check:imports``.github/workflows/ci.yml`
13-
- [x] Manual Android / iOS workflows — Node 20, `npm ci`; [OPERATIONS.md § GitHub Actions](OPERATIONS.md#github-actions)
14-
- [x] Maestro smoke starters — `maestro/smoke-*.yaml`; [OPERATIONS.md § Maestro](OPERATIONS.md#maestro)
15-
- [x] Community files — [LICENSE](../LICENSE), [CONTRIBUTING.md](../CONTRIBUTING.md), [CHANGELOG.md](../CHANGELOG.md), [.github/ISSUE_TEMPLATE/](../.github/ISSUE_TEMPLATE/), [.github/PULL_REQUEST_TEMPLATE.md](../.github/PULL_REQUEST_TEMPLATE.md), [.github/CODE_OF_CONDUCT.md](../.github/CODE_OF_CONDUCT.md)
16-
- [x] Single root README + doc matrix in [AGENTS.md](../AGENTS.md) (`#documentation-map`)
17-
18-
---
19-
205
## Before / when you go public (maintainer)
216

227
**Copy-paste text and templates:** [OPERATIONS.md § Publishing & discoverability](OPERATIONS.md#publishing--discoverability).

jest.setup.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,13 @@ jest.mock('react-native-gesture-handler', () => {
121121
},
122122
}
123123
})
124+
125+
// Drop i18next's promotional Locize message on init (noisy in every suite that imports i18n)
126+
const originalConsoleInfo = console.info.bind(console)
127+
console.info = (...args) => {
128+
const msg = typeof args[0] === 'string' ? args[0] : ''
129+
if (msg.includes('Locize') || msg.includes('locize.com')) {
130+
return
131+
}
132+
originalConsoleInfo(...args)
133+
}

src/features/auth/screens/AuthScreen.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,24 @@ export default function AuthScreen() {
488488
},
489489
]}
490490
>
491-
<Svg width={18} height={18} viewBox="0 0 24 24" fill="none" stroke={c.textSecondary} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round">
492-
{isDark
493-
? <><Circle cx="12" cy="12" r="5" /><Path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" /></>
494-
: <Path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
495-
}
491+
<Svg
492+
width={18}
493+
height={18}
494+
viewBox="0 0 24 24"
495+
fill="none"
496+
stroke={c.textSecondary}
497+
strokeWidth={2}
498+
strokeLinecap="round"
499+
strokeLinejoin="round"
500+
>
501+
{isDark ? (
502+
<>
503+
<Circle cx="12" cy="12" r="5" />
504+
<Path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
505+
</>
506+
) : (
507+
<Path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
508+
)}
496509
</Svg>
497510
</TouchableOpacity>
498511
</S>

0 commit comments

Comments
 (0)