jettypod 4.1.2 → 4.1.4
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/.nvmrc +1 -0
- package/docs/COMPLETE-TESTING-STRATEGY.md +970 -0
- package/docs/DECISIONS.md +10 -12
- package/docs/NODE_VERSION.md +83 -0
- package/docs/TDD-INFRASTRUCTURE-STRATEGY.md +1374 -0
- package/docs/TESTING-FOR-NON-ENGINEERS.md +1588 -0
- package/docs/TESTING-STRATEGY-AUDIT.md +698 -0
- package/hooks/post-checkout +17 -0
- package/hooks/post-merge +17 -0
- package/hooks/pre-commit +30 -0
- package/jettypod.js +259 -120
- package/lib/coverage-tracker.js +218 -0
- package/lib/database.js +2 -0
- package/lib/db-export.js +192 -0
- package/lib/db-import.js +193 -0
- package/lib/external-transition-handler.js +32 -0
- package/lib/git-hook-helpers.js +174 -0
- package/lib/git-root.js +90 -0
- package/lib/infrastructure-chore-generator.js +45 -0
- package/lib/install-hooks.js +52 -0
- package/lib/jettypod-backup.js +238 -0
- package/lib/merge-lock.js +193 -0
- package/lib/migrations/012-add-worktree-path.js +38 -0
- package/lib/migrations/013-worktrees-table.js +86 -0
- package/lib/migrations/014-migrate-worktree-data.js +161 -0
- package/lib/migrations/015-merge-locks-table.js +67 -0
- package/lib/pattern-finder.js +152 -0
- package/lib/process-manager.js +140 -0
- package/lib/production-standards-reader.js +13 -2
- package/lib/production-standards-writer.js +85 -0
- package/lib/skills/feature-planning/dry-run-validator.js +135 -0
- package/lib/skills/feature-planning/validation-formatter.js +160 -0
- package/lib/smart-conflict-detection.js +168 -0
- package/lib/smart-fetch-rebase.js +614 -0
- package/lib/step-definition-parser.js +76 -0
- package/lib/unit-test-generator.js +232 -0
- package/lib/verification-command-generator.js +66 -0
- package/lib/worktree-diagnostics.js +413 -0
- package/lib/worktree-facade.js +174 -0
- package/lib/worktree-manager.js +636 -0
- package/lib/worktree-reconciler.js +429 -0
- package/package.json +30 -3
- package/skills-templates/external-transition/SKILL.md +34 -3
- package/skills-templates/feature-planning/SKILL.md +190 -24
- package/skills-templates/production-mode/SKILL.md +127 -9
- package/skills-templates/speed-mode/SKILL.md +454 -51
- package/skills-templates/stable-mode/SKILL.md +285 -76
- package/.claude/PROTECT_SKILLS.md +0 -28
- package/.claude/settings.json +0 -24
- package/.claude/settings.local.json +0 -16
- package/.claude/skills/epic-planning/SKILL.md +0 -297
- package/.claude/skills/external-transition/SKILL.md +0 -384
- package/.claude/skills/feature-planning/SKILL.md +0 -464
- package/.claude/skills/production-mode/SKILL.md +0 -369
- package/.claude/skills/speed-mode/SKILL.md +0 -481
- package/.claude/skills/stable-mode/SKILL.md +0 -713
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T16-15-10-070Z/epic-discover/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/stable-mode/SKILL.md +0 -673
- package/.devpod/current-work.json +0 -10
- package/.devpod/work.db +0 -0
- package/.github/workflows/test-safety.yml +0 -85
- package/.jettypod/config.json +0 -5
- package/.jettypod/current-work.json +0 -10
- package/.jettypod/hooks/README.md +0 -77
- package/.jettypod/hooks/protect-claude-md.js +0 -338
- package/.jettypod/test-work.db +0 -0
- package/.jettypod/work.db +0 -0
- package/CLAUDE.md +0 -49
- package/SPEED-STABLE-AUDIT.md +0 -853
- package/SYSTEM-BEHAVIOR.md +0 -2199
- package/TEST_SAFETY_AUDIT.md +0 -314
- package/TEST_SAFETY_IMPLEMENTATION.md +0 -97
- package/cucumber-report.html +0 -45
- package/dist/devpod-linux +0 -0
- package/dist/devpod-macos +0 -0
- package/dist/devpod-win.exe +0 -0
- package/docs/features/jettypod-standards-explained.md +0 -543
- package/docs/features/standards-inventory.md +0 -257
- package/features/auto-generate-production-chores.feature +0 -13
- package/features/backlog-command.feature +0 -26
- package/features/backlog-filtering-production.feature +0 -10
- package/features/claude-md-protection/steps.js +0 -498
- package/features/decisions/index.js +0 -490
- package/features/decisions/index.test.js +0 -208
- package/features/fix-text-wrapping.feature +0 -42
- package/features/git-hooks/git-hooks.feature +0 -30
- package/features/git-hooks/index.js +0 -93
- package/features/git-hooks/index.test.js +0 -137
- package/features/git-hooks/post-commit +0 -56
- package/features/git-hooks/post-merge +0 -47
- package/features/git-hooks/pre-commit +0 -28
- package/features/git-hooks/simple-steps.js +0 -53
- package/features/git-hooks/simple-test.feature +0 -10
- package/features/git-hooks/steps.js +0 -196
- package/features/jettypod-update-command.feature +0 -46
- package/features/mode-prompts/index.js +0 -95
- package/features/mode-prompts/simple-steps.js +0 -44
- package/features/mode-prompts/simple-test.feature +0 -9
- package/features/mode-prompts/validation.test.js +0 -120
- package/features/multiple-claude-instances.feature +0 -121
- package/features/production-mode-skill.feature +0 -121
- package/features/refactor-mode/steps.js +0 -217
- package/features/refactor-mode.feature +0 -49
- package/features/simplify-external-transition.feature +0 -166
- package/features/skills-update/index.test.js +0 -216
- package/features/step_definitions/backlog-command.steps.js +0 -37
- package/features/step_definitions/fix-text-wrapping.steps.js +0 -271
- package/features/step_definitions/multiple-claude-instances.steps.js +0 -621
- package/features/step_definitions/production-mode-skill.steps.js +0 -862
- package/features/step_definitions/simplify-external-transition.steps.js +0 -370
- package/features/step_definitions/terminal-logo.steps.js +0 -145
- package/features/step_definitions/update-command.steps.js +0 -183
- package/features/support/hooks.js +0 -9
- package/features/terminal-logo/index.js +0 -39
- package/features/terminal-logo/terminal-logo.feature +0 -30
- package/features/update-command/index.js +0 -181
- package/features/update-command/index.test.js +0 -225
- package/features/work-commands/bug-workflow-display.feature +0 -22
- package/features/work-commands/index.js +0 -498
- package/features/work-commands/simple-steps.js +0 -69
- package/features/work-commands/stable-tests.feature +0 -57
- package/features/work-commands/steps.js +0 -1174
- package/features/work-commands/validation.test.js +0 -88
- package/features/work-commands/work-commands.feature +0 -13
- package/features/work-tracking/discovery-validation.test.js +0 -228
- package/features/work-tracking/index.js +0 -1921
- package/features/work-tracking/mode-required.feature +0 -112
- package/features/work-tracking/phase-tracking.test.js +0 -482
- package/features/work-tracking/prototype-tracking.test.js +0 -485
- package/features/work-tracking/tree-view.test.js +0 -310
- package/features/work-tracking/work-set-mode.feature +0 -71
- package/features/work-tracking/work-start-mode.feature +0 -88
- package/full-test.txt +0 -0
- package/lib/bug-workflow.test.js +0 -177
- package/lib/claudemd.test.js +0 -195
- package/lib/config.test.js +0 -511
- package/lib/constants.test.js +0 -164
- package/lib/current-work.test.js +0 -146
- package/lib/database-project-config.test.js +0 -111
- package/lib/database.test.js +0 -106
- package/lib/decisions-generator.test.js +0 -457
- package/lib/decisions-helpers.test.js +0 -310
- package/lib/git-coordinator.js +0 -167
- package/lib/git.test.js +0 -145
- package/lib/migrations/002-default-work-item-modes.test.js +0 -351
- package/lib/production-chore-generator.test.js +0 -432
- package/lib/production-context-detector.test.js +0 -277
- package/lib/production-scenario-appender.test.js +0 -235
- package/lib/production-scenario-validator.test.js +0 -246
- package/lib/production-standards-reader.test.js +0 -270
- package/lib/project-state.test.js +0 -92
- package/lib/push-queue.js +0 -417
- package/lib/queue-processor.js +0 -74
- package/lib/test-helpers.js +0 -202
- package/lib/test-helpers.test.js +0 -255
- package/prototypes/2025-01-11-production-mode-autonomous.js +0 -119
- package/prototypes/2025-01-11-production-mode-collaborative.js +0 -166
- package/prototypes/2025-01-11-production-mode-guided.js +0 -217
- package/prototypes/2025-01-11-production-mode-smart-context.js +0 -347
- package/prototypes/2025-01-11-production-standards-example.md +0 -204
- package/prototypes/2025-11-10-backlog-filtering-tree-aware.js +0 -242
- package/prototypes/test/index.html +0 -1
- package/setup-dist-repo.sh +0 -68
- package/test-production-standards-engine.js +0 -130
- package/test-results.json +0 -2195
- package/test-safety-check.sh +0 -80
- package/work-item-tracking-plan.md +0 -199
- /package/{.jettypod/devpod.db → jettypod.db} +0 -0
|
@@ -0,0 +1,1374 @@
|
|
|
1
|
+
# TDD Infrastructure & Testing Strategy for JettyPod
|
|
2
|
+
|
|
3
|
+
**Date**: 2025-11-14
|
|
4
|
+
**Scope**: Test-Driven Development strategy across Feature Planning → Speed → Stable → Production modes, plus standalone chores
|
|
5
|
+
**Focus**: WHEN tests run, WHAT tests run, maximum velocity + quality assurance
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Executive Summary
|
|
10
|
+
|
|
11
|
+
**Philosophy**: Tests should run at the right time, in the right place, with the right scope to maximize feedback velocity while maintaining quality gates.
|
|
12
|
+
|
|
13
|
+
**Key Insight**: Your pre-commit hook is currently **disabled** (`.git/hooks/pre-commit.disabled`). This is actually smart for your workflow, but you need a better strategy.
|
|
14
|
+
|
|
15
|
+
**Recommendation**: Different test execution strategies for different workflow phases + smart git hooks that adapt to context.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Current State Analysis
|
|
20
|
+
|
|
21
|
+
### What You Have Today
|
|
22
|
+
|
|
23
|
+
**Test Infrastructure:**
|
|
24
|
+
- ✅ Jest for unit tests
|
|
25
|
+
- ✅ Cucumber for BDD tests
|
|
26
|
+
- ✅ Test cleanup script
|
|
27
|
+
- ✅ `npm test` runs: unit → BDD → cleanup
|
|
28
|
+
|
|
29
|
+
**Git Hooks:**
|
|
30
|
+
- ✅ `post-commit`: Updates work item status todo → in_progress, regenerates docs
|
|
31
|
+
- ✅ `post-merge`: Updates work item status → done when merging to main
|
|
32
|
+
- ⚠️ `pre-commit`: **DISABLED** - would run full test suite
|
|
33
|
+
|
|
34
|
+
**Test Script:**
|
|
35
|
+
```json
|
|
36
|
+
"test": "npm run test:unit && npm run test:bdd && npm run test:cleanup"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Problems with current pre-commit hook:**
|
|
40
|
+
1. Runs ENTIRE test suite on every commit → slow
|
|
41
|
+
2. Blocks commits during TDD red-green-refactor cycle
|
|
42
|
+
3. Not context-aware (speed mode vs stable mode have different needs)
|
|
43
|
+
4. No differentiation between local commits vs push to remote
|
|
44
|
+
|
|
45
|
+
**Why it's disabled**: Smart move. Full test suite on every commit kills velocity.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## The TDD Testing Strategy
|
|
50
|
+
|
|
51
|
+
### Core Principle: Context-Aware Testing
|
|
52
|
+
|
|
53
|
+
Different workflow phases need different test strategies:
|
|
54
|
+
|
|
55
|
+
| Phase | Test Focus | Speed Need | Quality Gate |
|
|
56
|
+
|-------|-----------|------------|--------------|
|
|
57
|
+
| **Feature-planning** | Infrastructure validation | Very fast | Syntax check |
|
|
58
|
+
| **Speed-mode** | Happy path only | Fast iteration | BDD happy path passes |
|
|
59
|
+
| **Stable-mode** | Comprehensive coverage | Thorough validation | All BDD scenarios pass |
|
|
60
|
+
| **Production-mode** | Security/scale/compliance | Thorough validation | Production scenarios pass |
|
|
61
|
+
| **Standalone chore** | Isolated functionality | Fast iteration | Relevant tests pass |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Test Execution Timeline: WHEN to Run Tests
|
|
66
|
+
|
|
67
|
+
### 1. Feature-Planning Phase
|
|
68
|
+
|
|
69
|
+
**Test Activity:**
|
|
70
|
+
- ✅ Write BDD scenario (happy path)
|
|
71
|
+
- ✅ Write step definitions
|
|
72
|
+
- ✅ **NEW**: Validate test infrastructure
|
|
73
|
+
|
|
74
|
+
**When tests run:**
|
|
75
|
+
```
|
|
76
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
77
|
+
│ After creating .feature + .steps.js files: │
|
|
78
|
+
│ → Dry-run validation (5 seconds) │
|
|
79
|
+
│ → Ensures syntax correct + steps match │
|
|
80
|
+
│ → Catches errors BEFORE speed-mode starts │
|
|
81
|
+
└─────────────────────────────────────────────────────────────┘
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**No git hook needed** - skill executes validation internally.
|
|
85
|
+
|
|
86
|
+
**Command:**
|
|
87
|
+
```bash
|
|
88
|
+
npx cucumber-js --dry-run features/[feature-slug].feature
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**What this catches:**
|
|
92
|
+
- Step definition syntax errors
|
|
93
|
+
- Missing step implementations
|
|
94
|
+
- Gherkin syntax errors
|
|
95
|
+
- Import/require errors
|
|
96
|
+
|
|
97
|
+
**Why dry-run not full execution:**
|
|
98
|
+
- Implementation doesn't exist yet
|
|
99
|
+
- Just validating test infrastructure
|
|
100
|
+
- Very fast (< 5s)
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### 2. Speed-Mode Phase
|
|
105
|
+
|
|
106
|
+
**Test Activity:**
|
|
107
|
+
- ✅ Implement code to make happy path pass
|
|
108
|
+
- ✅ Run BDD tests continuously
|
|
109
|
+
- ✅ Iterate until tests pass
|
|
110
|
+
|
|
111
|
+
**When tests run:**
|
|
112
|
+
```
|
|
113
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
114
|
+
│ During implementation (inside skill loop): │
|
|
115
|
+
│ → After each code change │
|
|
116
|
+
│ → Only BDD tests for THIS feature │
|
|
117
|
+
│ → Fast feedback loop (30-60s) │
|
|
118
|
+
│ │
|
|
119
|
+
│ Before marking chore done: │
|
|
120
|
+
│ → Full feature BDD test suite │
|
|
121
|
+
│ → Ensures happy path works end-to-end │
|
|
122
|
+
└─────────────────────────────────────────────────────────────┘
|
|
123
|
+
|
|
124
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
125
|
+
│ Before commit (pre-commit hook - SMART VERSION): │
|
|
126
|
+
│ → Quick smoke test (30s) │
|
|
127
|
+
│ → Only tests related to changed files │
|
|
128
|
+
│ → Can be skipped with --no-verify if iterating │
|
|
129
|
+
└─────────────────────────────────────────────────────────────┘
|
|
130
|
+
|
|
131
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
132
|
+
│ Before push (pre-push hook - NEW): │
|
|
133
|
+
│ → Full test suite (unit + BDD) │
|
|
134
|
+
│ → Harder to bypass │
|
|
135
|
+
│ → Quality gate before sharing work │
|
|
136
|
+
└─────────────────────────────────────────────────────────────┘
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Git hooks strategy:**
|
|
140
|
+
- **pre-commit**: FAST, FOCUSED, BYPASSABLE - for rapid iteration
|
|
141
|
+
- **pre-push**: COMPREHENSIVE, MANDATORY - before sharing
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### 3. Stable-Mode Phase
|
|
146
|
+
|
|
147
|
+
**Test Activity:**
|
|
148
|
+
- ✅ Add error handling + validation
|
|
149
|
+
- ✅ Create error/edge case scenarios
|
|
150
|
+
- ✅ Run comprehensive test suite
|
|
151
|
+
- ✅ Ensure no regressions
|
|
152
|
+
|
|
153
|
+
**When tests run:**
|
|
154
|
+
```
|
|
155
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
156
|
+
│ During implementation (inside skill loop): │
|
|
157
|
+
│ → After each code change │
|
|
158
|
+
│ → ALL BDD scenarios for feature │
|
|
159
|
+
│ → Regression check (happy path still works) │
|
|
160
|
+
│ → Timeout protection (60s) │
|
|
161
|
+
│ │
|
|
162
|
+
│ Before marking chore done: │
|
|
163
|
+
│ → Full feature BDD test suite │
|
|
164
|
+
│ → All unit tests (if any created) │
|
|
165
|
+
│ → Ensures comprehensive coverage │
|
|
166
|
+
└─────────────────────────────────────────────────────────────┘
|
|
167
|
+
|
|
168
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
169
|
+
│ Before commit (pre-commit hook - SMART VERSION): │
|
|
170
|
+
│ → Run tests for changed files + dependencies │
|
|
171
|
+
│ → ~1-2 minutes acceptable (more thorough phase) │
|
|
172
|
+
└─────────────────────────────────────────────────────────────┘
|
|
173
|
+
|
|
174
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
175
|
+
│ Before push (pre-push hook): │
|
|
176
|
+
│ → FULL test suite (unit + BDD + cleanup) │
|
|
177
|
+
│ → Hard requirement │
|
|
178
|
+
│ → Quality gate before merge │
|
|
179
|
+
└─────────────────────────────────────────────────────────────┘
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### 4. Production-Mode Phase
|
|
185
|
+
|
|
186
|
+
**Test Activity:**
|
|
187
|
+
- ✅ Add security/scale/compliance scenarios
|
|
188
|
+
- ✅ Implement production hardening
|
|
189
|
+
- ✅ Run production scenarios
|
|
190
|
+
|
|
191
|
+
**When tests run:**
|
|
192
|
+
```
|
|
193
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
194
|
+
│ During implementation (inside skill loop): │
|
|
195
|
+
│ → After each code change │
|
|
196
|
+
│ → Production scenarios with @production tag │
|
|
197
|
+
│ → Longer timeout (2 minutes) │
|
|
198
|
+
│ → May include performance benchmarks │
|
|
199
|
+
│ │
|
|
200
|
+
│ Before marking chore done: │
|
|
201
|
+
│ → ALL scenarios (happy + error + production) │
|
|
202
|
+
│ → Full regression suite │
|
|
203
|
+
│ → Performance benchmarks (if defined) │
|
|
204
|
+
└─────────────────────────────────────────────────────────────┘
|
|
205
|
+
|
|
206
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
207
|
+
│ Before push (pre-push hook): │
|
|
208
|
+
│ → FULL test suite including production scenarios │
|
|
209
|
+
│ → Performance regression check │
|
|
210
|
+
│ → Security test validation │
|
|
211
|
+
└─────────────────────────────────────────────────────────────┘
|
|
212
|
+
|
|
213
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
214
|
+
│ Before merge to main (CI/CD - RECOMMENDED): │
|
|
215
|
+
│ → Full test suite on clean checkout │
|
|
216
|
+
│ → Performance benchmarks against baseline │
|
|
217
|
+
│ → Security scanning │
|
|
218
|
+
│ → Final quality gate │
|
|
219
|
+
└─────────────────────────────────────────────────────────────┘
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### 5. Standalone Chore Phase
|
|
225
|
+
|
|
226
|
+
**Test Activity:**
|
|
227
|
+
- ✅ Write tests for isolated functionality
|
|
228
|
+
- ✅ Implement with safety patterns
|
|
229
|
+
- ✅ Run relevant tests only
|
|
230
|
+
|
|
231
|
+
**When tests run:**
|
|
232
|
+
```
|
|
233
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
234
|
+
│ During implementation (TDD cycle): │
|
|
235
|
+
│ → After each code change │
|
|
236
|
+
│ → Only tests for THIS chore's scope │
|
|
237
|
+
│ → Fast iteration (< 30s) │
|
|
238
|
+
│ │
|
|
239
|
+
│ Before marking chore done: │
|
|
240
|
+
│ → Tests for chore scope │
|
|
241
|
+
│ → Smoke test to ensure no breakage elsewhere │
|
|
242
|
+
└─────────────────────────────────────────────────────────────┘
|
|
243
|
+
|
|
244
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
245
|
+
│ Before commit (pre-commit hook - SMART VERSION): │
|
|
246
|
+
│ → Tests for changed files │
|
|
247
|
+
│ → Quick smoke test │
|
|
248
|
+
└─────────────────────────────────────────────────────────────┘
|
|
249
|
+
|
|
250
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
251
|
+
│ Before push (pre-push hook): │
|
|
252
|
+
│ → Full test suite (ensure no regressions) │
|
|
253
|
+
└─────────────────────────────────────────────────────────────┘
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Smart Git Hooks Design
|
|
259
|
+
|
|
260
|
+
### Problem with Current Approach
|
|
261
|
+
|
|
262
|
+
**Your disabled pre-commit hook:**
|
|
263
|
+
```javascript
|
|
264
|
+
// Runs EVERYTHING on EVERY commit
|
|
265
|
+
execSync('npm test', { stdio: 'inherit' });
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Why this kills velocity:**
|
|
269
|
+
1. Full test suite might take 2-5 minutes
|
|
270
|
+
2. Blocks TDD red-green-refactor cycle
|
|
271
|
+
3. Discourages frequent commits
|
|
272
|
+
4. Tempts developers to use `--no-verify` always
|
|
273
|
+
|
|
274
|
+
### Solution: Context-Aware Hooks
|
|
275
|
+
|
|
276
|
+
#### Smart Pre-Commit Hook (NEW)
|
|
277
|
+
|
|
278
|
+
**Philosophy**: Fast, focused, helpful during iteration.
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
#!/usr/bin/env node
|
|
282
|
+
// Smart pre-commit hook: Fast, focused tests
|
|
283
|
+
|
|
284
|
+
const { execSync } = require('child_process');
|
|
285
|
+
const fs = require('fs');
|
|
286
|
+
const path = require('path');
|
|
287
|
+
|
|
288
|
+
// Skip if not a real project
|
|
289
|
+
if (!fs.existsSync('package.json')) process.exit(0);
|
|
290
|
+
|
|
291
|
+
// Get current work context
|
|
292
|
+
const currentWorkPath = '.jettypod/current-work.json';
|
|
293
|
+
let currentWork = null;
|
|
294
|
+
let workMode = null;
|
|
295
|
+
|
|
296
|
+
if (fs.existsSync(currentWorkPath)) {
|
|
297
|
+
currentWork = JSON.parse(fs.readFileSync(currentWorkPath, 'utf-8'));
|
|
298
|
+
workMode = currentWork.mode; // speed, stable, production
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Get changed files
|
|
302
|
+
const changedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
|
|
303
|
+
.split('\n')
|
|
304
|
+
.filter(f => f.trim());
|
|
305
|
+
|
|
306
|
+
console.log(`\n🧪 Running focused tests (${workMode || 'general'} mode)...\n`);
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
// Strategy varies by mode
|
|
310
|
+
if (workMode === 'speed') {
|
|
311
|
+
// SPEED MODE: Very fast, just syntax and current feature
|
|
312
|
+
console.log('Speed mode: Fast validation only');
|
|
313
|
+
|
|
314
|
+
// 1. Lint changed files
|
|
315
|
+
const jsFiles = changedFiles.filter(f => f.endsWith('.js'));
|
|
316
|
+
if (jsFiles.length > 0) {
|
|
317
|
+
console.log(' → Linting changed files...');
|
|
318
|
+
// Could add: execSync(`eslint ${jsFiles.join(' ')}`, { stdio: 'inherit' });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// 2. If feature file changed, validate it
|
|
322
|
+
const featureFiles = changedFiles.filter(f => f.endsWith('.feature'));
|
|
323
|
+
if (featureFiles.length > 0) {
|
|
324
|
+
console.log(' → Validating BDD scenarios...');
|
|
325
|
+
featureFiles.forEach(f => {
|
|
326
|
+
execSync(`npx cucumber-js --dry-run ${f}`, { stdio: 'inherit' });
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// 3. Run only tests for current feature (if working on feature)
|
|
331
|
+
if (currentWork && currentWork.parent_id) {
|
|
332
|
+
const db = require('./.jettypod/work.db');
|
|
333
|
+
// Get feature's scenario file
|
|
334
|
+
// Run only that feature's tests
|
|
335
|
+
console.log(' → Testing current feature only...');
|
|
336
|
+
// execSync('npx cucumber-js features/current-feature.feature', { stdio: 'inherit' });
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
console.log('\n✅ Speed mode validation passed (~15s)\n');
|
|
340
|
+
|
|
341
|
+
} else if (workMode === 'stable') {
|
|
342
|
+
// STABLE MODE: More thorough, but still focused
|
|
343
|
+
console.log('Stable mode: Focused regression testing');
|
|
344
|
+
|
|
345
|
+
// 1. Run unit tests for changed files
|
|
346
|
+
const testFiles = changedFiles
|
|
347
|
+
.filter(f => f.endsWith('.js') && !f.includes('node_modules'))
|
|
348
|
+
.map(f => f.replace(/\.js$/, '.test.js'))
|
|
349
|
+
.filter(f => fs.existsSync(f));
|
|
350
|
+
|
|
351
|
+
if (testFiles.length > 0) {
|
|
352
|
+
console.log(' → Running unit tests for changed files...');
|
|
353
|
+
execSync(`npx jest ${testFiles.join(' ')}`, { stdio: 'inherit' });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// 2. Run current feature's full BDD suite
|
|
357
|
+
if (currentWork && currentWork.parent_id) {
|
|
358
|
+
console.log(' → Running full BDD suite for current feature...');
|
|
359
|
+
// Run all scenarios for this feature
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
console.log('\n✅ Stable mode validation passed (~45s)\n');
|
|
363
|
+
|
|
364
|
+
} else if (workMode === 'production') {
|
|
365
|
+
// PRODUCTION MODE: Comprehensive, including production scenarios
|
|
366
|
+
console.log('Production mode: Comprehensive validation');
|
|
367
|
+
|
|
368
|
+
// Run full suite but with focus on production scenarios
|
|
369
|
+
execSync('npm run test:unit', { stdio: 'inherit' });
|
|
370
|
+
execSync('npx cucumber-js --tags "@production"', { stdio: 'inherit' });
|
|
371
|
+
|
|
372
|
+
console.log('\n✅ Production mode validation passed (~90s)\n');
|
|
373
|
+
|
|
374
|
+
} else {
|
|
375
|
+
// STANDALONE CHORE or NO CONTEXT: Focused on changed files only
|
|
376
|
+
console.log('Standalone: Testing changed files only');
|
|
377
|
+
|
|
378
|
+
// Run tests that match changed files
|
|
379
|
+
const testPattern = changedFiles
|
|
380
|
+
.filter(f => f.endsWith('.js'))
|
|
381
|
+
.map(f => path.basename(f, '.js'))
|
|
382
|
+
.join('|');
|
|
383
|
+
|
|
384
|
+
if (testPattern) {
|
|
385
|
+
execSync(`npx jest --testNamePattern="${testPattern}"`, { stdio: 'inherit' });
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
console.log('\n✅ Focused tests passed (~20s)\n');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
console.log('💡 Tip: Use --no-verify to skip if iterating rapidly\n');
|
|
392
|
+
process.exit(0);
|
|
393
|
+
|
|
394
|
+
} catch (err) {
|
|
395
|
+
console.log('\n❌ Tests failed!\n');
|
|
396
|
+
console.log('Options:');
|
|
397
|
+
console.log(' 1. Fix the failing tests');
|
|
398
|
+
console.log(' 2. Use --no-verify to skip (not recommended)');
|
|
399
|
+
console.log(' 3. Use git commit --amend to adjust\n');
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Key features:**
|
|
405
|
+
- ⚡ Context-aware: Different strategies for speed/stable/production
|
|
406
|
+
- ⚡ Fast: 15-90s depending on mode
|
|
407
|
+
- ⚡ Focused: Only tests relevant to changes
|
|
408
|
+
- ⚡ Bypassable: Can skip with --no-verify for rapid iteration
|
|
409
|
+
- ⚡ Helpful: Tells you what it's doing and why
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
#### Smart Pre-Push Hook (NEW)
|
|
414
|
+
|
|
415
|
+
**Philosophy**: Comprehensive quality gate before sharing.
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
#!/usr/bin/env node
|
|
419
|
+
// Pre-push hook: Comprehensive quality gate
|
|
420
|
+
|
|
421
|
+
const { execSync } = require('child_process');
|
|
422
|
+
const fs = require('fs');
|
|
423
|
+
|
|
424
|
+
console.log('\n🚀 Running full test suite before push...\n');
|
|
425
|
+
console.log('This ensures code quality before sharing with team.\n');
|
|
426
|
+
|
|
427
|
+
try {
|
|
428
|
+
// ALWAYS run full suite before push
|
|
429
|
+
console.log('1/3 Running unit tests...');
|
|
430
|
+
execSync('npm run test:unit', { stdio: 'inherit' });
|
|
431
|
+
|
|
432
|
+
console.log('\n2/3 Running BDD tests...');
|
|
433
|
+
execSync('npm run test:bdd', { stdio: 'inherit' });
|
|
434
|
+
|
|
435
|
+
console.log('\n3/3 Running cleanup validation...');
|
|
436
|
+
execSync('npm run test:cleanup', { stdio: 'inherit' });
|
|
437
|
+
|
|
438
|
+
console.log('\n✅ All tests passed! Push approved.\n');
|
|
439
|
+
process.exit(0);
|
|
440
|
+
|
|
441
|
+
} catch (err) {
|
|
442
|
+
console.log('\n❌ Tests failed! Push blocked.\n');
|
|
443
|
+
console.log('⚠️ Pre-push hooks are harder to bypass (intentionally).\n');
|
|
444
|
+
console.log('Options:');
|
|
445
|
+
console.log(' 1. Fix the failing tests (recommended)');
|
|
446
|
+
console.log(' 2. Use --no-verify to force push (use sparingly)\n');
|
|
447
|
+
console.log('Why this matters:');
|
|
448
|
+
console.log(' • Pushing broken code affects the whole team');
|
|
449
|
+
console.log(' • CI/CD will fail anyway');
|
|
450
|
+
console.log(' • Better to catch issues locally\n');
|
|
451
|
+
process.exit(1);
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
**Key features:**
|
|
456
|
+
- 🛡️ Comprehensive: Full test suite always
|
|
457
|
+
- 🛡️ Quality gate: Before sharing with team
|
|
458
|
+
- 🛡️ Clear messaging: Explains why it matters
|
|
459
|
+
- 🛡️ Harder to bypass: Requires explicit --no-verify
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
### Hook Comparison
|
|
464
|
+
|
|
465
|
+
| Hook | When | Speed | Scope | Bypassable | Purpose |
|
|
466
|
+
|------|------|-------|-------|------------|---------|
|
|
467
|
+
| **pre-commit** | Every commit | Fast (15-90s) | Focused on changes | Yes (--no-verify) | Rapid iteration feedback |
|
|
468
|
+
| **pre-push** | Before push | Full (2-5min) | Complete test suite | Technically yes, discouraged | Quality gate before sharing |
|
|
469
|
+
| **post-commit** | After commit | Instant | No tests | N/A | Status tracking + docs |
|
|
470
|
+
| **post-merge** | After merge to main | Instant | No tests | N/A | Mark work done |
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Test Organization Strategy
|
|
475
|
+
|
|
476
|
+
### Test Types and When to Use Them
|
|
477
|
+
|
|
478
|
+
#### 1. Unit Tests (Jest)
|
|
479
|
+
|
|
480
|
+
**What:** Test isolated functions/modules in isolation.
|
|
481
|
+
|
|
482
|
+
**When to write:**
|
|
483
|
+
- Stable mode (when adding error handling)
|
|
484
|
+
- Standalone chores (for utility functions)
|
|
485
|
+
- Complex algorithms or business logic
|
|
486
|
+
|
|
487
|
+
**When to run:**
|
|
488
|
+
- During development (watch mode)
|
|
489
|
+
- Pre-commit (for changed files)
|
|
490
|
+
- Pre-push (all unit tests)
|
|
491
|
+
|
|
492
|
+
**Structure:**
|
|
493
|
+
```
|
|
494
|
+
lib/
|
|
495
|
+
merge-lock.js
|
|
496
|
+
merge-lock.test.js ← Unit tests here
|
|
497
|
+
validators.js
|
|
498
|
+
validators.test.js ← Unit tests here
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Example:**
|
|
502
|
+
```javascript
|
|
503
|
+
// lib/validators.test.js
|
|
504
|
+
describe('validateEmail', () => {
|
|
505
|
+
it('accepts valid emails', () => {
|
|
506
|
+
expect(validateEmail('user@example.com')).toBe(true);
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
it('rejects invalid emails', () => {
|
|
510
|
+
expect(validateEmail('not-an-email')).toBe(false);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it('handles null/undefined', () => {
|
|
514
|
+
expect(validateEmail(null)).toBe(false);
|
|
515
|
+
expect(validateEmail(undefined)).toBe(false);
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Characteristics:**
|
|
521
|
+
- ✅ Very fast (milliseconds)
|
|
522
|
+
- ✅ No external dependencies
|
|
523
|
+
- ✅ Great for TDD
|
|
524
|
+
- ✅ Easy to debug
|
|
525
|
+
- ✅ High coverage possible
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
#### 2. BDD Integration Tests (Cucumber)
|
|
530
|
+
|
|
531
|
+
**What:** Test complete user workflows end-to-end.
|
|
532
|
+
|
|
533
|
+
**When to write:**
|
|
534
|
+
- Feature-planning (happy path)
|
|
535
|
+
- Stable mode (error + edge cases)
|
|
536
|
+
- Production mode (security/scale/compliance)
|
|
537
|
+
|
|
538
|
+
**When to run:**
|
|
539
|
+
- During implementation (inside skill loops)
|
|
540
|
+
- Pre-commit (for current feature)
|
|
541
|
+
- Pre-push (all features)
|
|
542
|
+
|
|
543
|
+
**Structure:**
|
|
544
|
+
```
|
|
545
|
+
features/
|
|
546
|
+
merge-lock.feature ← Gherkin scenarios
|
|
547
|
+
step_definitions/
|
|
548
|
+
merge-lock.steps.js ← Step implementations
|
|
549
|
+
support/
|
|
550
|
+
hooks.js ← Before/After hooks
|
|
551
|
+
world.js ← Shared context
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
**Example:**
|
|
555
|
+
```gherkin
|
|
556
|
+
# features/merge-lock.feature
|
|
557
|
+
|
|
558
|
+
Feature: Merge Lock Protection
|
|
559
|
+
Prevent simultaneous merges that could corrupt work state
|
|
560
|
+
|
|
561
|
+
Scenario: Acquire lock successfully
|
|
562
|
+
Given no merge is in progress
|
|
563
|
+
When I start a merge operation
|
|
564
|
+
Then I acquire the merge lock
|
|
565
|
+
And the lock file exists
|
|
566
|
+
|
|
567
|
+
Scenario: Lock blocks concurrent merge (Stable mode)
|
|
568
|
+
Given a merge is already in progress
|
|
569
|
+
When I attempt to start another merge
|
|
570
|
+
Then I receive a "merge in progress" error
|
|
571
|
+
And the second merge is blocked
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**Characteristics:**
|
|
575
|
+
- ⚠️ Slower (seconds per scenario)
|
|
576
|
+
- ✅ Tests real integration
|
|
577
|
+
- ✅ Readable by non-developers
|
|
578
|
+
- ✅ Living documentation
|
|
579
|
+
- ⚠️ Harder to debug
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
#### 3. Test Safety Infrastructure (Hooks)
|
|
584
|
+
|
|
585
|
+
**What:** Ensure tests don't corrupt production code.
|
|
586
|
+
|
|
587
|
+
**When to write:**
|
|
588
|
+
- ALWAYS when writing BDD step definitions
|
|
589
|
+
- Reference ai-test-writing-requirements.md patterns
|
|
590
|
+
|
|
591
|
+
**Structure:**
|
|
592
|
+
```javascript
|
|
593
|
+
// features/support/hooks.js
|
|
594
|
+
|
|
595
|
+
const { Before, After } = require('@cucumber/cucumber');
|
|
596
|
+
const fs = require('fs');
|
|
597
|
+
|
|
598
|
+
Before(function() {
|
|
599
|
+
// Track everything created
|
|
600
|
+
this.createdFiles = [];
|
|
601
|
+
this.createdDirs = [];
|
|
602
|
+
|
|
603
|
+
// Snapshot critical files
|
|
604
|
+
this.snapshots = {
|
|
605
|
+
packageJson: fs.existsSync('package.json')
|
|
606
|
+
? fs.readFileSync('package.json', 'utf-8')
|
|
607
|
+
: null,
|
|
608
|
+
config: fs.existsSync('.jettypod/config.json')
|
|
609
|
+
? fs.readFileSync('.jettypod/config.json', 'utf-8')
|
|
610
|
+
: null
|
|
611
|
+
};
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
After(function() {
|
|
615
|
+
// Restore critical files FIRST
|
|
616
|
+
if (this.snapshots?.packageJson) {
|
|
617
|
+
fs.writeFileSync('package.json', this.snapshots.packageJson);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Clean up created files
|
|
621
|
+
this.createdFiles?.forEach(file => {
|
|
622
|
+
if (fs.existsSync(file)) {
|
|
623
|
+
try { fs.unlinkSync(file); } catch (e) {}
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
// Clean up created directories (reverse order)
|
|
628
|
+
this.createdDirs?.reverse().forEach(dir => {
|
|
629
|
+
if (fs.existsSync(dir)) {
|
|
630
|
+
try { fs.rmSync(dir, { recursive: true }); } catch (e) {}
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
});
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Characteristics:**
|
|
637
|
+
- ✅ Prevents test pollution
|
|
638
|
+
- ✅ Protects production code
|
|
639
|
+
- ✅ Required for safe BDD tests
|
|
640
|
+
- ✅ Automatic cleanup
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
## Recommended Testing Strategy by Workflow Phase
|
|
645
|
+
|
|
646
|
+
### Feature-Planning Phase
|
|
647
|
+
|
|
648
|
+
**Goal**: Validate test infrastructure, not implementation.
|
|
649
|
+
|
|
650
|
+
```
|
|
651
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
652
|
+
│ Tests Written: │
|
|
653
|
+
│ ✅ BDD happy path scenario │
|
|
654
|
+
│ ✅ Step definitions (with safety patterns) │
|
|
655
|
+
│ │
|
|
656
|
+
│ Tests Run: │
|
|
657
|
+
│ ✅ Dry-run validation (syntax check) │
|
|
658
|
+
│ ⏱️ ~5 seconds │
|
|
659
|
+
│ │
|
|
660
|
+
│ Git Hooks: │
|
|
661
|
+
│ ❌ None (validation inside skill) │
|
|
662
|
+
│ │
|
|
663
|
+
│ Quality Gate: │
|
|
664
|
+
│ ✅ BDD infrastructure valid │
|
|
665
|
+
│ ✅ Step definitions match scenario │
|
|
666
|
+
└─────────────────────────────────────────────────────────────┘
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Skill integration:**
|
|
670
|
+
```javascript
|
|
671
|
+
// At end of feature-planning skill
|
|
672
|
+
console.log('🧪 Validating BDD infrastructure...');
|
|
673
|
+
|
|
674
|
+
try {
|
|
675
|
+
execSync(`npx cucumber-js --dry-run ${scenarioFile}`, {
|
|
676
|
+
stdio: 'pipe',
|
|
677
|
+
timeout: 5000
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
console.log('✅ BDD infrastructure validated');
|
|
681
|
+
console.log('✅ Step definitions match scenario steps');
|
|
682
|
+
console.log('✅ Ready for speed-mode implementation');
|
|
683
|
+
|
|
684
|
+
} catch (err) {
|
|
685
|
+
console.error('❌ BDD infrastructure broken:');
|
|
686
|
+
console.error(err.message);
|
|
687
|
+
console.log('\n⚠️ Fix step definitions before proceeding');
|
|
688
|
+
console.log('Common issues:');
|
|
689
|
+
console.log(' • Missing step definition for a Given/When/Then');
|
|
690
|
+
console.log(' • Syntax error in step definition');
|
|
691
|
+
console.log(' • Import/require error');
|
|
692
|
+
return; // Don't proceed
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
### Speed-Mode Phase
|
|
699
|
+
|
|
700
|
+
**Goal**: Make happy path work, iterate fast.
|
|
701
|
+
|
|
702
|
+
```
|
|
703
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
704
|
+
│ Tests Written: │
|
|
705
|
+
│ (inherited from feature-planning) │
|
|
706
|
+
│ │
|
|
707
|
+
│ Tests Run During Implementation: │
|
|
708
|
+
│ 🔄 BDD happy path for current feature │
|
|
709
|
+
│ ⏱️ After each code change (~30s) │
|
|
710
|
+
│ 🔄 Iterate until passing │
|
|
711
|
+
│ │
|
|
712
|
+
│ Tests Run Before Chore Complete: │
|
|
713
|
+
│ ✅ Full feature BDD suite (happy path) │
|
|
714
|
+
│ ⏱️ ~60s │
|
|
715
|
+
│ │
|
|
716
|
+
│ Git Hooks: │
|
|
717
|
+
│ pre-commit: Fast focused tests (~15s) │
|
|
718
|
+
│ pre-push: Full suite (before sharing) │
|
|
719
|
+
│ │
|
|
720
|
+
│ Quality Gate: │
|
|
721
|
+
│ ✅ Happy path scenario passes │
|
|
722
|
+
│ ✅ Feature works end-to-end (no error handling yet) │
|
|
723
|
+
└─────────────────────────────────────────────────────────────┘
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
**Skill integration:**
|
|
727
|
+
```javascript
|
|
728
|
+
// Inside speed-mode implementation loop
|
|
729
|
+
let iteration = 0;
|
|
730
|
+
const MAX_ITERATIONS = 10;
|
|
731
|
+
|
|
732
|
+
while (iteration < MAX_ITERATIONS) {
|
|
733
|
+
iteration++;
|
|
734
|
+
|
|
735
|
+
// 1. Make code changes
|
|
736
|
+
console.log(`✍️ Implementing (iteration ${iteration})...`);
|
|
737
|
+
// ... use Edit/Write tools ...
|
|
738
|
+
|
|
739
|
+
// 2. Run BDD tests for THIS feature only
|
|
740
|
+
console.log('🧪 Testing happy path...');
|
|
741
|
+
|
|
742
|
+
try {
|
|
743
|
+
const result = execSync(
|
|
744
|
+
`npx cucumber-js ${featureFile}`,
|
|
745
|
+
{ encoding: 'utf-8', timeout: 30000 }
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
// Check if happy path passed
|
|
749
|
+
if (result.includes('1 scenario (1 passed)')) {
|
|
750
|
+
console.log('✅ Happy path scenario passes!');
|
|
751
|
+
break;
|
|
752
|
+
} else {
|
|
753
|
+
console.log('❌ Scenario still failing, iterating...');
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
} catch (err) {
|
|
757
|
+
console.log('❌ Tests failed:', err.message);
|
|
758
|
+
// Analyze and iterate
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
### Stable-Mode Phase
|
|
766
|
+
|
|
767
|
+
**Goal**: Add comprehensive robustness, ensure no regressions.
|
|
768
|
+
|
|
769
|
+
```
|
|
770
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
771
|
+
│ Tests Written: │
|
|
772
|
+
│ ✅ BDD error handling scenarios │
|
|
773
|
+
│ ✅ BDD edge case scenarios │
|
|
774
|
+
│ ✅ Step definitions for above │
|
|
775
|
+
│ ✅ (Optional) Unit tests for error handling logic │
|
|
776
|
+
│ │
|
|
777
|
+
│ Tests Run During Implementation: │
|
|
778
|
+
│ 🔄 ALL BDD scenarios for feature │
|
|
779
|
+
│ 🔄 Regression check (happy path still works) │
|
|
780
|
+
│ ⏱️ After each code change (~60s) │
|
|
781
|
+
│ 🔄 Iterate with timeout protection │
|
|
782
|
+
│ │
|
|
783
|
+
│ Tests Run Before Chore Complete: │
|
|
784
|
+
│ ✅ Full feature BDD suite (all scenarios) │
|
|
785
|
+
│ ✅ All unit tests (if any) │
|
|
786
|
+
│ ⏱️ ~90s │
|
|
787
|
+
│ │
|
|
788
|
+
│ Git Hooks: │
|
|
789
|
+
│ pre-commit: Focused regression tests (~45s) │
|
|
790
|
+
│ pre-push: Full suite (comprehensive) │
|
|
791
|
+
│ │
|
|
792
|
+
│ Quality Gate: │
|
|
793
|
+
│ ✅ All BDD scenarios pass │
|
|
794
|
+
│ ✅ Error handling comprehensive │
|
|
795
|
+
│ ✅ Edge cases covered │
|
|
796
|
+
│ ✅ No regressions │
|
|
797
|
+
└─────────────────────────────────────────────────────────────┘
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Skill integration:**
|
|
801
|
+
```javascript
|
|
802
|
+
// Inside stable-mode implementation loop
|
|
803
|
+
const MAX_ITERATIONS = 10;
|
|
804
|
+
const TEST_TIMEOUT = 60000;
|
|
805
|
+
|
|
806
|
+
let iteration = 0;
|
|
807
|
+
let allPass = false;
|
|
808
|
+
|
|
809
|
+
while (!allPass && iteration < MAX_ITERATIONS) {
|
|
810
|
+
iteration++;
|
|
811
|
+
console.log(`\n🔄 Stable mode iteration ${iteration}/${MAX_ITERATIONS}`);
|
|
812
|
+
|
|
813
|
+
// 1. Add error handling
|
|
814
|
+
console.log('✍️ Adding error handling...');
|
|
815
|
+
// ... use Edit tool ...
|
|
816
|
+
|
|
817
|
+
// 2. Run ALL scenarios for this feature
|
|
818
|
+
console.log('🧪 Running all scenarios (happy + error + edge)...');
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
const result = execSync(
|
|
822
|
+
`npx cucumber-js ${featureFile}`,
|
|
823
|
+
{
|
|
824
|
+
encoding: 'utf-8',
|
|
825
|
+
timeout: TEST_TIMEOUT,
|
|
826
|
+
killSignal: 'SIGTERM'
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
|
|
830
|
+
// Check if ALL scenarios passed
|
|
831
|
+
const scenarioCount = result.match(/(\d+) scenarios? \((\d+) passed\)/);
|
|
832
|
+
if (scenarioCount && scenarioCount[1] === scenarioCount[2]) {
|
|
833
|
+
console.log('✅ All scenarios pass!');
|
|
834
|
+
|
|
835
|
+
// Also check no regressions in other features (smoke test)
|
|
836
|
+
console.log('🧪 Smoke testing other features...');
|
|
837
|
+
const smokeResult = execSync('npx cucumber-js --tags "not @wip"', {
|
|
838
|
+
encoding: 'utf-8',
|
|
839
|
+
timeout: 30000
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
if (!smokeResult.includes('failed')) {
|
|
843
|
+
console.log('✅ No regressions detected');
|
|
844
|
+
allPass = true;
|
|
845
|
+
} else {
|
|
846
|
+
console.log('⚠️ Regressions detected, adjusting...');
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
} else {
|
|
850
|
+
console.log('❌ Some scenarios failing, iterating...');
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
} catch (err) {
|
|
854
|
+
console.log('❌ Tests failed:', err.message);
|
|
855
|
+
// Analyze and iterate
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
---
|
|
861
|
+
|
|
862
|
+
### Production-Mode Phase
|
|
863
|
+
|
|
864
|
+
**Goal**: Harden for production with security/scale/compliance.
|
|
865
|
+
|
|
866
|
+
```
|
|
867
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
868
|
+
│ Tests Written: │
|
|
869
|
+
│ ✅ BDD production scenarios (@production tag) │
|
|
870
|
+
│ ✅ Security test scenarios │
|
|
871
|
+
│ ✅ Performance benchmark scenarios (optional) │
|
|
872
|
+
│ ✅ Step definitions for above │
|
|
873
|
+
│ │
|
|
874
|
+
│ Tests Run During Implementation: │
|
|
875
|
+
│ 🔄 Production scenarios only │
|
|
876
|
+
│ ⏱️ After each code change (~2min) │
|
|
877
|
+
│ 🔄 Iterate until passing │
|
|
878
|
+
│ │
|
|
879
|
+
│ Tests Run Before Chore Complete: │
|
|
880
|
+
│ ✅ ALL scenarios (happy + error + edge + production) │
|
|
881
|
+
│ ✅ Performance benchmarks (if defined) │
|
|
882
|
+
│ ✅ Full regression suite │
|
|
883
|
+
│ ⏱️ ~3-5min │
|
|
884
|
+
│ │
|
|
885
|
+
│ Git Hooks: │
|
|
886
|
+
│ pre-commit: Focused production tests (~90s) │
|
|
887
|
+
│ pre-push: Full comprehensive suite │
|
|
888
|
+
│ │
|
|
889
|
+
│ Quality Gate: │
|
|
890
|
+
│ ✅ All production scenarios pass │
|
|
891
|
+
│ ✅ Security requirements met │
|
|
892
|
+
│ ✅ Performance targets achieved │
|
|
893
|
+
│ ✅ Compliance validated │
|
|
894
|
+
└─────────────────────────────────────────────────────────────┘
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
**Skill integration:**
|
|
898
|
+
```javascript
|
|
899
|
+
// Inside production-mode implementation loop
|
|
900
|
+
const MAX_ITERATIONS = 10;
|
|
901
|
+
const PRODUCTION_TEST_TIMEOUT = 120000; // 2 minutes
|
|
902
|
+
|
|
903
|
+
let iteration = 0;
|
|
904
|
+
let productionPass = false;
|
|
905
|
+
|
|
906
|
+
while (!productionPass && iteration < MAX_ITERATIONS) {
|
|
907
|
+
iteration++;
|
|
908
|
+
|
|
909
|
+
// 1. Add production hardening
|
|
910
|
+
console.log('✍️ Adding production hardening...');
|
|
911
|
+
// ... security, rate limiting, monitoring, etc ...
|
|
912
|
+
|
|
913
|
+
// 2. Run production scenarios
|
|
914
|
+
console.log('🧪 Running production scenarios...');
|
|
915
|
+
|
|
916
|
+
try {
|
|
917
|
+
const result = execSync(
|
|
918
|
+
`npx cucumber-js --tags "@production" ${featureFile}`,
|
|
919
|
+
{
|
|
920
|
+
encoding: 'utf-8',
|
|
921
|
+
timeout: PRODUCTION_TEST_TIMEOUT
|
|
922
|
+
}
|
|
923
|
+
);
|
|
924
|
+
|
|
925
|
+
if (result.includes('passed')) {
|
|
926
|
+
console.log('✅ Production scenarios pass!');
|
|
927
|
+
|
|
928
|
+
// 3. Run full regression suite
|
|
929
|
+
console.log('🧪 Running full regression suite...');
|
|
930
|
+
const fullResult = execSync('npx cucumber-js', {
|
|
931
|
+
encoding: 'utf-8',
|
|
932
|
+
timeout: 180000 // 3 minutes
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
if (!fullResult.includes('failed')) {
|
|
936
|
+
console.log('✅ Full regression suite passes!');
|
|
937
|
+
productionPass = true;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
} catch (err) {
|
|
942
|
+
console.log('❌ Production tests failed, iterating...');
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
---
|
|
948
|
+
|
|
949
|
+
### Standalone Chore Phase
|
|
950
|
+
|
|
951
|
+
**Goal**: Test isolated functionality without breaking anything.
|
|
952
|
+
|
|
953
|
+
```
|
|
954
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
955
|
+
│ Tests Written: │
|
|
956
|
+
│ ✅ Unit tests for new functionality │
|
|
957
|
+
│ ✅ BDD scenarios if user-facing │
|
|
958
|
+
│ ✅ Safety patterns (hooks for cleanup) │
|
|
959
|
+
│ │
|
|
960
|
+
│ Tests Run During Implementation: │
|
|
961
|
+
│ 🔄 Tests for THIS chore only │
|
|
962
|
+
│ ⏱️ Fast iteration (< 30s) │
|
|
963
|
+
│ 🔄 TDD red-green-refactor cycle │
|
|
964
|
+
│ │
|
|
965
|
+
│ Tests Run Before Chore Complete: │
|
|
966
|
+
│ ✅ Tests for chore scope │
|
|
967
|
+
│ ✅ Smoke test (ensure no breakage) │
|
|
968
|
+
│ ⏱️ ~45s │
|
|
969
|
+
│ │
|
|
970
|
+
│ Git Hooks: │
|
|
971
|
+
│ pre-commit: Tests for changed files (~20s) │
|
|
972
|
+
│ pre-push: Full suite (ensure no regressions) │
|
|
973
|
+
│ │
|
|
974
|
+
│ Quality Gate: │
|
|
975
|
+
│ ✅ New functionality works │
|
|
976
|
+
│ ✅ No regressions in existing features │
|
|
977
|
+
│ ✅ Safety patterns prevent corruption │
|
|
978
|
+
└─────────────────────────────────────────────────────────────┘
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
**Implementation approach:**
|
|
982
|
+
```javascript
|
|
983
|
+
// Standalone chore TDD cycle
|
|
984
|
+
// 1. Write test first (RED)
|
|
985
|
+
describe('new utility function', () => {
|
|
986
|
+
it('handles the new case', () => {
|
|
987
|
+
expect(newFunction('input')).toBe('expected');
|
|
988
|
+
});
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// Run: npm run test:unit:watch (watch mode for fast feedback)
|
|
992
|
+
|
|
993
|
+
// 2. Implement (GREEN)
|
|
994
|
+
function newFunction(input) {
|
|
995
|
+
return 'expected';
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// 3. Refactor and ensure tests still pass
|
|
999
|
+
|
|
1000
|
+
// Before commit:
|
|
1001
|
+
// - Run tests for this file
|
|
1002
|
+
// - Smoke test other functionality
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
---
|
|
1006
|
+
|
|
1007
|
+
## Test Execution Speed Targets
|
|
1008
|
+
|
|
1009
|
+
### Speed is Critical for TDD
|
|
1010
|
+
|
|
1011
|
+
| Test Type | Target Speed | Max Acceptable | Notes |
|
|
1012
|
+
|-----------|-------------|----------------|-------|
|
|
1013
|
+
| Dry-run validation | < 5s | 10s | Feature-planning phase |
|
|
1014
|
+
| Unit test (single file) | < 1s | 5s | Fast feedback loop |
|
|
1015
|
+
| Unit test (all) | < 30s | 60s | Pre-push acceptable |
|
|
1016
|
+
| BDD single scenario | < 10s | 30s | Integration overhead |
|
|
1017
|
+
| BDD single feature | < 30s | 60s | Multiple scenarios |
|
|
1018
|
+
| BDD all features | < 2min | 5min | Full regression |
|
|
1019
|
+
| Pre-commit hook | < 30s | 90s | Must not kill velocity |
|
|
1020
|
+
| Pre-push hook | < 3min | 5min | Comprehensive acceptable |
|
|
1021
|
+
|
|
1022
|
+
**Why speed matters:**
|
|
1023
|
+
- Slow tests = developers skip tests
|
|
1024
|
+
- Fast feedback = more frequent testing
|
|
1025
|
+
- TDD requires fast red-green-refactor cycle
|
|
1026
|
+
|
|
1027
|
+
**How to keep tests fast:**
|
|
1028
|
+
- ✅ Mock external dependencies
|
|
1029
|
+
- ✅ Use in-memory databases for tests
|
|
1030
|
+
- ✅ Parallelize test execution
|
|
1031
|
+
- ✅ Smart test selection (changed files only)
|
|
1032
|
+
- ✅ Separate fast unit tests from slow integration tests
|
|
1033
|
+
|
|
1034
|
+
---
|
|
1035
|
+
|
|
1036
|
+
## Git Hook Implementation Guide
|
|
1037
|
+
|
|
1038
|
+
### Step 1: Install Smart Pre-Commit Hook
|
|
1039
|
+
|
|
1040
|
+
**Create:** `.git/hooks/pre-commit`
|
|
1041
|
+
|
|
1042
|
+
```bash
|
|
1043
|
+
#!/usr/bin/env node
|
|
1044
|
+
|
|
1045
|
+
// [Full smart pre-commit hook code from earlier]
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
**Make executable:**
|
|
1049
|
+
```bash
|
|
1050
|
+
chmod +x .git/hooks/pre-commit
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
### Step 2: Install Smart Pre-Push Hook
|
|
1056
|
+
|
|
1057
|
+
**Create:** `.git/hooks/pre-push`
|
|
1058
|
+
|
|
1059
|
+
```bash
|
|
1060
|
+
#!/usr/bin/env node
|
|
1061
|
+
|
|
1062
|
+
// [Full pre-push hook code from earlier]
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
**Make executable:**
|
|
1066
|
+
```bash
|
|
1067
|
+
chmod +x .git/hooks/pre-push
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
---
|
|
1071
|
+
|
|
1072
|
+
### Step 3: Keep Existing Hooks
|
|
1073
|
+
|
|
1074
|
+
**Keep:** `.git/hooks/post-commit` ✅
|
|
1075
|
+
**Keep:** `.git/hooks/post-merge` ✅
|
|
1076
|
+
|
|
1077
|
+
These are perfect as-is for workflow tracking.
|
|
1078
|
+
|
|
1079
|
+
---
|
|
1080
|
+
|
|
1081
|
+
### Step 4: Update Skills to Reference Hooks
|
|
1082
|
+
|
|
1083
|
+
**In feature-planning skill:**
|
|
1084
|
+
```javascript
|
|
1085
|
+
console.log(`
|
|
1086
|
+
✅ BDD infrastructure validated
|
|
1087
|
+
|
|
1088
|
+
ℹ️ Testing Strategy:
|
|
1089
|
+
• Feature-planning: Infrastructure validated ✅ (you are here)
|
|
1090
|
+
• Speed-mode: Happy path tests (fast iteration)
|
|
1091
|
+
• Stable-mode: Comprehensive error/edge tests
|
|
1092
|
+
• Production-mode: Security/scale/compliance tests
|
|
1093
|
+
|
|
1094
|
+
Git hooks will help:
|
|
1095
|
+
• pre-commit: Fast focused tests during development
|
|
1096
|
+
• pre-push: Full suite before sharing with team
|
|
1097
|
+
`);
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
---
|
|
1101
|
+
|
|
1102
|
+
## Test Organization Best Practices
|
|
1103
|
+
|
|
1104
|
+
### File Structure
|
|
1105
|
+
|
|
1106
|
+
```
|
|
1107
|
+
jettypod-source/
|
|
1108
|
+
├── lib/
|
|
1109
|
+
│ ├── merge-lock.js ← Implementation
|
|
1110
|
+
│ ├── merge-lock.test.js ← Unit tests
|
|
1111
|
+
│ ├── validators.js
|
|
1112
|
+
│ └── validators.test.js
|
|
1113
|
+
│
|
|
1114
|
+
├── features/
|
|
1115
|
+
│ ├── merge-lock.feature ← BDD scenarios
|
|
1116
|
+
│ ├── git-hooks.feature
|
|
1117
|
+
│ │
|
|
1118
|
+
│ ├── step_definitions/
|
|
1119
|
+
│ │ ├── merge-lock.steps.js ← Step implementations
|
|
1120
|
+
│ │ └── git-hooks.steps.js
|
|
1121
|
+
│ │
|
|
1122
|
+
│ └── support/
|
|
1123
|
+
│ ├── hooks.js ← Before/After cleanup
|
|
1124
|
+
│ └── world.js ← Shared context
|
|
1125
|
+
│
|
|
1126
|
+
├── scripts/
|
|
1127
|
+
│ └── test-cleanup.js ← Post-test cleanup
|
|
1128
|
+
│
|
|
1129
|
+
├── .git/hooks/
|
|
1130
|
+
│ ├── pre-commit ← Smart fast hook
|
|
1131
|
+
│ ├── pre-push ← Comprehensive gate
|
|
1132
|
+
│ ├── post-commit ← Status tracking
|
|
1133
|
+
│ └── post-merge ← Mark done
|
|
1134
|
+
│
|
|
1135
|
+
└── package.json
|
|
1136
|
+
└── scripts:
|
|
1137
|
+
├── test ← Run all tests
|
|
1138
|
+
├── test:unit ← Unit tests only
|
|
1139
|
+
├── test:bdd ← BDD tests only
|
|
1140
|
+
├── test:unit:watch ← TDD watch mode
|
|
1141
|
+
└── test:cleanup ← Clean artifacts
|
|
1142
|
+
```
|
|
1143
|
+
|
|
1144
|
+
---
|
|
1145
|
+
|
|
1146
|
+
### Naming Conventions
|
|
1147
|
+
|
|
1148
|
+
**Unit Tests:**
|
|
1149
|
+
- `[module].test.js` - matches implementation file
|
|
1150
|
+
- Example: `merge-lock.js` → `merge-lock.test.js`
|
|
1151
|
+
|
|
1152
|
+
**BDD Features:**
|
|
1153
|
+
- `[feature-slug].feature` - Gherkin scenarios
|
|
1154
|
+
- Example: `merge-lock.feature`
|
|
1155
|
+
|
|
1156
|
+
**Step Definitions:**
|
|
1157
|
+
- `[feature-slug].steps.js` - implements steps
|
|
1158
|
+
- Example: `merge-lock.steps.js`
|
|
1159
|
+
|
|
1160
|
+
**Test Artifacts:**
|
|
1161
|
+
- Prefix with `test_` or `temp_` for easy cleanup
|
|
1162
|
+
- Example: `test_work.db`, `temp_config.json`
|
|
1163
|
+
|
|
1164
|
+
---
|
|
1165
|
+
|
|
1166
|
+
## Recommended Package.json Scripts
|
|
1167
|
+
|
|
1168
|
+
```json
|
|
1169
|
+
{
|
|
1170
|
+
"scripts": {
|
|
1171
|
+
// Main test command - runs everything
|
|
1172
|
+
"test": "npm run test:unit && npm run test:bdd && npm run test:cleanup",
|
|
1173
|
+
|
|
1174
|
+
// Unit tests
|
|
1175
|
+
"test:unit": "NODE_ENV=test jest",
|
|
1176
|
+
"test:unit:watch": "NODE_ENV=test jest --watch",
|
|
1177
|
+
"test:unit:coverage": "NODE_ENV=test jest --coverage",
|
|
1178
|
+
|
|
1179
|
+
// BDD tests
|
|
1180
|
+
"test:bdd": "NODE_ENV=test cucumber-js",
|
|
1181
|
+
"test:bdd:wip": "NODE_ENV=test cucumber-js --tags @wip",
|
|
1182
|
+
"test:bdd:production": "NODE_ENV=test cucumber-js --tags @production",
|
|
1183
|
+
|
|
1184
|
+
// Focused testing (for pre-commit)
|
|
1185
|
+
"test:focused": "NODE_ENV=test jest --onlyChanged && cucumber-js --tags @wip",
|
|
1186
|
+
|
|
1187
|
+
// Cleanup
|
|
1188
|
+
"test:cleanup": "node scripts/test-cleanup.js",
|
|
1189
|
+
|
|
1190
|
+
// Dry-run validation (for feature-planning)
|
|
1191
|
+
"test:validate": "cucumber-js --dry-run",
|
|
1192
|
+
|
|
1193
|
+
// Pre-push simulation (run locally)
|
|
1194
|
+
"test:pre-push": "npm test"
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
```
|
|
1198
|
+
|
|
1199
|
+
---
|
|
1200
|
+
|
|
1201
|
+
## Integration with CI/CD (Future)
|
|
1202
|
+
|
|
1203
|
+
### GitHub Actions Example
|
|
1204
|
+
|
|
1205
|
+
```yaml
|
|
1206
|
+
# .github/workflows/test.yml
|
|
1207
|
+
name: Test Suite
|
|
1208
|
+
|
|
1209
|
+
on:
|
|
1210
|
+
push:
|
|
1211
|
+
branches: [ main ]
|
|
1212
|
+
pull_request:
|
|
1213
|
+
branches: [ main ]
|
|
1214
|
+
|
|
1215
|
+
jobs:
|
|
1216
|
+
test:
|
|
1217
|
+
runs-on: ubuntu-latest
|
|
1218
|
+
|
|
1219
|
+
steps:
|
|
1220
|
+
- uses: actions/checkout@v2
|
|
1221
|
+
|
|
1222
|
+
- name: Setup Node.js
|
|
1223
|
+
uses: actions/setup-node@v2
|
|
1224
|
+
with:
|
|
1225
|
+
node-version: '18'
|
|
1226
|
+
|
|
1227
|
+
- name: Install dependencies
|
|
1228
|
+
run: npm ci
|
|
1229
|
+
|
|
1230
|
+
- name: Run unit tests
|
|
1231
|
+
run: npm run test:unit
|
|
1232
|
+
|
|
1233
|
+
- name: Run BDD tests
|
|
1234
|
+
run: npm run test:bdd
|
|
1235
|
+
|
|
1236
|
+
- name: Upload coverage
|
|
1237
|
+
uses: codecov/codecov-action@v2
|
|
1238
|
+
if: always()
|
|
1239
|
+
```
|
|
1240
|
+
|
|
1241
|
+
**Why CI/CD is the ultimate quality gate:**
|
|
1242
|
+
- Clean environment (no local state)
|
|
1243
|
+
- Enforced on all PRs
|
|
1244
|
+
- Can't be bypassed
|
|
1245
|
+
- Tracks test history
|
|
1246
|
+
- Integrates with deployment
|
|
1247
|
+
|
|
1248
|
+
---
|
|
1249
|
+
|
|
1250
|
+
## Summary: Test Execution Timeline
|
|
1251
|
+
|
|
1252
|
+
### Feature Workflow Timeline
|
|
1253
|
+
|
|
1254
|
+
```
|
|
1255
|
+
Feature-Planning:
|
|
1256
|
+
├─ Write scenarios + step definitions
|
|
1257
|
+
├─ 🧪 Dry-run validation (~5s)
|
|
1258
|
+
└─ ✅ Test infrastructure validated
|
|
1259
|
+
|
|
1260
|
+
Speed-Mode (per chore):
|
|
1261
|
+
├─ Implement code
|
|
1262
|
+
├─ 🧪 Test happy path (~30s per iteration)
|
|
1263
|
+
├─ 🔄 Iterate until passing
|
|
1264
|
+
├─ 📝 Commit (pre-commit hook: ~15s)
|
|
1265
|
+
└─ ✅ Happy path works
|
|
1266
|
+
|
|
1267
|
+
Stable-Mode (per chore):
|
|
1268
|
+
├─ Add error/edge scenarios
|
|
1269
|
+
├─ Add error handling
|
|
1270
|
+
├─ 🧪 Test all scenarios (~60s per iteration)
|
|
1271
|
+
├─ 🔄 Iterate until passing
|
|
1272
|
+
├─ 📝 Commit (pre-commit hook: ~45s)
|
|
1273
|
+
└─ ✅ Comprehensive coverage
|
|
1274
|
+
|
|
1275
|
+
Production-Mode (per chore):
|
|
1276
|
+
├─ Add production scenarios
|
|
1277
|
+
├─ Add security/scale hardening
|
|
1278
|
+
├─ 🧪 Test production scenarios (~2min per iteration)
|
|
1279
|
+
├─ 🔄 Iterate until passing
|
|
1280
|
+
├─ 📝 Commit (pre-commit hook: ~90s)
|
|
1281
|
+
└─ ✅ Production-ready
|
|
1282
|
+
|
|
1283
|
+
Before Push (any phase):
|
|
1284
|
+
├─ 🚀 Pre-push hook runs
|
|
1285
|
+
├─ 🧪 Full test suite (~3min)
|
|
1286
|
+
└─ ✅ Quality gate passed
|
|
1287
|
+
|
|
1288
|
+
After Merge to Main:
|
|
1289
|
+
├─ 🪝 Post-merge hook
|
|
1290
|
+
├─ 📋 Mark work done
|
|
1291
|
+
└─ ✅ Workflow complete
|
|
1292
|
+
```
|
|
1293
|
+
|
|
1294
|
+
---
|
|
1295
|
+
|
|
1296
|
+
## Recommendations Summary
|
|
1297
|
+
|
|
1298
|
+
### Immediate Actions
|
|
1299
|
+
|
|
1300
|
+
1. **✅ Enable smart pre-commit hook**
|
|
1301
|
+
- Context-aware testing
|
|
1302
|
+
- Fast feedback (15-90s depending on mode)
|
|
1303
|
+
- Bypassable for rapid iteration
|
|
1304
|
+
|
|
1305
|
+
2. **✅ Add pre-push hook**
|
|
1306
|
+
- Comprehensive quality gate
|
|
1307
|
+
- Full test suite before sharing
|
|
1308
|
+
- Harder to bypass
|
|
1309
|
+
|
|
1310
|
+
3. **✅ Add dry-run validation to feature-planning**
|
|
1311
|
+
- 5-second syntax check
|
|
1312
|
+
- Catches broken tests immediately
|
|
1313
|
+
- Prevents wasted time in speed-mode
|
|
1314
|
+
|
|
1315
|
+
4. **✅ Integrate test safety patterns**
|
|
1316
|
+
- Reference ai-test-writing-requirements.md in skills
|
|
1317
|
+
- Ensure all BDD tests use cleanup hooks
|
|
1318
|
+
- Prevent test corruption
|
|
1319
|
+
|
|
1320
|
+
### Future Enhancements
|
|
1321
|
+
|
|
1322
|
+
5. **⚠️ Add CI/CD pipeline**
|
|
1323
|
+
- GitHub Actions for automated testing
|
|
1324
|
+
- Test on every PR
|
|
1325
|
+
- Ultimate quality gate
|
|
1326
|
+
|
|
1327
|
+
6. **⚠️ Add test coverage tracking**
|
|
1328
|
+
- Jest coverage reports
|
|
1329
|
+
- Track coverage trends
|
|
1330
|
+
- Identify untested code
|
|
1331
|
+
|
|
1332
|
+
7. **⚠️ Add performance benchmarking**
|
|
1333
|
+
- Track test execution time
|
|
1334
|
+
- Identify slow tests
|
|
1335
|
+
- Optimize test suite
|
|
1336
|
+
|
|
1337
|
+
---
|
|
1338
|
+
|
|
1339
|
+
## Conclusion
|
|
1340
|
+
|
|
1341
|
+
### The Problem You're Solving
|
|
1342
|
+
|
|
1343
|
+
**Old approach (disabled pre-commit):**
|
|
1344
|
+
- ❌ Full test suite on every commit → kills velocity
|
|
1345
|
+
- ❌ Developers use --no-verify to bypass
|
|
1346
|
+
- ❌ No differentiation between rapid iteration vs sharing code
|
|
1347
|
+
|
|
1348
|
+
**New approach (smart hooks):**
|
|
1349
|
+
- ✅ Fast focused tests during development
|
|
1350
|
+
- ✅ Comprehensive tests before sharing
|
|
1351
|
+
- ✅ Context-aware (speed/stable/production modes)
|
|
1352
|
+
- ✅ Appropriate at each workflow phase
|
|
1353
|
+
|
|
1354
|
+
### Key Principles
|
|
1355
|
+
|
|
1356
|
+
1. **Test at the right time** - Not all tests need to run always
|
|
1357
|
+
2. **Test the right things** - Focus on what changed
|
|
1358
|
+
3. **Test fast enough** - Speed enables frequency
|
|
1359
|
+
4. **Test comprehensively when it matters** - Before sharing/merging
|
|
1360
|
+
5. **Make tests helpful, not annoying** - Good UX increases adoption
|
|
1361
|
+
|
|
1362
|
+
### Final Recommendation
|
|
1363
|
+
|
|
1364
|
+
**Your pre-commit hook being disabled was a symptom of poor test execution strategy, not a problem with testing itself.**
|
|
1365
|
+
|
|
1366
|
+
The solution isn't "no pre-commit hook" but rather "smart pre-commit hook that adapts to context and runs fast enough to be helpful."
|
|
1367
|
+
|
|
1368
|
+
Implement:
|
|
1369
|
+
- Smart pre-commit (fast, focused, bypassable)
|
|
1370
|
+
- Smart pre-push (comprehensive, quality gate)
|
|
1371
|
+
- Dry-run validation in feature-planning
|
|
1372
|
+
- Context-aware test execution in all skills
|
|
1373
|
+
|
|
1374
|
+
This gives you maximum velocity during development while maintaining strong quality gates before sharing code.
|