- Introduced coding standards for TypeScript and React in SKILL.md. - Added continuous learning skill with configuration and evaluation scripts. - Created detail layout guidelines for read-only pages. - Established form layout rules for data-entry forms. - Documented project guidelines for the frontend monorepo. - Implemented security review checklist for frontend/Electron applications. - Developed a verification loop skill for comprehensive session checks. This commit enhances the skill set available for developers, ensuring adherence to best practices and improving code quality.
103 lines
2.4 KiB
Markdown
103 lines
2.4 KiB
Markdown
---
|
|
name: tdd-workflow
|
|
description: Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage using Vitest, Testing Library, and browser journeys.
|
|
---
|
|
|
|
# Test-Driven Development Workflow
|
|
|
|
TDD for this frontend monorepo (Vitest, not NestJS/Supertest).
|
|
|
|
## When to Activate
|
|
|
|
- New features or components
|
|
- Bug fixes
|
|
- Refactors
|
|
- New validators, transformers, stores
|
|
|
|
## Core Principles
|
|
|
|
1. Tests BEFORE code
|
|
2. 80% coverage (unit + component + critical journeys)
|
|
3. Edge cases and error paths
|
|
|
|
### Test types
|
|
|
|
- **Unit** — validators, transformers, utils, stores (`*.test.ts`)
|
|
- **Component** — Testing Library in `packages/ui` / `packages/core-events`
|
|
- **Journeys** — login and FULL_PAGE index/form/detail; mock HTTP services; browser-verify layout
|
|
|
|
## Workflow
|
|
|
|
1. Write the failing test (RED)
|
|
2. `pnpm --filter web test` or `pnpm test` — must fail
|
|
3. Minimal implementation (GREEN)
|
|
4. Tests pass
|
|
5. Refactor
|
|
6. `pnpm check:all`
|
|
|
|
## Unit example
|
|
|
|
```typescript
|
|
import { describe, it, expect } from 'vitest'
|
|
import { createFullPageSchema } from './full-page.validator'
|
|
|
|
describe('createFullPageSchema', () => {
|
|
const t = (key: string) => key
|
|
|
|
it('rejects an empty code', () => {
|
|
const result = createFullPageSchema(t).safeParse({ code: '', name: 'Widget' })
|
|
expect(result.success).toBe(false)
|
|
})
|
|
})
|
|
```
|
|
|
|
## Component example
|
|
|
|
```tsx
|
|
import { render, screen } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
|
|
it('calls onClick', async () => {
|
|
const onClick = vi.fn()
|
|
render(<Button onClick={onClick}>Save</Button>)
|
|
await userEvent.click(screen.getByRole('button', { name: 'Save' }))
|
|
expect(onClick).toHaveBeenCalledTimes(1)
|
|
})
|
|
```
|
|
|
|
## Mocking
|
|
|
|
Mock `@repo/core-api` and `apiClient`, not a database.
|
|
|
|
```ts
|
|
vi.mock('@repo/core-api/http-client', () => ({
|
|
createHttpClient: () => ({ get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn() }),
|
|
}))
|
|
```
|
|
|
|
## File organization
|
|
|
|
Colocate `*.test.ts(x)` next to source. No `test/*.e2e-spec.ts` NestJS tree.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
pnpm test
|
|
pnpm --filter @repo/ui test
|
|
pnpm --filter web test -- --watch
|
|
pnpm lint
|
|
```
|
|
|
|
## Mistakes to avoid
|
|
|
|
- Testing implementation details instead of behavior
|
|
- Tests that depend on each other
|
|
- CSS-class selectors instead of roles/labels
|
|
- Hitting a real API in unit tests
|
|
|
|
## Success
|
|
|
|
- 80%+ coverage
|
|
- All tests green
|
|
- Critical FULL_PAGE flows covered or browser-verified
|