feat(tests-hooks): 23/23 hooks tests pass — useToggle, useAsync, useDebounce, useLocalStorage, useMedia, useInterval, useClipboard, useFetch
- useLocalStorage: retorna tupla [valor, setter] tipada como [T, (v: T|fn) => void] - useAsync: espera microtask act cycle antes de checar status - useClipboard: mock navigator.clipboard.writeText antes - useMedia: mock matchMedia antes - Busca por padrão: act() + waitFor p/ efeitos assíncronos (sem fakeTimers gerais) - docs: PROJECTS-REGISTER, SESSION-STATE (pretérito + presente)
This commit is contained in:
@@ -83,3 +83,69 @@ Quando instalar nova skill:
|
||||
- Recurrence-Count: 1
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## [LRN-20260519-004] category
|
||||
**Logged**: 2026-05-19T23:10:00-03:00
|
||||
**Priority**: high
|
||||
**Status**: pending
|
||||
**Area**: testing
|
||||
|
||||
### Summary
|
||||
Vitest jsdom — mocks obrigatórios antes de renderizar hooks que usam APIs do navegador
|
||||
|
||||
### Details
|
||||
No ambiente jsdom:
|
||||
- `localStorage` não existe → mock com `Object.defineProperty(global, 'localStorage', ...)` antes de qualquer hook useLocalStorage
|
||||
- `navigator.clipboard` não existe → mock antes de useClipboard
|
||||
- `window.matchMedia` não existe → mock antes de useMedia
|
||||
- `setTimeout/setInterval` no useInterval/useDebounce → `vi.useFakeTimers()` em beforeEach
|
||||
- fetch mock global → restaurar em `afterEach` com `global.fetch = originalFetch`
|
||||
|
||||
### Suggested Action
|
||||
Criar um arquivo `tests/setup.ts` com todos os mocks globais e importar em `vitest.config.ts`.
|
||||
|
||||
### Metadata
|
||||
- Source: best_practice
|
||||
- Tags: vitest, jsdom, mocks, testing
|
||||
- Pattern-Key: vitest.jsdom.mocks
|
||||
- Recurrence-Count: 3
|
||||
|
||||
---
|
||||
|
||||
## [LRN-20260519-005] category
|
||||
**Logged**: 2026-05-19T23:10:00-03:00
|
||||
**Priority**: medium
|
||||
**Status**: pending
|
||||
**Area**: testing
|
||||
|
||||
### Summary
|
||||
React Testing Library — renderHook + act() para testar hooks assíncronos
|
||||
|
||||
### Details
|
||||
Hooks que fazem async operations (useAsync, useFetch, useClipboard):
|
||||
1. `renderHook` retorna `{ result }`
|
||||
2. Para atualizações async, sempre envolva em `act(async () => { await ... })`
|
||||
3. Para等待 promises: `await act(async () => { await new Promise(r => setTimeout(r, ms)); })`
|
||||
4. Com fakeTimers: `act(() => { vi.advanceTimersByTime(ms); })`
|
||||
5. Nunca acesse `result.current` diretamente após um await async — sempre dentro de act()
|
||||
|
||||
### Suggested Action
|
||||
Template de teste async:
|
||||
```ts
|
||||
it('descrição', async () => {
|
||||
global.fetch = vi.fn(() => Promise.resolve(makeRes(200, body))) as any;
|
||||
const { result } = renderHook(() => useFetch<T>('/url', {}));
|
||||
|
||||
await act(async () => { await new Promise(r => setTimeout(r, 50)); });
|
||||
|
||||
expect(result.current.status).toBe('success');
|
||||
});
|
||||
```
|
||||
|
||||
### Metadata
|
||||
- Source: best_practice
|
||||
- Tags: react, testing-library, hooks, async, vitest
|
||||
- Pattern-Key: react.testing-library
|
||||
- Recurrence-Count: 3
|
||||
|
||||
Reference in New Issue
Block a user