class-ai-agent 1.2.3 → 1.3.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.
- package/.agent/README.md +33 -0
- package/.agent/SESSION.md +54 -0
- package/.agent/SESSION.template.md +46 -0
- package/.claude/CLAUDE.md +21 -6
- package/.claude/commands/build.md +5 -4
- package/.claude/commands/debug.md +2 -1
- package/.claude/commands/handoff.md +94 -0
- package/.claude/commands/plan.md +1 -0
- package/.claude/commands/publish-npm.md +119 -0
- package/.claude/commands/resume.md +107 -0
- package/.claude/commands/spec.md +2 -1
- package/.claude/references/agent-continuity.md +42 -0
- package/.claude/references/codegraph.md +50 -0
- package/.claude/rules/agent-continuity.md +39 -0
- package/.claude/skills/agent-continuity/SKILL.md +70 -0
- package/.cursor/CURSOR.md +37 -5
- package/.cursor/commands/build.md +5 -4
- package/.cursor/commands/debug.md +2 -1
- package/.cursor/commands/handoff.md +94 -0
- package/.cursor/commands/plan.md +1 -0
- package/.cursor/commands/publish-npm.md +119 -0
- package/.cursor/commands/resume.md +107 -0
- package/.cursor/commands/spec.md +2 -1
- package/.cursor/mcp.json +15 -0
- package/.cursor/references/agent-continuity.md +42 -0
- package/.cursor/references/codegraph.md +87 -0
- package/.cursor/rules/agent-continuity.mdc +44 -0
- package/.cursor/rules/codegraph.mdc +47 -0
- package/.cursor/rules/cursor-overview.mdc +10 -3
- package/.cursor/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/KIRO.md +146 -0
- package/.kiro/agents/backend.md +395 -0
- package/.kiro/agents/code-reviewer.md +110 -0
- package/.kiro/agents/copywriter-seo.md +236 -0
- package/.kiro/agents/frontend.md +384 -0
- package/.kiro/agents/project-manager.md +201 -0
- package/.kiro/agents/qa.md +221 -0
- package/.kiro/agents/security-auditor.md +143 -0
- package/.kiro/agents/systems-architect.md +211 -0
- package/.kiro/agents/test-engineer.md +123 -0
- package/.kiro/agents/ui-ux-designer.md +210 -0
- package/.kiro/commands/build.md +133 -0
- package/.kiro/commands/debug.md +243 -0
- package/.kiro/commands/deploy.md +40 -0
- package/.kiro/commands/fix-issue.md +42 -0
- package/.kiro/commands/handoff.md +94 -0
- package/.kiro/commands/plan.md +126 -0
- package/.kiro/commands/publish-npm.md +119 -0
- package/.kiro/commands/resume.md +107 -0
- package/.kiro/commands/review.md +50 -0
- package/.kiro/commands/simplify.md +222 -0
- package/.kiro/commands/spec.md +96 -0
- package/.kiro/commands/test.md +214 -0
- package/.kiro/references/accessibility-checklist.md +174 -0
- package/.kiro/references/agent-continuity.md +42 -0
- package/.kiro/references/codegraph.md +86 -0
- package/.kiro/references/performance-checklist.md +150 -0
- package/.kiro/references/security-checklist.md +94 -0
- package/.kiro/references/testing-patterns.md +183 -0
- package/.kiro/settings/mcp.json +15 -0
- package/.kiro/settings.json +8 -0
- package/.kiro/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/skills/code-review/SKILL.md +208 -0
- package/.kiro/skills/deploy/SKILL.md +68 -0
- package/.kiro/skills/deploy/deploy.md +735 -0
- package/.kiro/skills/incremental-implementation/SKILL.md +210 -0
- package/.kiro/skills/security-review/SKILL.md +71 -0
- package/.kiro/skills/tdd/SKILL.md +217 -0
- package/.kiro/skills/ui-ux-pro-max/SKILL.md +288 -0
- package/.kiro/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.kiro/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.kiro/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.kiro/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.kiro/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.kiro/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.kiro/steering/agent-continuity.md +44 -0
- package/.kiro/steering/api-conventions.md +85 -0
- package/.kiro/steering/clean-code.md +211 -0
- package/.kiro/steering/code-style.md +92 -0
- package/.kiro/steering/codegraph.md +47 -0
- package/.kiro/steering/database.md +66 -0
- package/.kiro/steering/error-handling.md +98 -0
- package/.kiro/steering/git-workflow.md +83 -0
- package/.kiro/steering/kiro-overview.md +38 -0
- package/.kiro/steering/monitoring.md +317 -0
- package/.kiro/steering/naming-conventions.md +266 -0
- package/.kiro/steering/project-structure.md +71 -0
- package/.kiro/steering/security.md +95 -0
- package/.kiro/steering/system-design.md +168 -0
- package/.kiro/steering/tech-stack.md +462 -0
- package/.kiro/steering/testing.md +110 -0
- package/AGENTS.md +13 -7
- package/README.md +122 -18
- package/bin/class-ai-agent.cjs +165 -11
- package/package.json +10 -4
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Incremental Implementation
|
|
3
|
+
description: Build features in thin vertical slices with continuous verification
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Incremental Implementation Skill
|
|
7
|
+
|
|
8
|
+
## Philosophy
|
|
9
|
+
|
|
10
|
+
> "The simplest thing that could work."
|
|
11
|
+
|
|
12
|
+
Build in thin vertical slices. Each increment leaves the system working and testable.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## When to Apply
|
|
17
|
+
|
|
18
|
+
**Use this skill when:**
|
|
19
|
+
- Multi-file changes
|
|
20
|
+
- New features
|
|
21
|
+
- Refactoring work
|
|
22
|
+
- Any change > 100 lines
|
|
23
|
+
|
|
24
|
+
**Skip for:**
|
|
25
|
+
- Single-file, small changes
|
|
26
|
+
- Simple bug fixes
|
|
27
|
+
- Configuration updates
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## The Increment Cycle
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌─────────────────────────────────────────┐
|
|
35
|
+
│ 1. Pick smallest complete piece │
|
|
36
|
+
│ ↓ │
|
|
37
|
+
│ 2. Write failing test (RED) │
|
|
38
|
+
│ ↓ │
|
|
39
|
+
│ 3. Implement minimal code (GREEN) │
|
|
40
|
+
│ ↓ │
|
|
41
|
+
│ 4. Refactor if needed │
|
|
42
|
+
│ ↓ │
|
|
43
|
+
│ 5. Run all tests │
|
|
44
|
+
│ ↓ │
|
|
45
|
+
│ 6. Commit with clear message │
|
|
46
|
+
│ ↓ │
|
|
47
|
+
│ 7. Repeat for next piece │
|
|
48
|
+
└─────────────────────────────────────────┘
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Vertical vs Horizontal Slicing
|
|
54
|
+
|
|
55
|
+
### Vertical Slices (Correct)
|
|
56
|
+
|
|
57
|
+
Each slice delivers end-to-end functionality:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Task 1: User can create a task
|
|
61
|
+
└── DB model + API route + UI component
|
|
62
|
+
|
|
63
|
+
Task 2: User can view task list
|
|
64
|
+
└── DB query + API endpoint + List component
|
|
65
|
+
|
|
66
|
+
Task 3: User can complete a task
|
|
67
|
+
└── DB update + API handler + Toggle UI
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Horizontal Slices (Anti-pattern)
|
|
71
|
+
|
|
72
|
+
Layers completed separately:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
Task 1: Create all DB models
|
|
76
|
+
Task 2: Create all API routes
|
|
77
|
+
Task 3: Create all UI components
|
|
78
|
+
|
|
79
|
+
❌ Problem: Nothing works until everything is done
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Slicing Strategies
|
|
85
|
+
|
|
86
|
+
### 1. Happy Path First
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Slice 1: Basic flow works
|
|
90
|
+
Slice 2: Add validation
|
|
91
|
+
Slice 3: Add error handling
|
|
92
|
+
Slice 4: Add edge cases
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Risk-First
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Slice 1: Uncertain/complex piece (reduce risk early)
|
|
99
|
+
Slice 2: Dependent pieces (build on verified foundation)
|
|
100
|
+
Slice 3: Polish (now safe to invest time)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Contract-First
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
Slice 1: Define API contract (types, endpoints)
|
|
107
|
+
Slice 2: Backend implements contract
|
|
108
|
+
Slice 3: Frontend implements against contract
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Rules
|
|
114
|
+
|
|
115
|
+
### The 100-Line Rule
|
|
116
|
+
|
|
117
|
+
> Test before writing more than ~100 lines.
|
|
118
|
+
|
|
119
|
+
If you've written 100+ lines without running tests, stop and verify.
|
|
120
|
+
|
|
121
|
+
### Touch Only What's Needed
|
|
122
|
+
|
|
123
|
+
> Don't refactor adjacent code. Don't add unrequested features.
|
|
124
|
+
|
|
125
|
+
Stay focused on the current task.
|
|
126
|
+
|
|
127
|
+
### Keep It Building
|
|
128
|
+
|
|
129
|
+
> Project must compile and tests must pass after each increment.
|
|
130
|
+
|
|
131
|
+
Never leave the codebase broken between commits.
|
|
132
|
+
|
|
133
|
+
### Feature Flags for Incomplete Work
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// Use flags when merging incomplete features
|
|
137
|
+
if (featureFlags.newCheckout) {
|
|
138
|
+
return <NewCheckoutFlow />;
|
|
139
|
+
}
|
|
140
|
+
return <LegacyCheckout />;
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Safe Defaults
|
|
144
|
+
|
|
145
|
+
New code defaults to conservative, disabled behavior:
|
|
146
|
+
- New features off by default
|
|
147
|
+
- New permissions denied by default
|
|
148
|
+
- New validations strict by default
|
|
149
|
+
|
|
150
|
+
### Rollback-Friendly
|
|
151
|
+
|
|
152
|
+
Each increment should be independently revertable:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# If this commit breaks something, revert just this
|
|
156
|
+
git revert HEAD
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Red Flags
|
|
162
|
+
|
|
163
|
+
**Stop and reassess if you're:**
|
|
164
|
+
|
|
165
|
+
- Writing > 100 lines without testing
|
|
166
|
+
- Mixing unrelated changes in one commit
|
|
167
|
+
- Expanding scope mid-task
|
|
168
|
+
- Breaking the build between increments
|
|
169
|
+
- Creating abstractions "for later"
|
|
170
|
+
- Touching files outside the task scope
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Commit Strategy
|
|
175
|
+
|
|
176
|
+
Each increment = one commit:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Good: Atomic, focused commits
|
|
180
|
+
git commit -m "feat(tasks): add Task model with title and status"
|
|
181
|
+
git commit -m "feat(tasks): add POST /api/tasks endpoint"
|
|
182
|
+
git commit -m "feat(tasks): add CreateTaskForm component"
|
|
183
|
+
|
|
184
|
+
# Bad: Large, unfocused commits
|
|
185
|
+
git commit -m "Add task feature" # 500 lines across 10 files
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## When Stuck
|
|
191
|
+
|
|
192
|
+
If an increment fails:
|
|
193
|
+
|
|
194
|
+
1. **Stop** — Don't push through
|
|
195
|
+
2. **Diagnose** — What specifically failed?
|
|
196
|
+
3. **Reduce scope** — Can you make a smaller increment?
|
|
197
|
+
4. **Ask for help** — If truly blocked
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Verification Checklist
|
|
202
|
+
|
|
203
|
+
After each increment:
|
|
204
|
+
|
|
205
|
+
- [ ] Tests pass
|
|
206
|
+
- [ ] Build succeeds
|
|
207
|
+
- [ ] Code compiles
|
|
208
|
+
- [ ] Feature works (manual check if UI)
|
|
209
|
+
- [ ] Commit is atomic and focused
|
|
210
|
+
- [ ] Message follows conventions
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-review
|
|
3
|
+
description: Skill to perform a thorough security audit of the codebase
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Security Review Skill
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
Systematically scan the codebase for security vulnerabilities and produce a prioritized report.
|
|
10
|
+
|
|
11
|
+
## Checklist
|
|
12
|
+
|
|
13
|
+
### 🔴 Critical (Check First)
|
|
14
|
+
- [ ] Hardcoded secrets, API keys, passwords in source files
|
|
15
|
+
```bash
|
|
16
|
+
grep -r "password\s*=\s*['\"]" src/
|
|
17
|
+
grep -r "api_key\s*=\s*['\"]" src/
|
|
18
|
+
```
|
|
19
|
+
- [ ] `.env` files accidentally committed
|
|
20
|
+
```bash
|
|
21
|
+
git log --all --full-history -- .env
|
|
22
|
+
```
|
|
23
|
+
- [ ] SQL injection via string concatenation
|
|
24
|
+
- [ ] `eval()` or `new Function()` with user input
|
|
25
|
+
|
|
26
|
+
### 🟡 High Priority
|
|
27
|
+
- [ ] Missing authentication on protected routes
|
|
28
|
+
- [ ] Missing authorization (privilege escalation)
|
|
29
|
+
- [ ] Passwords stored in plain text
|
|
30
|
+
- [ ] JWT secrets too short or exposed
|
|
31
|
+
- [ ] No rate limiting on auth endpoints
|
|
32
|
+
- [ ] Missing input validation
|
|
33
|
+
|
|
34
|
+
### 🟢 Medium Priority
|
|
35
|
+
- [ ] Missing security headers (run Helmet scan)
|
|
36
|
+
- [ ] CORS configured too broadly (`origin: *`)
|
|
37
|
+
- [ ] Dependencies with known vulnerabilities
|
|
38
|
+
```bash
|
|
39
|
+
npm audit
|
|
40
|
+
```
|
|
41
|
+
- [ ] Sensitive data in logs
|
|
42
|
+
- [ ] Missing HTTPS enforcement
|
|
43
|
+
|
|
44
|
+
### ℹ️ Low / Informational
|
|
45
|
+
- [ ] Error messages revealing stack traces to client
|
|
46
|
+
- [ ] Missing CSP headers
|
|
47
|
+
- [ ] Cookie security flags (HttpOnly, Secure, SameSite)
|
|
48
|
+
|
|
49
|
+
## Output Format
|
|
50
|
+
```markdown
|
|
51
|
+
# Security Review Report — [Date]
|
|
52
|
+
|
|
53
|
+
## Critical Issues
|
|
54
|
+
[List with file:line references]
|
|
55
|
+
|
|
56
|
+
## High Priority Issues
|
|
57
|
+
[List with file:line references]
|
|
58
|
+
|
|
59
|
+
## Recommendations
|
|
60
|
+
[Prioritized action items]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Commands
|
|
64
|
+
```bash
|
|
65
|
+
# Dependency audit
|
|
66
|
+
npm audit --audit-level=moderate
|
|
67
|
+
|
|
68
|
+
# Check for secret patterns
|
|
69
|
+
grep -rn --include="*.js" --include="*.ts" \
|
|
70
|
+
-E "(password|secret|api_key|token)\s*=\s*['\"][^'\"]{8,}" src/
|
|
71
|
+
```
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Test-Driven Development
|
|
3
|
+
description: Write tests before code using RED-GREEN-REFACTOR cycle
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test-Driven Development Skill
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
TDD transforms testing from an afterthought into the foundation of development. Tests are proof that code works correctly.
|
|
11
|
+
|
|
12
|
+
## When to Invoke
|
|
13
|
+
|
|
14
|
+
- Writing new features
|
|
15
|
+
- Fixing bugs (Prove-It pattern)
|
|
16
|
+
- When asked to write tests
|
|
17
|
+
- Before any implementation work
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Core Cycle: RED-GREEN-REFACTOR
|
|
22
|
+
|
|
23
|
+
### RED Phase
|
|
24
|
+
|
|
25
|
+
Write a test that describes expected behavior. **It must fail.**
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
describe('calculateDiscount', () => {
|
|
29
|
+
it('should apply 10% discount for orders over $100', () => {
|
|
30
|
+
const result = calculateDiscount(150);
|
|
31
|
+
expect(result).toBe(15);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Run: `npm test` → Should **FAIL**
|
|
37
|
+
|
|
38
|
+
### GREEN Phase
|
|
39
|
+
|
|
40
|
+
Write **minimal** code to pass the test. No extras.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
function calculateDiscount(amount) {
|
|
44
|
+
if (amount > 100) return amount * 0.1;
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Run: `npm test` → Should **PASS**
|
|
50
|
+
|
|
51
|
+
### REFACTOR Phase
|
|
52
|
+
|
|
53
|
+
Improve code while keeping tests green.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
const DISCOUNT_THRESHOLD = 100;
|
|
57
|
+
const DISCOUNT_RATE = 0.1;
|
|
58
|
+
|
|
59
|
+
function calculateDiscount(amount) {
|
|
60
|
+
if (amount <= DISCOUNT_THRESHOLD) return 0;
|
|
61
|
+
return amount * DISCOUNT_RATE;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Run: `npm test` → Should still **PASS**
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Prove-It Pattern (Bug Fixes)
|
|
70
|
+
|
|
71
|
+
### Step 1: Write Failing Test
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
it('should handle empty cart without error (bug #456)', () => {
|
|
75
|
+
const cart = new Cart([]);
|
|
76
|
+
expect(() => cart.getTotal()).not.toThrow();
|
|
77
|
+
expect(cart.getTotal()).toBe(0);
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 2: Verify Failure
|
|
82
|
+
|
|
83
|
+
Run test → Confirms bug exists
|
|
84
|
+
|
|
85
|
+
### Step 3: Fix Bug
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
getTotal() {
|
|
89
|
+
if (this.items.length === 0) return 0; // Fix
|
|
90
|
+
return this.items.reduce((sum, item) => sum + item.price, 0);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Step 4: Verify Pass
|
|
95
|
+
|
|
96
|
+
Run test → Confirms fix works
|
|
97
|
+
|
|
98
|
+
### Step 5: Run Full Suite
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm test # No regressions
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Test Pyramid
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
┌─────────┐
|
|
110
|
+
│ E2E │ 5% — Critical user flows
|
|
111
|
+
│ Tests │ Full system, minutes
|
|
112
|
+
├─────────┤
|
|
113
|
+
│ Integr. │ 15% — API + DB interactions
|
|
114
|
+
│ Tests │ Seconds
|
|
115
|
+
├─────────┤
|
|
116
|
+
│ Unit │ 80% — Pure logic
|
|
117
|
+
│ Tests │ Milliseconds
|
|
118
|
+
└─────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Test Structure: AAA Pattern
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
it('should calculate tax for California', () => {
|
|
127
|
+
// Arrange — Setup
|
|
128
|
+
const order = createOrder({ state: 'CA', subtotal: 100 });
|
|
129
|
+
|
|
130
|
+
// Act — Execute
|
|
131
|
+
const tax = calculateTax(order);
|
|
132
|
+
|
|
133
|
+
// Assert — Verify
|
|
134
|
+
expect(tax).toBe(7.25);
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## DAMP > DRY in Tests
|
|
141
|
+
|
|
142
|
+
Tests should be **Descriptive And Meaningful Phrases**.
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// ✅ DAMP — Self-contained and clear
|
|
146
|
+
it('should reject password without uppercase letter', () => {
|
|
147
|
+
const result = validatePassword('lowercase123!');
|
|
148
|
+
|
|
149
|
+
expect(result.valid).toBe(false);
|
|
150
|
+
expect(result.errors).toContain('Must contain uppercase letter');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ❌ Too DRY — Requires reading shared context
|
|
154
|
+
it('should reject invalid password', () => {
|
|
155
|
+
expect(validate(INVALID_PASSWORD_NO_UPPER)).toBe(false);
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Test Doubles (Preference Order)
|
|
162
|
+
|
|
163
|
+
1. **Real implementations** — Best, but may be slow
|
|
164
|
+
2. **Fakes** — In-memory DB, simplified implementations
|
|
165
|
+
3. **Stubs** — Return canned responses
|
|
166
|
+
4. **Mocks** — Verify interactions (use sparingly)
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// ✅ Prefer: Real or fake
|
|
170
|
+
const db = createTestDatabase();
|
|
171
|
+
const user = await userService.create(db, userData);
|
|
172
|
+
|
|
173
|
+
// ⚠️ Use sparingly: Mocks
|
|
174
|
+
const mockDb = { create: vi.fn().mockResolvedValue(user) };
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Naming Conventions
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
// Pattern: should [expected behavior] when [condition]
|
|
183
|
+
|
|
184
|
+
// ✅ Good
|
|
185
|
+
'should return empty array when no users exist'
|
|
186
|
+
'should throw ValidationError when email is invalid'
|
|
187
|
+
'should send welcome email after registration'
|
|
188
|
+
|
|
189
|
+
// ❌ Bad
|
|
190
|
+
'works correctly'
|
|
191
|
+
'test user creation'
|
|
192
|
+
'handles error'
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Anti-Patterns
|
|
198
|
+
|
|
199
|
+
| Pattern | Problem | Solution |
|
|
200
|
+
|---------|---------|----------|
|
|
201
|
+
| Testing internals | Breaks on refactor | Test behavior, not implementation |
|
|
202
|
+
| Flaky tests | Erodes trust | Use deterministic data |
|
|
203
|
+
| Over-mocking | False confidence | Prefer real implementations |
|
|
204
|
+
| Snapshot abuse | Large diffs ignored | Use sparingly |
|
|
205
|
+
| Shared mutable state | Tests affect each other | Reset in beforeEach |
|
|
206
|
+
| Testing frameworks | Wasted effort | Only test your code |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Verification Checklist
|
|
211
|
+
|
|
212
|
+
- [ ] All new code has tests
|
|
213
|
+
- [ ] Bug fixes have reproduction tests
|
|
214
|
+
- [ ] Tests describe behavior (readable names)
|
|
215
|
+
- [ ] No skipped tests
|
|
216
|
+
- [ ] Coverage maintained/improved
|
|
217
|
+
- [ ] Full suite passes
|