Loading...
Loading...
Use when writing tests, adding coverage, implementing business logic, or building features with TDD. Enforces output-based testing of pure functions only - never test imperative shell directly.
npx skill4agent add bumgeunsong/daily-writing-friends testingTESTABLE (Functional Core) │ NOT UNIT TESTED (Imperative Shell)
───────────────────────────────│────────────────────────────────────
Pure functions in utils/ │ React hooks (useX)
Calculations, transformations │ Components (*.tsx)
Validators, formatters │ API calls, Firebase operations
State machines, reducers │ localStorage, Date.now(), Math.random()// ✅ TESTABLE: Pure function
export const calculateStreak = (dates: Date[], today: Date): number => {
// Pure transformation: dates → number
};
// Test with simple input/output
describe('calculateStreak', () => {
it('returns 0 for empty dates', () => {
expect(calculateStreak([], new Date('2024-01-15'))).toBe(0);
});
it('returns consecutive days count', () => {
const dates = [new Date('2024-01-14'), new Date('2024-01-15')];
expect(calculateStreak(dates, new Date('2024-01-15'))).toBe(2);
});
});// ❌ DON'T TEST: Hook with side effects
export function useStreak(userId: string) {
const { data } = useQuery(['streak', userId], () => fetchStreak(userId));
return calculateStreak(data?.dates ?? [], new Date());
}
// ❌ DON'T TEST: Component
const StreakBadge = ({ userId }) => {
const streak = useStreak(userId);
return <Badge>{streak} days</Badge>;
};1. Write failing test for pure function
2. Implement pure function to pass test
3. Create thin hook/component that calls pure function
4. Skip unit tests for hook/component (E2E covers integration)src/
├── feature/
│ ├── utils/
│ │ ├── calculations.ts # Pure functions
│ │ └── calculations.test.ts # Tests here
│ ├── hooks/
│ │ └── useFeature.ts # NO unit tests
│ └── components/
│ └── Feature.tsx # NO unit tests| Mistake | Symptom | Fix |
|---|---|---|
| Testing hooks | | Extract logic to pure function |
| Mocking time | | Inject timestamp as parameter |
| Mocking internals | | Test pure logic, not integration |
| Testing UI | | Only E2E tests for UI |
vi.mock()renderHook()render()QueryClientProviderwrapperdescribe('FeatureName', () => {
describe('when [condition]', () => {
it('[expected outcome]', () => {
// Arrange - Act - Assert (max 3-5 lines)
});
});
});