groundswell 0.0.2 → 1.0.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/LICENSE +21 -0
- package/README.md +26 -9
- package/dist/cache/cache-key.d.ts +86 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +204 -0
- package/dist/cache/cache-key.js.map +1 -0
- package/dist/cache/cache.d.ts +104 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +179 -0
- package/dist/cache/cache.js.map +1 -0
- package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/agent.d.ts +203 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +833 -0
- package/dist/core/agent.js.map +1 -0
- package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +80 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-tree.d.ts +72 -0
- package/dist/core/event-tree.d.ts.map +1 -0
- package/dist/core/event-tree.js +211 -0
- package/dist/core/event-tree.js.map +1 -0
- package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +110 -0
- package/dist/core/factory.js.map +1 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +50 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +91 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp-handler.d.ts +127 -0
- package/dist/core/mcp-handler.d.ts.map +1 -0
- package/dist/core/mcp-handler.js +323 -0
- package/dist/core/mcp-handler.js.map +1 -0
- package/dist/core/prompt.d.ts +80 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +120 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/workflow-context.d.ts +61 -0
- package/dist/core/workflow-context.d.ts.map +1 -0
- package/dist/core/workflow-context.js +358 -0
- package/dist/core/workflow-context.js.map +1 -0
- package/dist/core/workflow.d.ts +543 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +986 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/debugger/event-replayer.d.ts +422 -0
- package/dist/debugger/event-replayer.d.ts.map +1 -0
- package/dist/debugger/event-replayer.js +639 -0
- package/dist/debugger/event-replayer.js.map +1 -0
- package/dist/debugger/index.d.ts +2 -0
- package/dist/debugger/index.d.ts.map +1 -0
- package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
- package/dist/debugger/index.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +240 -0
- package/dist/debugger/tree-debugger.d.ts.map +1 -0
- package/dist/debugger/tree-debugger.js +620 -0
- package/dist/debugger/tree-debugger.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/observed-state.d.ts +32 -0
- package/dist/decorators/observed-state.d.ts.map +1 -0
- package/dist/decorators/observed-state.js +79 -0
- package/dist/decorators/observed-state.js.map +1 -0
- package/dist/decorators/step.d.ts +15 -0
- package/dist/decorators/step.d.ts.map +1 -0
- package/dist/decorators/step.js +192 -0
- package/dist/decorators/step.js.map +1 -0
- package/dist/decorators/task.d.ts +50 -0
- package/dist/decorators/task.d.ts.map +1 -0
- package/dist/decorators/task.js +118 -0
- package/dist/decorators/task.js.map +1 -0
- package/dist/examples/index.d.ts +3 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/{src/examples/index.ts → dist/examples/index.js} +1 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/tdd-orchestrator.d.ts +15 -0
- package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
- package/dist/examples/tdd-orchestrator.js +121 -0
- package/dist/examples/tdd-orchestrator.js.map +1 -0
- package/dist/examples/test-cycle-workflow.d.ts +14 -0
- package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
- package/dist/examples/test-cycle-workflow.js +116 -0
- package/dist/examples/test-cycle-workflow.js.map +1 -0
- package/dist/harnesses/claude-code-harness.d.ts +391 -0
- package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
- package/dist/harnesses/claude-code-harness.js +1076 -0
- package/dist/harnesses/claude-code-harness.js.map +1 -0
- package/dist/harnesses/harness-registry.d.ts +440 -0
- package/dist/harnesses/harness-registry.d.ts.map +1 -0
- package/dist/harnesses/harness-registry.js +543 -0
- package/dist/harnesses/harness-registry.js.map +1 -0
- package/dist/harnesses/index.d.ts +12 -0
- package/dist/harnesses/index.d.ts.map +1 -0
- package/dist/harnesses/index.js +11 -0
- package/dist/harnesses/index.js.map +1 -0
- package/dist/harnesses/pi-harness.d.ts +219 -0
- package/dist/harnesses/pi-harness.d.ts.map +1 -0
- package/dist/harnesses/pi-harness.js +676 -0
- package/dist/harnesses/pi-harness.js.map +1 -0
- package/dist/harnesses/pi-schema-converter.d.ts +24 -0
- package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
- package/dist/harnesses/pi-schema-converter.js +81 -0
- package/dist/harnesses/pi-schema-converter.js.map +1 -0
- package/dist/harnesses/register-defaults.d.ts +24 -0
- package/dist/harnesses/register-defaults.d.ts.map +1 -0
- package/dist/harnesses/register-defaults.js +40 -0
- package/dist/harnesses/register-defaults.js.map +1 -0
- package/dist/harnesses/session-store.d.ts +201 -0
- package/dist/harnesses/session-store.d.ts.map +1 -0
- package/dist/harnesses/session-store.js +254 -0
- package/dist/harnesses/session-store.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/reflection/index.d.ts +5 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/reflection.d.ts +84 -0
- package/dist/reflection/reflection.d.ts.map +1 -0
- package/dist/reflection/reflection.js +344 -0
- package/dist/reflection/reflection.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/introspection.d.ts +165 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js +324 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/types/agent.d.ts +1317 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +423 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/decorators.d.ts +40 -0
- package/dist/types/decorators.d.ts.map +1 -0
- package/dist/types/decorators.js +2 -0
- package/dist/types/decorators.js.map +1 -0
- package/dist/types/error-strategy.d.ts +13 -0
- package/dist/types/error-strategy.d.ts.map +1 -0
- package/dist/types/error-strategy.js +2 -0
- package/dist/types/error-strategy.js.map +1 -0
- package/dist/types/error.d.ts +20 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +2 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/events.d.ts +113 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/harnesses.d.ts +474 -0
- package/dist/types/harnesses.d.ts.map +1 -0
- package/dist/types/harnesses.js +2 -0
- package/dist/types/harnesses.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logging.d.ts +24 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/observer.d.ts +18 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +2 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/prompt.d.ts +31 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +6 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/providers.d.ts +691 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/providers.js +14 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/types/reflection.d.ts +96 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +24 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/restart.d.ts +132 -0
- package/dist/types/restart.d.ts.map +1 -0
- package/dist/types/restart.js +2 -0
- package/dist/types/restart.js.map +1 -0
- package/dist/types/sdk-primitives.d.ts +118 -0
- package/dist/types/sdk-primitives.d.ts.map +1 -0
- package/dist/types/sdk-primitives.js +6 -0
- package/dist/types/sdk-primitives.js.map +1 -0
- package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/types/streaming.d.ts +194 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/types/streaming.js +67 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/workflow-context.d.ts +275 -0
- package/dist/types/workflow-context.d.ts.map +1 -0
- package/dist/types/workflow-context.js +8 -0
- package/dist/types/workflow-context.js.map +1 -0
- package/dist/types/workflow.d.ts +30 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/agent-validation.d.ts +88 -0
- package/dist/utils/agent-validation.d.ts.map +1 -0
- package/dist/utils/agent-validation.js +87 -0
- package/dist/utils/agent-validation.js.map +1 -0
- package/dist/utils/delay.d.ts +7 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/harness-config.d.ts +180 -0
- package/dist/utils/harness-config.d.ts.map +1 -0
- package/dist/utils/harness-config.js +311 -0
- package/dist/utils/harness-config.js.map +1 -0
- package/dist/utils/id.d.ts +6 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/model-spec.d.ts +110 -0
- package/dist/utils/model-spec.d.ts.map +1 -0
- package/dist/utils/model-spec.js +149 -0
- package/dist/utils/model-spec.js.map +1 -0
- package/dist/utils/observable.d.ts +54 -0
- package/dist/utils/observable.d.ts.map +1 -0
- package/dist/utils/observable.js +82 -0
- package/dist/utils/observable.js.map +1 -0
- package/dist/utils/provider-config.d.ts +10 -0
- package/dist/utils/provider-config.d.ts.map +1 -0
- package/dist/utils/provider-config.js +10 -0
- package/dist/utils/provider-config.js.map +1 -0
- package/dist/utils/restart-analysis.d.ts +202 -0
- package/dist/utils/restart-analysis.d.ts.map +1 -0
- package/dist/utils/restart-analysis.js +426 -0
- package/dist/utils/restart-analysis.js.map +1 -0
- package/dist/utils/session-serialization.d.ts +118 -0
- package/dist/utils/session-serialization.d.ts.map +1 -0
- package/dist/utils/session-serialization.js +217 -0
- package/dist/utils/session-serialization.js.map +1 -0
- package/dist/utils/workflow-error-utils.d.ts +22 -0
- package/dist/utils/workflow-error-utils.d.ts.map +1 -0
- package/dist/utils/workflow-error-utils.js +45 -0
- package/dist/utils/workflow-error-utils.js.map +1 -0
- package/package.json +34 -5
- package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
- package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
- package/.claude/commands/task-breakdown.md +0 -94
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -101
- package/CHANGELOG.md +0 -188
- package/PRD.md +0 -543
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/002-agent-prompt.md +0 -390
- package/PRPs/PRDs/003-agent-prompt.md +0 -943
- package/PRPs/PRDs/004-agent-prompt.md +0 -1136
- package/PRPs/PRDs/tasks-001.json +0 -492
- package/PRPs/README.md +0 -83
- package/PRPs/templates/prp_base.md +0 -222
- package/docs/agent.md +0 -422
- package/docs/prompt.md +0 -419
- package/docs/workflow.md +0 -600
- package/examples/README.md +0 -258
- package/examples/examples/01-basic-workflow.ts +0 -100
- package/examples/examples/02-decorator-options.ts +0 -217
- package/examples/examples/03-parent-child.ts +0 -241
- package/examples/examples/04-observers-debugger.ts +0 -340
- package/examples/examples/05-error-handling.ts +0 -387
- package/examples/examples/06-concurrent-tasks.ts +0 -352
- package/examples/examples/07-agent-loops.ts +0 -432
- package/examples/examples/08-sdk-features.ts +0 -667
- package/examples/examples/09-reflection.ts +0 -573
- package/examples/examples/10-introspection.ts +0 -550
- package/examples/examples/11-reparenting-workflows.ts +0 -269
- package/examples/index.ts +0 -147
- package/examples/utils/helpers.ts +0 -57
- package/package-lock.json +0 -2398
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
- package/plan/001_d3bb02af4886/backlog.json +0 -867
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
- package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
- package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
- package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
- package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
- package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
- package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
- package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
- package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
- package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
- package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
- package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
- package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
- package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
- package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
- package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
- package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
- package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
- package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
- package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
- package/src/__tests__/adversarial/edge-case.test.ts +0 -703
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
- package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
- package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
- package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
- package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
- package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
- package/src/__tests__/helpers/index.ts +0 -18
- package/src/__tests__/helpers/tree-verification.ts +0 -257
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
- package/src/__tests__/integration/observer-logging.test.ts +0 -643
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
- package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
- package/src/__tests__/unit/agent.test.ts +0 -169
- package/src/__tests__/unit/cache-key.test.ts +0 -182
- package/src/__tests__/unit/cache.test.ts +0 -172
- package/src/__tests__/unit/context.test.ts +0 -217
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/logger.test.ts +0 -293
- package/src/__tests__/unit/observable.test.ts +0 -321
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
- package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
- package/src/__tests__/unit/workflow.test.ts +0 -357
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -593
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -112
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -351
- package/src/core/workflow.ts +0 -540
- package/src/debugger/tree-debugger.ts +0 -255
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -159
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -142
- package/src/reflection/reflection.ts +0 -407
- package/src/tools/index.ts +0 -36
- package/src/tools/introspection.ts +0 -464
- package/src/types/agent.ts +0 -90
- package/src/types/decorators.ts +0 -32
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -75
- package/src/types/index.ts +0 -55
- package/src/types/logging.ts +0 -24
- package/src/types/observer.ts +0 -18
- package/src/types/prompt.ts +0 -40
- package/src/types/reflection.ts +0 -117
- package/src/types/sdk-primitives.ts +0 -128
- package/src/types/workflow-context.ts +0 -163
- package/src/types/workflow.ts +0 -37
- package/src/utils/id.ts +0 -11
- package/src/utils/index.ts +0 -4
- package/src/utils/observable.ts +0 -106
- package/src/utils/workflow-error-utils.ts +0 -56
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md
DELETED
|
@@ -1,1323 +0,0 @@
|
|
|
1
|
-
# Test Maintenance Research: Best Practices After Bug Fixes
|
|
2
|
-
|
|
3
|
-
**Research Date:** 2026-01-12
|
|
4
|
-
**Context:** P1M4T1S2 - Test Maintenance and Bug Fix Validation
|
|
5
|
-
**Project:** Groundswell
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
1. [Vitest Best Practices](#vitest-best-practices)
|
|
9
|
-
2. [Test Maintenance After Bug Fixes](#test-maintenance-after-bug-fixes)
|
|
10
|
-
3. [Common Test Failure Patterns](#common-test-failure-patterns)
|
|
11
|
-
4. [Test Debugging Strategies](#test-debugging-strategies)
|
|
12
|
-
5. [Decision Framework: Test vs Implementation](#decision-framework)
|
|
13
|
-
6. [Resources and References](#resources-and-references)
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 1. Vitest Best Practices
|
|
18
|
-
|
|
19
|
-
### 1.1 Debugging Failing Tests
|
|
20
|
-
|
|
21
|
-
#### Running Specific Tests
|
|
22
|
-
```bash
|
|
23
|
-
# Run a specific test file
|
|
24
|
-
vitest run path/to/test.ts
|
|
25
|
-
|
|
26
|
-
# Run tests matching a pattern
|
|
27
|
-
vitest run --testNamePattern="should validate"
|
|
28
|
-
|
|
29
|
-
# Run only failed tests from last run
|
|
30
|
-
vitest run --reporter=verbose --bail 1
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
#### Using Vitest UI
|
|
34
|
-
```bash
|
|
35
|
-
# Start Vitest UI for interactive debugging
|
|
36
|
-
vitest --ui
|
|
37
|
-
|
|
38
|
-
# UI with coverage
|
|
39
|
-
vitest --ui --coverage
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
#### Debug Mode
|
|
43
|
-
```bash
|
|
44
|
-
# Run with Node.js debugger
|
|
45
|
-
vitest --inspect-brk --no-coverage
|
|
46
|
-
|
|
47
|
-
# Run single test in debug mode
|
|
48
|
-
vitest run --inspect-brk path/to/test.ts
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
#### Watch Mode for Iterative Debugging
|
|
52
|
-
```bash
|
|
53
|
-
# Watch mode with file filtering
|
|
54
|
-
vitest --watch path/to/test.ts
|
|
55
|
-
|
|
56
|
-
# Watch mode that runs only changed tests
|
|
57
|
-
vitest --watch --changed
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Best Practice:** Always use watch mode during development to get immediate feedback on test changes.
|
|
61
|
-
|
|
62
|
-
### 1.2 Understanding Test Failure Patterns
|
|
63
|
-
|
|
64
|
-
#### Common Failure Types
|
|
65
|
-
|
|
66
|
-
1. **Assertion Failures**
|
|
67
|
-
- Expected vs actual values don't match
|
|
68
|
-
- Usually indicates logic errors or incorrect expectations
|
|
69
|
-
- Example: `expect(actual).toBe(expected)`
|
|
70
|
-
|
|
71
|
-
2. **Timeout Errors**
|
|
72
|
-
- Test exceeds default timeout (5000ms)
|
|
73
|
-
- Often caused by:
|
|
74
|
-
- Infinite loops
|
|
75
|
-
- Unresolved promises
|
|
76
|
-
- Missing async/await
|
|
77
|
-
- Slow operations
|
|
78
|
-
|
|
79
|
-
3. **Mock/Vi Failures**
|
|
80
|
-
- Mock not called
|
|
81
|
-
- Wrong arguments passed to mock
|
|
82
|
-
- Mock not properly restored
|
|
83
|
-
|
|
84
|
-
4. **Type Errors**
|
|
85
|
-
- TypeScript compilation issues
|
|
86
|
-
- Type mismatches in tests
|
|
87
|
-
- Missing type definitions
|
|
88
|
-
|
|
89
|
-
### 1.3 Common Pitfalls and How to Avoid Them
|
|
90
|
-
|
|
91
|
-
#### Pitfall 1: Testing Implementation Details
|
|
92
|
-
**Problem:** Tests break when implementation changes without behavior change.
|
|
93
|
-
|
|
94
|
-
**Solution:**
|
|
95
|
-
```typescript
|
|
96
|
-
// ❌ Bad - Tests implementation
|
|
97
|
-
expect(userService.fetchUsers).toHaveBeenCalledWith('/api/users')
|
|
98
|
-
|
|
99
|
-
// ✅ Good - Tests behavior
|
|
100
|
-
await expect(userService.getUsers()).resolves.toEqual(expectedUsers)
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### Pitfall 2: Not Cleaning Up Mocks
|
|
104
|
-
**Problem:** Mocks leak between tests causing flaky behavior.
|
|
105
|
-
|
|
106
|
-
**Solution:**
|
|
107
|
-
```typescript
|
|
108
|
-
import { vi, beforeEach, afterEach } from 'vitest'
|
|
109
|
-
|
|
110
|
-
beforeEach(() => {
|
|
111
|
-
vi.clearAllMocks()
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
afterEach(() => {
|
|
115
|
-
vi.restoreAllMocks()
|
|
116
|
-
})
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
#### Pitfall 3: Improper Async Handling
|
|
120
|
-
**Problem:** Tests pass when they should fail or vice versa.
|
|
121
|
-
|
|
122
|
-
**Solution:**
|
|
123
|
-
```typescript
|
|
124
|
-
// ❌ Bad - Doesn't wait for promise
|
|
125
|
-
test('async test', () => {
|
|
126
|
-
fetchData().then(data => {
|
|
127
|
-
expect(data).toBe('value')
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
// ✅ Good - Proper async handling
|
|
132
|
-
test('async test', async () => {
|
|
133
|
-
const data = await fetchData()
|
|
134
|
-
expect(data).toBe('value')
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
// ✅ Also Good - Using promises
|
|
138
|
-
test('async test', () => {
|
|
139
|
-
return expect(fetchData()).resolves.toBe('value')
|
|
140
|
-
})
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
#### Pitfall 4: Brittle Assertions
|
|
144
|
-
**Problem:** Tests break due to unrelated changes.
|
|
145
|
-
|
|
146
|
-
**Solution:**
|
|
147
|
-
```typescript
|
|
148
|
-
// ❌ Bad - Too specific
|
|
149
|
-
expect(result).toEqual({
|
|
150
|
-
id: 1,
|
|
151
|
-
name: 'Test',
|
|
152
|
-
createdAt: '2025-01-12T10:00:00.000Z'
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
// ✅ Good - Focused on what matters
|
|
156
|
-
expect(result).toEqual({
|
|
157
|
-
id: expect.any(Number),
|
|
158
|
-
name: 'Test',
|
|
159
|
-
createdAt: expect.any(String)
|
|
160
|
-
})
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
#### Pitfall 5: Missing Error Cases
|
|
164
|
-
**Problem:** Only testing happy path.
|
|
165
|
-
|
|
166
|
-
**Solution:**
|
|
167
|
-
```typescript
|
|
168
|
-
test('handles errors gracefully', async () => {
|
|
169
|
-
// Mock error response
|
|
170
|
-
vi.spyOn(api, 'fetch').mockRejectedValue(new Error('Network error'))
|
|
171
|
-
|
|
172
|
-
await expect(service.getData()).rejects.toThrow('Network error')
|
|
173
|
-
})
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### 1.4 Test Organization Best Practices
|
|
177
|
-
|
|
178
|
-
#### File Structure
|
|
179
|
-
```
|
|
180
|
-
src/
|
|
181
|
-
components/
|
|
182
|
-
Button.tsx
|
|
183
|
-
Button.test.tsx # Co-located test
|
|
184
|
-
utils/
|
|
185
|
-
helpers.ts
|
|
186
|
-
helpers.test.ts
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
#### Test Structure
|
|
190
|
-
```typescript
|
|
191
|
-
describe('UserService', () => {
|
|
192
|
-
describe('getUsers', () => {
|
|
193
|
-
beforeEach(() => {
|
|
194
|
-
// Setup common to all tests in this describe block
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
afterEach(() => {
|
|
198
|
-
// Cleanup
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
it('should return users when API call succeeds', async () => {
|
|
202
|
-
// Arrange
|
|
203
|
-
const expectedUsers = [...]
|
|
204
|
-
mockApi.getUsers.mockResolvedValue(expectedUsers)
|
|
205
|
-
|
|
206
|
-
// Act
|
|
207
|
-
const result = await userService.getUsers()
|
|
208
|
-
|
|
209
|
-
// Assert
|
|
210
|
-
expect(result).toEqual(expectedUsers)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('should throw error when API call fails', async () => {
|
|
214
|
-
// Test error case
|
|
215
|
-
})
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## 2. Test Maintenance After Bug Fixes
|
|
223
|
-
|
|
224
|
-
### 2.1 Determining if Test Needs Updating vs Implementation Wrong
|
|
225
|
-
|
|
226
|
-
#### Decision Framework
|
|
227
|
-
|
|
228
|
-
**Step 1: Review Requirements**
|
|
229
|
-
- Check if the test reflects current requirements
|
|
230
|
-
- Verify product specifications haven't changed
|
|
231
|
-
- Consult documentation and design documents
|
|
232
|
-
|
|
233
|
-
**Step 2: Analyze the Failure**
|
|
234
|
-
```typescript
|
|
235
|
-
// Example: Understanding failure context
|
|
236
|
-
test('calculateTotal returns sum with tax', () => {
|
|
237
|
-
const result = calculateTotal(100, 0.1)
|
|
238
|
-
expect(result).toBe(110) // Fails - actual: 110.00000000000001
|
|
239
|
-
})
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Analysis Questions:**
|
|
243
|
-
1. Is this a floating-point precision issue? → Update test/approach
|
|
244
|
-
2. Is the calculation logic wrong? → Fix implementation
|
|
245
|
-
3. Have requirements changed? → Update both
|
|
246
|
-
|
|
247
|
-
**Step 3: Check Test Intent**
|
|
248
|
-
|
|
249
|
-
| Test Intent | Implementation Detail | Decision |
|
|
250
|
-
|------------|----------------------|----------|
|
|
251
|
-
| Behavior verification | Encapsulates business logic | **Fix implementation** |
|
|
252
|
-
| Implementation detail | Tight coupling to code structure | **Update test** |
|
|
253
|
-
| Edge case | Valid scenario not covered | **Fix implementation** |
|
|
254
|
-
| Brittle assertion | Tests irrelevant details | **Update test** |
|
|
255
|
-
|
|
256
|
-
### 2.2 Best Practices for Updating Tests
|
|
257
|
-
|
|
258
|
-
#### When Behavior Changes Intentionally
|
|
259
|
-
|
|
260
|
-
1. **Document the Change**
|
|
261
|
-
```typescript
|
|
262
|
-
/**
|
|
263
|
-
* Updated: 2025-01-12
|
|
264
|
-
* Reason: Bug fix #123 - Added email validation
|
|
265
|
-
* Previous: Accepted any string
|
|
266
|
-
* Now: Requires valid email format
|
|
267
|
-
*/
|
|
268
|
-
test('should validate email format', () => {
|
|
269
|
-
expect(validateEmail('invalid')).toBe(false)
|
|
270
|
-
expect(validateEmail('test@example.com')).toBe(true)
|
|
271
|
-
})
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
2. **Add Regression Tests**
|
|
275
|
-
```typescript
|
|
276
|
-
// Test that prevents regression of the bug
|
|
277
|
-
test('should not allow empty email after bug fix #123', () => {
|
|
278
|
-
expect(() => validateEmail('')).toThrow('Email is required')
|
|
279
|
-
})
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
3. **Update Test Suite Structure**
|
|
283
|
-
```typescript
|
|
284
|
-
describe('Bug Fix #123', () => {
|
|
285
|
-
describe('Previously broken cases', () => {
|
|
286
|
-
it('should handle edge case X', () => { /* ... */ })
|
|
287
|
-
it('should handle edge case Y', () => { /* ... */ })
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
describe('Existing functionality preserved', () => {
|
|
291
|
-
it('should still do Z', () => { /* ... */ })
|
|
292
|
-
})
|
|
293
|
-
})
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
#### When Test is Wrong
|
|
297
|
-
|
|
298
|
-
1. **Identify Test Flaws**
|
|
299
|
-
```typescript
|
|
300
|
-
// ❌ Bad: Tests implementation detail
|
|
301
|
-
test('userService calls API', () => {
|
|
302
|
-
userService.getUsers()
|
|
303
|
-
expect(api.fetch).toHaveBeenCalledWith('/users')
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
// ✅ Good: Tests behavior
|
|
307
|
-
test('userService returns users', async () => {
|
|
308
|
-
const users = await userService.getUsers()
|
|
309
|
-
expect(users).toEqual(expectedUsers)
|
|
310
|
-
})
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
2. **Refactor Test**
|
|
314
|
-
```typescript
|
|
315
|
-
// Before: Brittle test
|
|
316
|
-
test('returns user object', () => {
|
|
317
|
-
expect(getUser(1)).toEqual({
|
|
318
|
-
id: 1,
|
|
319
|
-
name: 'John',
|
|
320
|
-
email: 'john@example.com',
|
|
321
|
-
passwordHash: 'abc123...',
|
|
322
|
-
createdAt: '2025-01-12'
|
|
323
|
-
})
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
// After: Focused test
|
|
327
|
-
test('returns user with required fields', () => {
|
|
328
|
-
const user = getUser(1)
|
|
329
|
-
expect(user).toMatchObject({
|
|
330
|
-
id: expect.any(Number),
|
|
331
|
-
name: expect.any(String),
|
|
332
|
-
email: expect.stringContaining('@')
|
|
333
|
-
})
|
|
334
|
-
expect(user).not.toHaveProperty('passwordHash')
|
|
335
|
-
})
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### 2.3 Documenting Test Changes
|
|
339
|
-
|
|
340
|
-
#### Commit Message Format
|
|
341
|
-
```
|
|
342
|
-
test: update email validation tests after bug fix #123
|
|
343
|
-
|
|
344
|
-
- Add test for empty email validation
|
|
345
|
-
- Update assertion to check format validation
|
|
346
|
-
- Add regression test for edge case case with special chars
|
|
347
|
-
|
|
348
|
-
Related: #123
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
#### Test Documentation Template
|
|
352
|
-
```typescript
|
|
353
|
-
/**
|
|
354
|
-
* Test Suite: User Authentication
|
|
355
|
-
*
|
|
356
|
-
* Bug Fixes Applied:
|
|
357
|
-
* - #123: Fixed email validation (2025-01-12)
|
|
358
|
-
* - #456: Fixed password hash comparison (2025-01-10)
|
|
359
|
-
*
|
|
360
|
-
* Known Issues:
|
|
361
|
-
* - #789: Tests fail in Safari due to crypto API
|
|
362
|
-
*
|
|
363
|
-
* Maintenance Notes:
|
|
364
|
-
* - Update mock tokens monthly
|
|
365
|
-
* - Refresh fixtures after auth schema changes
|
|
366
|
-
*/
|
|
367
|
-
describe('Authentication', () => {
|
|
368
|
-
// tests...
|
|
369
|
-
})
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
#### Change Log Approach
|
|
373
|
-
```typescript
|
|
374
|
-
/*
|
|
375
|
-
* CHANGE LOG
|
|
376
|
-
* ----------
|
|
377
|
-
* 2025-01-12: Updated test expectations after bug fix #123
|
|
378
|
-
* - Changed from toBe() to toBeCloseTo() for floating point
|
|
379
|
-
* - Added edge case test for zero values
|
|
380
|
-
*
|
|
381
|
-
* 2025-01-10: Added test for new feature
|
|
382
|
-
* - Added test case for batch processing
|
|
383
|
-
* - Updated mock data structure
|
|
384
|
-
*/
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
## 3. Common Test Failure Patterns
|
|
390
|
-
|
|
391
|
-
### 3.1 Understanding Failure Types
|
|
392
|
-
|
|
393
|
-
#### 1. Assertion Failures
|
|
394
|
-
|
|
395
|
-
**Pattern:** Expected vs Actual Mismatch
|
|
396
|
-
```typescript
|
|
397
|
-
// Error: Expected: 10, Received: 5
|
|
398
|
-
expect(add(5, 5)).toBe(10)
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Common Causes:**
|
|
402
|
-
- Incorrect implementation logic
|
|
403
|
-
- Wrong test expectations
|
|
404
|
-
- Data type mismatches
|
|
405
|
-
- Async timing issues
|
|
406
|
-
|
|
407
|
-
**Debug Strategy:**
|
|
408
|
-
```typescript
|
|
409
|
-
// Add logging
|
|
410
|
-
test('debug assertion', () => {
|
|
411
|
-
const result = calculate(5, 5)
|
|
412
|
-
console.log('Result:', result)
|
|
413
|
-
console.log('Type:', typeof result)
|
|
414
|
-
expect(result).toBe(10)
|
|
415
|
-
})
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
#### 2. Timeout Errors
|
|
419
|
-
|
|
420
|
-
**Pattern:** Test exceeds time limit
|
|
421
|
-
```
|
|
422
|
-
Error: Timeout - Async callback was not invoked within the 5000ms timeout
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
**Common Causes:**
|
|
426
|
-
```typescript
|
|
427
|
-
// 1. Missing await
|
|
428
|
-
test('timeout example', async () => {
|
|
429
|
-
const result = fetchData() // ❌ Missing await
|
|
430
|
-
expect(result).toBe('data')
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
// 2. Unresolved promise
|
|
434
|
-
test('timeout example', () => {
|
|
435
|
-
fetchData().then(data => {
|
|
436
|
-
expect(data).toBe('data') // ❌ Promise not returned
|
|
437
|
-
})
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
// 3. Infinite loop
|
|
441
|
-
test('timeout example', () => {
|
|
442
|
-
while (true) { // ❌ Never ends
|
|
443
|
-
process.nextTick()
|
|
444
|
-
}
|
|
445
|
-
})
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
**Solutions:**
|
|
449
|
-
```typescript
|
|
450
|
-
// ✅ Correct async handling
|
|
451
|
-
test('async test', async () => {
|
|
452
|
-
const result = await fetchData()
|
|
453
|
-
expect(result).toBe('data')
|
|
454
|
-
})
|
|
455
|
-
|
|
456
|
-
// ✅ Return promise
|
|
457
|
-
test('async test', () => {
|
|
458
|
-
return fetchData().then(data => {
|
|
459
|
-
expect(data).toBe('data')
|
|
460
|
-
})
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
// ✅ Increase timeout if needed
|
|
464
|
-
test('slow operation', async () => {
|
|
465
|
-
const result = await slowOperation()
|
|
466
|
-
expect(result).toBe('done')
|
|
467
|
-
}, { timeout: 10000 })
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
#### 3. Mock Failures
|
|
471
|
-
|
|
472
|
-
**Pattern:** Mock not called or called incorrectly
|
|
473
|
-
```typescript
|
|
474
|
-
// Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)
|
|
475
|
-
// Expected: "/api/users"
|
|
476
|
-
// Received: "/api/user"
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
**Common Issues:**
|
|
480
|
-
```typescript
|
|
481
|
-
// 1. Mock not set up
|
|
482
|
-
test('mock example', () => {
|
|
483
|
-
const spy = vi.spyOn(api, 'fetch')
|
|
484
|
-
// ❌ Forgot to mock implementation
|
|
485
|
-
service.getData()
|
|
486
|
-
expect(spy).toHaveBeenCalled()
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
// ✅ Correct: Set up mock
|
|
490
|
-
test('mock example', () => {
|
|
491
|
-
const spy = vi.spyOn(api, 'fetch').mockResolvedValue(data)
|
|
492
|
-
service.getData()
|
|
493
|
-
expect(spy).toHaveBeenCalled()
|
|
494
|
-
})
|
|
495
|
-
|
|
496
|
-
// 2. Wrong arguments
|
|
497
|
-
test('mock example', () => {
|
|
498
|
-
const spy = vi.spyOn(api, 'fetch')
|
|
499
|
-
api.fetch('/users') // ❌ Test expects '/api/users'
|
|
500
|
-
expect(spy).toHaveBeenCalledWith('/api/users')
|
|
501
|
-
})
|
|
502
|
-
|
|
503
|
-
// 3. Mock not restored
|
|
504
|
-
test('mock example', () => {
|
|
505
|
-
vi.spyOn(api, 'fetch')
|
|
506
|
-
// ❌ No cleanup - affects other tests
|
|
507
|
-
})
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
**Best Practices:**
|
|
511
|
-
```typescript
|
|
512
|
-
beforeEach(() => {
|
|
513
|
-
vi.clearAllMocks()
|
|
514
|
-
})
|
|
515
|
-
|
|
516
|
-
afterEach(() => {
|
|
517
|
-
vi.restoreAllMocks()
|
|
518
|
-
})
|
|
519
|
-
|
|
520
|
-
// Or use vi.mocked with proper typing
|
|
521
|
-
const mockFetch = vi.mocked(api.fetch)
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
#### 4. TypeScript Type Errors
|
|
525
|
-
|
|
526
|
-
**Pattern:** Type mismatches in tests
|
|
527
|
-
```typescript
|
|
528
|
-
// Error: Argument of type 'string' is not assignable to parameter of type 'number'
|
|
529
|
-
test('type error', () => {
|
|
530
|
-
expect(add('5', '5')).toBe(10) // ❌ Type error
|
|
531
|
-
})
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
**Common Issues:**
|
|
535
|
-
```typescript
|
|
536
|
-
// 1. Missing type casting
|
|
537
|
-
test('type casting', () => {
|
|
538
|
-
const value = getValue() as string // ❌ Unsafe cast
|
|
539
|
-
expect(value.toUpperCase()).toBe('TEST')
|
|
540
|
-
})
|
|
541
|
-
|
|
542
|
-
// ✅ Better: Use type guards
|
|
543
|
-
test('type guard', () => {
|
|
544
|
-
const value = getValue()
|
|
545
|
-
if (typeof value === 'string') {
|
|
546
|
-
expect(value.toUpperCase()).toBe('TEST')
|
|
547
|
-
}
|
|
548
|
-
})
|
|
549
|
-
|
|
550
|
-
// 2. Mock return type mismatch
|
|
551
|
-
const mockFn = vi.fn()
|
|
552
|
-
mockFn.mockReturnValue('string') // ❌ Should return number
|
|
553
|
-
const result: number = mockFn()
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
### 3.2 Reading Vitest Error Output
|
|
557
|
-
|
|
558
|
-
#### Error Message Structure
|
|
559
|
-
```
|
|
560
|
-
FAIL src/utils/math.test.ts > MathUtils > divide
|
|
561
|
-
Error: 2 / 0 should throw error
|
|
562
|
-
|
|
563
|
-
❯ src/utils/math.test.ts:15:23
|
|
564
|
-
13|
|
|
565
|
-
14| it('should throw on divide by zero', () => {
|
|
566
|
-
❯ 15| expect(() => divide(2, 0)).toThrow()
|
|
567
|
-
| ^
|
|
568
|
-
16| })
|
|
569
|
-
17|
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
**Key Parts:**
|
|
573
|
-
1. **Test Path:** `src/utils/math.test.ts > MathUtils > divide`
|
|
574
|
-
2. **Error Message:** Human-readable description
|
|
575
|
-
3. **File Location:** Line and column number
|
|
576
|
-
4. **Code Context:** Surrounding lines with pointer to failure
|
|
577
|
-
5. **Diff:** Expected vs Actual (for assertion failures)
|
|
578
|
-
|
|
579
|
-
#### Diff Interpretation
|
|
580
|
-
```
|
|
581
|
-
Error: expect(received).toEqual(expected)
|
|
582
|
-
|
|
583
|
-
Expected: { id: 1, name: "John", active: true }
|
|
584
|
-
Received: { id: 1, name: "John", active: false }
|
|
585
|
-
|
|
586
|
-
- Expected
|
|
587
|
-
+ Received
|
|
588
|
-
|
|
589
|
-
{
|
|
590
|
-
id: 1,
|
|
591
|
-
name: "John",
|
|
592
|
-
- active: true
|
|
593
|
-
+ active: false
|
|
594
|
-
}
|
|
595
|
-
```
|
|
596
|
-
|
|
597
|
-
**Interpretation:**
|
|
598
|
-
- `-` lines show expected values
|
|
599
|
-
- `+` lines show actual values
|
|
600
|
-
- Focus on the differences (in this case: `active` property)
|
|
601
|
-
|
|
602
|
-
### 3.3 Common TypeScript Test Issues
|
|
603
|
-
|
|
604
|
-
#### Issue 1: Property Access on Mocks
|
|
605
|
-
```typescript
|
|
606
|
-
// ❌ Error: Property 'mock' does not exist on type
|
|
607
|
-
const mockFn = vi.fn()
|
|
608
|
-
expect(mockFn.mock.calls.length).toBe(1)
|
|
609
|
-
|
|
610
|
-
// ✅ Use Vitest's mocked utility
|
|
611
|
-
import { vi, expect } from 'vitest'
|
|
612
|
-
const mockFn = vi.fn()
|
|
613
|
-
expect(mockFn).toHaveBeenCalledTimes(1)
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
#### Issue 2: Module Mocking Type Errors
|
|
617
|
-
```typescript
|
|
618
|
-
// ❌ Type error with vi.mock
|
|
619
|
-
vi.mock('./api', () => ({
|
|
620
|
-
fetchUsers: vi.fn()
|
|
621
|
-
}))
|
|
622
|
-
|
|
623
|
-
// ✅ Proper typing
|
|
624
|
-
import { vi } from 'vitest'
|
|
625
|
-
import { fetchUsers } from './api'
|
|
626
|
-
|
|
627
|
-
vi.mock('./api', () => ({
|
|
628
|
-
fetchUsers: vi.fn()
|
|
629
|
-
}))
|
|
630
|
-
|
|
631
|
-
const mockFetchUsers = vi.mocked(fetchUsers)
|
|
632
|
-
mockFetchUsers.mockResolvedValue([])
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
#### Issue 3. Async Function Return Types
|
|
636
|
-
```typescript
|
|
637
|
-
// ❌ Missing Promise type
|
|
638
|
-
const result = getData() // Type: any
|
|
639
|
-
expect(result).toBe(data)
|
|
640
|
-
|
|
641
|
-
// ✅ Proper async typing
|
|
642
|
-
const result = await getData() // Type: Data
|
|
643
|
-
expect(result).toBe(data)
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
---
|
|
647
|
-
|
|
648
|
-
## 4. Test Debugging Strategies
|
|
649
|
-
|
|
650
|
-
### 4.1 Using Vitest's Debugging Features
|
|
651
|
-
|
|
652
|
-
#### Console Logging
|
|
653
|
-
```typescript
|
|
654
|
-
test('debug with console', () => {
|
|
655
|
-
const input = { name: 'test' }
|
|
656
|
-
console.log('Input:', input)
|
|
657
|
-
|
|
658
|
-
const result = process(input)
|
|
659
|
-
console.log('Result:', result)
|
|
660
|
-
console.log('Result type:', typeof result)
|
|
661
|
-
|
|
662
|
-
expect(result.name).toBe('TEST')
|
|
663
|
-
})
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
#### Using debug() Method
|
|
667
|
-
```typescript
|
|
668
|
-
import { expect } from 'vitest'
|
|
669
|
-
|
|
670
|
-
test('debug with expect.debug', () => {
|
|
671
|
-
const result = complexOperation()
|
|
672
|
-
expect(result).debug() // Prints value to console
|
|
673
|
-
expect(result).toHaveProperty('id')
|
|
674
|
-
})
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
#### Test-Only Focus
|
|
678
|
-
```typescript
|
|
679
|
-
// Run only this test
|
|
680
|
-
test.only('debugging this specific test', () => {
|
|
681
|
-
// This test runs, others are skipped
|
|
682
|
-
})
|
|
683
|
-
|
|
684
|
-
// Or use CLI
|
|
685
|
-
vitest run -t "test name pattern"
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
#### Skipping Tests
|
|
689
|
-
```typescript
|
|
690
|
-
// Skip failing test temporarily
|
|
691
|
-
test.skip('broken test', () => {
|
|
692
|
-
// This is skipped
|
|
693
|
-
})
|
|
694
|
-
|
|
695
|
-
// Or skip conditionally
|
|
696
|
-
test.skipIf(isWindows)('unix-only test', () => {
|
|
697
|
-
// Skipped on Windows
|
|
698
|
-
})
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
### 4.2 Isolating Failing Tests
|
|
702
|
-
|
|
703
|
-
#### Strategy 1: Run Single Test File
|
|
704
|
-
```bash
|
|
705
|
-
vitest run path/to/failing.test.ts
|
|
706
|
-
```
|
|
707
|
-
|
|
708
|
-
#### Strategy 2: Run Specific Test
|
|
709
|
-
```typescript
|
|
710
|
-
// Use test.only
|
|
711
|
-
test.only('failing test', () => {
|
|
712
|
-
// Only this runs
|
|
713
|
-
})
|
|
714
|
-
|
|
715
|
-
// Or use pattern matching
|
|
716
|
-
vitest run -t "failing test"
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
#### Strategy 3: Bisect Tests
|
|
720
|
-
```bash
|
|
721
|
-
# Use binary search to find problematic test
|
|
722
|
-
vitest run --bail 1
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
#### Strategy 4: Disable Other Tests
|
|
726
|
-
```typescript
|
|
727
|
-
// Comment out or skip other tests temporarily
|
|
728
|
-
describe('Feature', () => {
|
|
729
|
-
test.skip('test 1', () => { /* ... */ })
|
|
730
|
-
test.skip('test 2', () => { /* ... */ })
|
|
731
|
-
test('failing test', () => {
|
|
732
|
-
// Only this runs
|
|
733
|
-
})
|
|
734
|
-
})
|
|
735
|
-
```
|
|
736
|
-
|
|
737
|
-
### 4.3 Understanding Stack Traces
|
|
738
|
-
|
|
739
|
-
#### Reading Stack Traces
|
|
740
|
-
```
|
|
741
|
-
Error: Cannot read property 'map' of undefined
|
|
742
|
-
|
|
743
|
-
❯ src/utils/users.ts:25:18
|
|
744
|
-
23| const users = await fetchUsers()
|
|
745
|
-
24| const activeUsers = users.filter(u => u.active)
|
|
746
|
-
❯ 25| const names = activeUsers.map(u => u.name)
|
|
747
|
-
| ^
|
|
748
|
-
26| return names
|
|
749
|
-
27| }
|
|
750
|
-
|
|
751
|
-
❯ src/utils/users.test.ts:15:20
|
|
752
|
-
13|
|
|
753
|
-
14| it('should get active user names', async () => {
|
|
754
|
-
❯ 15| const names = await getActiveUserNames()
|
|
755
|
-
| ^
|
|
756
|
-
16| expect(names).toEqual(['John'])
|
|
757
|
-
17| })
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
**Analysis:**
|
|
761
|
-
1. **Error Location:** Line 25 in `users.ts`
|
|
762
|
-
2. **Error Type:** `Cannot read property 'map' of undefined`
|
|
763
|
-
3. **Root Cause:** `activeUsers` is undefined
|
|
764
|
-
4. **Why:** `users.filter()` returned undefined (users was likely undefined)
|
|
765
|
-
5. **Test Location:** Line 15 in test file
|
|
766
|
-
|
|
767
|
-
#### Debug Flow
|
|
768
|
-
```typescript
|
|
769
|
-
// 1. Check what's undefined
|
|
770
|
-
test('debug undefined', async () => {
|
|
771
|
-
const users = await fetchUsers()
|
|
772
|
-
console.log('Users:', users) // Check if users is undefined
|
|
773
|
-
|
|
774
|
-
const activeUsers = users?.filter(u => u.active)
|
|
775
|
-
console.log('Active users:', activeUsers) // Check result
|
|
776
|
-
})
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
#### Common Stack Trace Patterns
|
|
780
|
-
|
|
781
|
-
| Pattern | Meaning | Fix |
|
|
782
|
-
|---------|---------|-----|
|
|
783
|
-
| `Cannot read property 'X' of undefined` | Object is undefined | Add null check or fix data source |
|
|
784
|
-
| `X is not a function` | Wrong type or not imported | Check import and type |
|
|
785
|
-
| `Expected X to be Y` | Assertion failure | Check logic or update expectation |
|
|
786
|
-
| `Timeout exceeded` | Test too long | Fix async code or increase timeout |
|
|
787
|
-
|
|
788
|
-
### 4.4 Advanced Debugging Techniques
|
|
789
|
-
|
|
790
|
-
#### Using Node.js Debugger
|
|
791
|
-
```bash
|
|
792
|
-
# Start with inspect flag
|
|
793
|
-
vitest --inspect-brk --no-coverage
|
|
794
|
-
|
|
795
|
-
# Then in Chrome: chrome://inspect
|
|
796
|
-
# Or in VS Code: Add launch configuration
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
#### VS Code Launch Configuration
|
|
800
|
-
```json
|
|
801
|
-
{
|
|
802
|
-
"version": "0.2.0",
|
|
803
|
-
"configurations": [
|
|
804
|
-
{
|
|
805
|
-
"type": "node",
|
|
806
|
-
"request": "launch",
|
|
807
|
-
"name": "Debug Vitest",
|
|
808
|
-
"runtimeExecutable": "npm",
|
|
809
|
-
"runtimeArgs": ["test", "--", "--inspect-brk", "--no-coverage"],
|
|
810
|
-
"console": "integratedTerminal",
|
|
811
|
-
"internalConsoleOptions": "neverOpen"
|
|
812
|
-
}
|
|
813
|
-
]
|
|
814
|
-
}
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
#### Conditional Breakpoints in Tests
|
|
818
|
-
```typescript
|
|
819
|
-
test('debug specific condition', () => {
|
|
820
|
-
let value = process(input)
|
|
821
|
-
|
|
822
|
-
// Add conditional check
|
|
823
|
-
if (value !== expected) {
|
|
824
|
-
console.log('Debug info:', { input, value, expected })
|
|
825
|
-
debugger // Breaks here in debugger
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
expect(value).toBe(expected)
|
|
829
|
-
})
|
|
830
|
-
```
|
|
831
|
-
|
|
832
|
-
---
|
|
833
|
-
|
|
834
|
-
## 5. Decision Framework: Test vs Implementation
|
|
835
|
-
|
|
836
|
-
### 5.1 Flowchart for Determining Action
|
|
837
|
-
|
|
838
|
-
```
|
|
839
|
-
┌─────────────────────────────┐
|
|
840
|
-
│ Test Failing │
|
|
841
|
-
└──────────┬──────────────────┘
|
|
842
|
-
│
|
|
843
|
-
▼
|
|
844
|
-
┌─────────────────────────────┐
|
|
845
|
-
│ Are requirements current? │
|
|
846
|
-
└──────────┬──────────────────┘
|
|
847
|
-
│
|
|
848
|
-
┌─────┴─────┐
|
|
849
|
-
│ │
|
|
850
|
-
Yes No
|
|
851
|
-
│ │
|
|
852
|
-
▼ ▼
|
|
853
|
-
┌─────────┐ ┌─────────────────┐
|
|
854
|
-
│ Check │ │ Update test to │
|
|
855
|
-
│ behavior│ │ match new reqs │
|
|
856
|
-
└────┬────┘ └─────────────────┘
|
|
857
|
-
│
|
|
858
|
-
▼
|
|
859
|
-
┌─────────────────────────────┐
|
|
860
|
-
│ Does implementation match │
|
|
861
|
-
│ documented requirements? │
|
|
862
|
-
└──────────┬──────────────────┘
|
|
863
|
-
│
|
|
864
|
-
┌─────┴─────┐
|
|
865
|
-
│ │
|
|
866
|
-
Yes No
|
|
867
|
-
│ │
|
|
868
|
-
▼ ▼
|
|
869
|
-
┌─────────┐ ┌─────────────────┐
|
|
870
|
-
│ Update │ │ Fix │
|
|
871
|
-
│ test │ │ implementation │
|
|
872
|
-
└─────────┘ └─────────────────┘
|
|
873
|
-
```
|
|
874
|
-
|
|
875
|
-
### 5.2 Checklist
|
|
876
|
-
|
|
877
|
-
#### Before Changing Test
|
|
878
|
-
- [ ] Reviewed requirements documentation
|
|
879
|
-
- [ ] Checked if product spec changed
|
|
880
|
-
- [ ] Verified test wasn't testing implementation detail
|
|
881
|
-
- [ ] Confirmed test was correct before bug fix
|
|
882
|
-
- [ ] Consulted with product owner if needed
|
|
883
|
-
|
|
884
|
-
#### Before Changing Implementation
|
|
885
|
-
- [ ] Verified implementation is wrong
|
|
886
|
-
- [ ] Checked related code for similar issues
|
|
887
|
-
- [ ] Reviewed test assertions are correct
|
|
888
|
-
- [ ] Added regression test for bug fix
|
|
889
|
-
- [ ] Documented the bug and fix
|
|
890
|
-
|
|
891
|
-
### 5.3 Decision Matrix
|
|
892
|
-
|
|
893
|
-
| Scenario | Test Behavior | Implementation | Action |
|
|
894
|
-
|----------|--------------|----------------|--------|
|
|
895
|
-
| Bug found in code | Correct | Wrong | Fix implementation, add regression test |
|
|
896
|
-
| Requirements changed | Outdated | Correct | Update test |
|
|
897
|
-
| Test too brittle | Implementation detail | Correct | Refactor test to test behavior |
|
|
898
|
-
| Edge case discovered | Missing | Correct | Add test case |
|
|
899
|
-
| Feature deprecated | Correct | Deprecated | Remove test and implementation |
|
|
900
|
-
| API contract changed | Outdated | Updated | Update test to match new contract |
|
|
901
|
-
|
|
902
|
-
### 5.4 Examples
|
|
903
|
-
|
|
904
|
-
#### Example 1: Bug in Implementation
|
|
905
|
-
```typescript
|
|
906
|
-
// Test is correct
|
|
907
|
-
test('should calculate tax correctly', () => {
|
|
908
|
-
expect(calculateTax(100, 0.1)).toBe(10)
|
|
909
|
-
})
|
|
910
|
-
|
|
911
|
-
// Implementation has bug
|
|
912
|
-
function calculateTax(amount: number, rate: number): number {
|
|
913
|
-
return amount * rate // ❌ Missing rounding
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
// Action: Fix implementation
|
|
917
|
-
function calculateTax(amount: number, rate: number): number {
|
|
918
|
-
return Math.round(amount * rate * 100) / 100
|
|
919
|
-
}
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
#### Example 2: Test Needs Update
|
|
923
|
-
```typescript
|
|
924
|
-
// Old behavior
|
|
925
|
-
test('should return active users', () => {
|
|
926
|
-
const users = getActiveUsers(allUsers)
|
|
927
|
-
expect(users).toHaveLength(3) // ❌ Old expectation
|
|
928
|
-
})
|
|
929
|
-
|
|
930
|
-
// New requirement: Include users with 'pending' status
|
|
931
|
-
function getActiveUsers(users: User[]): User[] {
|
|
932
|
-
return users.filter(u => u.status === 'active' || u.status === 'pending')
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
// Action: Update test
|
|
936
|
-
test('should return active and pending users', () => {
|
|
937
|
-
const users = getActiveUsers(allUsers)
|
|
938
|
-
expect(users).toHaveLength(5) // ✅ Updated
|
|
939
|
-
})
|
|
940
|
-
```
|
|
941
|
-
|
|
942
|
-
#### Example 3: Test Implementation Detail
|
|
943
|
-
```typescript
|
|
944
|
-
// ❌ Bad: Tests implementation
|
|
945
|
-
test('sortUsers calls Array.sort', () => {
|
|
946
|
-
const spy = vi.spyOn(Array.prototype, 'sort')
|
|
947
|
-
sortUsers(users)
|
|
948
|
-
expect(spy).toHaveBeenCalled()
|
|
949
|
-
})
|
|
950
|
-
|
|
951
|
-
// ✅ Good: Tests behavior
|
|
952
|
-
test('sortUsers returns users sorted by name', () => {
|
|
953
|
-
const sorted = sortUsers(users)
|
|
954
|
-
expect(sorted).toEqual(sortedByName)
|
|
955
|
-
})
|
|
956
|
-
```
|
|
957
|
-
|
|
958
|
-
---
|
|
959
|
-
|
|
960
|
-
## 6. Resources and References
|
|
961
|
-
|
|
962
|
-
### 6.1 Official Vitest Documentation
|
|
963
|
-
|
|
964
|
-
**Primary Resources:**
|
|
965
|
-
- **Vitest Official Website:** https://vitest.dev
|
|
966
|
-
- **Vitest GitHub Repository:** https://github.com/vitest-dev/vitest
|
|
967
|
-
- **Vitest Discord Community:** https://vitest.dev/chat
|
|
968
|
-
|
|
969
|
-
#### Essential Documentation Sections:
|
|
970
|
-
|
|
971
|
-
1. **Getting Started Guide**
|
|
972
|
-
- URL: https://vitest.dev/guide/
|
|
973
|
-
- Installation, configuration, and basic usage
|
|
974
|
-
|
|
975
|
-
2. **API Reference**
|
|
976
|
-
- URL: https://vitest.dev/api/
|
|
977
|
-
- Complete reference for `expect`, `test`, `describe`, and all assertion methods
|
|
978
|
-
|
|
979
|
-
3. **Debugging Guide**
|
|
980
|
-
- URL: https://vitest.dev/guide/debugging.html
|
|
981
|
-
- Using `--inspect-brk`, VS Code integration, Chrome DevTools
|
|
982
|
-
|
|
983
|
-
4. **Mock Functions**
|
|
984
|
-
- URL: https://vitest.dev/api/mock.html
|
|
985
|
-
- `vi.fn()`, `vi.mock()`, `vi.spyOn()`, `vi.mocked()`
|
|
986
|
-
|
|
987
|
-
5. **Test Context**
|
|
988
|
-
- URL: https://vitest.dev/api/context.html
|
|
989
|
-
- Using test context for advanced scenarios
|
|
990
|
-
|
|
991
|
-
6. **Configuration Options**
|
|
992
|
-
- URL: https://vitest.dev/config/
|
|
993
|
-
- Complete `vitest.config.ts` reference
|
|
994
|
-
|
|
995
|
-
7. **CLI Reference**
|
|
996
|
-
- URL: https://vitest.dev/cli/
|
|
997
|
-
- All command-line flags and options
|
|
998
|
-
|
|
999
|
-
8. **UI Interface**
|
|
1000
|
-
- URL: https://vitest.dev/guide/ui.html
|
|
1001
|
-
- Interactive test browser and debugging UI
|
|
1002
|
-
|
|
1003
|
-
9. **Coverage**
|
|
1004
|
-
- URL: https://vitest.dev/guide/coverage.html
|
|
1005
|
-
- Code coverage configuration with c8 and istanbul
|
|
1006
|
-
|
|
1007
|
-
10. **Common Errors**
|
|
1008
|
-
- URL: https://vitest.dev/guide/common-errors.html
|
|
1009
|
-
- Troubleshooting common test failures
|
|
1010
|
-
|
|
1011
|
-
11. **Snapshot Testing**
|
|
1012
|
-
- URL: https://vitest.dev/guide/snapshot.html
|
|
1013
|
-
- Inline and external snapshot testing
|
|
1014
|
-
|
|
1015
|
-
12. **Testing Library Support**
|
|
1016
|
-
- URL: https://vitest.dev/guide/testing-library.html
|
|
1017
|
-
- Integration with @testing-library
|
|
1018
|
-
|
|
1019
|
-
13. **In-Source Testing**
|
|
1020
|
-
- URL: https://vitest.dev/guide/in-source.html
|
|
1021
|
-
- Writing tests alongside source code
|
|
1022
|
-
|
|
1023
|
-
14. **Workspace Projects**
|
|
1024
|
-
- URL: https://vitest.dev/guide/workspace.html
|
|
1025
|
-
- Monorepo and multi-project setup
|
|
1026
|
-
|
|
1027
|
-
### 6.2 External Best Practices and Community Resources
|
|
1028
|
-
|
|
1029
|
-
#### Testing Best Practices from Industry Experts
|
|
1030
|
-
|
|
1031
|
-
1. **Kent C. Dodds - Testing Principles**
|
|
1032
|
-
- Blog: https://kentcdodds.com/blog/tags/testing
|
|
1033
|
-
- Key Concepts:
|
|
1034
|
-
- "The more your tests resemble the way your software is used, the more confidence they can give you"
|
|
1035
|
-
- Integration tests over unit tests
|
|
1036
|
-
- Avoid mocking when possible
|
|
1037
|
-
- Test user behavior, not implementation details
|
|
1038
|
-
|
|
1039
|
-
2. **Martin Fowler - Testing Strategies**
|
|
1040
|
-
- Articles: https://martinfowler.com/tags/testing.html
|
|
1041
|
-
- Key Topics:
|
|
1042
|
-
- Test Pyramid (unit, integration, e2e)
|
|
1043
|
-
- Test Coverage
|
|
1044
|
-
- Continuous Integration testing
|
|
1045
|
-
- Refactoring test code
|
|
1046
|
-
|
|
1047
|
-
3. **Google Testing Blog**
|
|
1048
|
-
- URL: https://testing.googleblog.com/
|
|
1049
|
-
- Key Topics:
|
|
1050
|
-
- Test size categorization (small, medium, large)
|
|
1051
|
-
- Test doubles and fakes
|
|
1052
|
-
- Hermetic testing
|
|
1053
|
-
- Flaky test detection
|
|
1054
|
-
|
|
1055
|
-
4. **JavaScript Testing Best Practices**
|
|
1056
|
-
- GitHub: https://github.com/goldbergyoni/javascript-testing-best-practices
|
|
1057
|
-
- Comprehensive guide covering:
|
|
1058
|
-
- Test structure and organization
|
|
1059
|
-
- Async testing patterns
|
|
1060
|
-
- Mock and stub strategies
|
|
1061
|
-
- Performance testing
|
|
1062
|
-
|
|
1063
|
-
#### TypeScript-Specific Testing Resources
|
|
1064
|
-
|
|
1065
|
-
1. **TypeScript Deep Dive - Testing**
|
|
1066
|
-
- URL: https://basarat.gitbook.io/typescript/type-system/typings-for-npm-packages
|
|
1067
|
-
- Mocking TypeScript modules
|
|
1068
|
-
- Type-safe test helpers
|
|
1069
|
-
|
|
1070
|
-
2. **Testing TypeScript with Vitest**
|
|
1071
|
-
- Community tutorials on Medium and Dev.to
|
|
1072
|
-
- Focus on type safety in tests
|
|
1073
|
-
- Generic test utilities
|
|
1074
|
-
|
|
1075
|
-
#### Test Maintenance Patterns
|
|
1076
|
-
|
|
1077
|
-
1. **Regression Testing**
|
|
1078
|
-
- Always add tests when fixing bugs
|
|
1079
|
-
- Keep bug fix tests separate from feature tests
|
|
1080
|
-
- Document the bug being prevented
|
|
1081
|
-
|
|
1082
|
-
2. **Test Refactoring**
|
|
1083
|
-
- Extract common setup into fixtures
|
|
1084
|
-
- Create custom matchers for domain-specific assertions
|
|
1085
|
-
- Use factory functions for test data
|
|
1086
|
-
|
|
1087
|
-
3. **Flaky Test Management**
|
|
1088
|
-
- Identify and isolate flaky tests
|
|
1089
|
-
- Retry mechanisms for known flaky tests
|
|
1090
|
-
- Fix underlying timing or dependency issues
|
|
1091
|
-
|
|
1092
|
-
#### Community Forums and Q&A
|
|
1093
|
-
|
|
1094
|
-
1. **Stack Overflow - Vitest Tag**
|
|
1095
|
-
- URL: https://stackoverflow.com/questions/tagged/vitest
|
|
1096
|
-
- Search for specific error messages
|
|
1097
|
-
- Common solutions to test failures
|
|
1098
|
-
|
|
1099
|
-
2. **Vitest GitHub Discussions**
|
|
1100
|
-
- URL: https://github.com/vitest-dev/vitest/discussions
|
|
1101
|
-
- Feature requests and best practices
|
|
1102
|
-
- Community solutions
|
|
1103
|
-
|
|
1104
|
-
3. **Reddit - r/vitest**
|
|
1105
|
-
- User experiences and solutions
|
|
1106
|
-
- Testing patterns and anti-patterns
|
|
1107
|
-
|
|
1108
|
-
#### Recommended Reading Topics
|
|
1109
|
-
|
|
1110
|
-
##### For Vitest:
|
|
1111
|
-
- Debugging tests with `--inspect-brk`
|
|
1112
|
-
- Using the Vitest UI for visual debugging
|
|
1113
|
-
- Mock module patterns
|
|
1114
|
-
- Snapshot testing
|
|
1115
|
-
- Parallel test execution
|
|
1116
|
-
- Workspace configuration for monorepos
|
|
1117
|
-
|
|
1118
|
-
##### For Test Maintenance:
|
|
1119
|
-
- Regression testing strategies
|
|
1120
|
-
- Test-driven development workflows
|
|
1121
|
-
- Continuous integration for tests
|
|
1122
|
-
- Test smell identification and refactoring
|
|
1123
|
-
- Test suite organization and structure
|
|
1124
|
-
- Documentation patterns for tests
|
|
1125
|
-
|
|
1126
|
-
##### For TypeScript Testing:
|
|
1127
|
-
- Type-safe mocking with `vi.mocked()`
|
|
1128
|
-
- Testing async code patterns
|
|
1129
|
-
- Type assertion patterns in tests
|
|
1130
|
-
- Generic test utilities
|
|
1131
|
-
- Testing with complex types
|
|
1132
|
-
- Mock type definitions
|
|
1133
|
-
|
|
1134
|
-
### 6.3 Common Patterns to Implement
|
|
1135
|
-
|
|
1136
|
-
#### Test Helpers
|
|
1137
|
-
```typescript
|
|
1138
|
-
// test-helpers.ts
|
|
1139
|
-
export const createMockUser = (overrides = {}) => ({
|
|
1140
|
-
id: 1,
|
|
1141
|
-
name: 'Test User',
|
|
1142
|
-
email: 'test@example.com',
|
|
1143
|
-
...overrides
|
|
1144
|
-
})
|
|
1145
|
-
|
|
1146
|
-
export const waitForCondition = async (
|
|
1147
|
-
condition: () => boolean,
|
|
1148
|
-
timeout = 5000
|
|
1149
|
-
) => {
|
|
1150
|
-
const start = Date.now()
|
|
1151
|
-
while (!condition() && Date.now() - start < timeout) {
|
|
1152
|
-
await new Promise(resolve => setTimeout(resolve, 100))
|
|
1153
|
-
}
|
|
1154
|
-
return condition()
|
|
1155
|
-
}
|
|
1156
|
-
```
|
|
1157
|
-
|
|
1158
|
-
#### Custom Matchers
|
|
1159
|
-
```typescript
|
|
1160
|
-
// custom-matchers.ts
|
|
1161
|
-
import { expect } from 'vitest'
|
|
1162
|
-
|
|
1163
|
-
interface CustomMatchers {
|
|
1164
|
-
toBeValidEmail(): any
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
expect.extend({
|
|
1168
|
-
toBeValidEmail(received: string) {
|
|
1169
|
-
const pass = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(received)
|
|
1170
|
-
return {
|
|
1171
|
-
pass,
|
|
1172
|
-
message: () =>
|
|
1173
|
-
pass
|
|
1174
|
-
? `Expected ${received} not to be valid email`
|
|
1175
|
-
: `Expected ${received} to be valid email`,
|
|
1176
|
-
}
|
|
1177
|
-
},
|
|
1178
|
-
})
|
|
1179
|
-
```
|
|
1180
|
-
|
|
1181
|
-
### 6.4 CI/CD Integration and Test Automation
|
|
1182
|
-
|
|
1183
|
-
#### GitHub Actions Configuration
|
|
1184
|
-
|
|
1185
|
-
```yaml
|
|
1186
|
-
# .github/workflows/test.yml
|
|
1187
|
-
name: Test Suite
|
|
1188
|
-
|
|
1189
|
-
on:
|
|
1190
|
-
push:
|
|
1191
|
-
branches: [main, develop]
|
|
1192
|
-
pull_request:
|
|
1193
|
-
branches: [main, develop]
|
|
1194
|
-
|
|
1195
|
-
jobs:
|
|
1196
|
-
test:
|
|
1197
|
-
runs-on: ubuntu-latest
|
|
1198
|
-
|
|
1199
|
-
steps:
|
|
1200
|
-
- uses: actions/checkout@v4
|
|
1201
|
-
|
|
1202
|
-
- uses: actions/setup-node@v4
|
|
1203
|
-
with:
|
|
1204
|
-
node-version: '20'
|
|
1205
|
-
|
|
1206
|
-
- name: Install dependencies
|
|
1207
|
-
run: npm ci
|
|
1208
|
-
|
|
1209
|
-
- name: Run tests
|
|
1210
|
-
run: npm run test:ci
|
|
1211
|
-
|
|
1212
|
-
- name: Upload coverage
|
|
1213
|
-
uses: codecov/codecov-action@v3
|
|
1214
|
-
with:
|
|
1215
|
-
files: ./coverage/coverage-final.json
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
#### Test Scripts for package.json
|
|
1219
|
-
|
|
1220
|
-
```json
|
|
1221
|
-
{
|
|
1222
|
-
"scripts": {
|
|
1223
|
-
"test": "vitest",
|
|
1224
|
-
"test:ci": "vitest run --coverage",
|
|
1225
|
-
"test:ui": "vitest --ui",
|
|
1226
|
-
"test:debug": "vitest --inspect-brk --no-coverage",
|
|
1227
|
-
"test:watch": "vitest --watch",
|
|
1228
|
-
"test:changed": "vitest --changed"
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
```
|
|
1232
|
-
|
|
1233
|
-
#### Pre-commit Hooks with Husky
|
|
1234
|
-
|
|
1235
|
-
```bash
|
|
1236
|
-
# Install Husky
|
|
1237
|
-
npm install -D husky
|
|
1238
|
-
|
|
1239
|
-
# Set up git hooks
|
|
1240
|
-
npx husky install
|
|
1241
|
-
npx husky add .husky/pre-commit "npm run test"
|
|
1242
|
-
```
|
|
1243
|
-
|
|
1244
|
-
#### Test Maintenance Checklist Template
|
|
1245
|
-
|
|
1246
|
-
```markdown
|
|
1247
|
-
## Test Maintenance Checklist
|
|
1248
|
-
|
|
1249
|
-
### Before Modifying Tests
|
|
1250
|
-
- [ ] Reviewed bug report/requirements
|
|
1251
|
-
- [ ] Identified root cause
|
|
1252
|
-
- [ ] Checked related tests
|
|
1253
|
-
- [ ] Confirmed test intent
|
|
1254
|
-
- [ ] Verified requirements haven't changed
|
|
1255
|
-
|
|
1256
|
-
### During Update
|
|
1257
|
-
- [ ] Updated failing tests
|
|
1258
|
-
- [ ] Added regression tests
|
|
1259
|
-
- [ ] Updated mocks if needed
|
|
1260
|
-
- [ ] Verified all tests pass
|
|
1261
|
-
- [ ] Checked test coverage
|
|
1262
|
-
- [ ] Ran full test suite
|
|
1263
|
-
|
|
1264
|
-
### After Update
|
|
1265
|
-
- [ ] Ran full test suite
|
|
1266
|
-
- [ ] Checked coverage
|
|
1267
|
-
- [ ] Updated documentation
|
|
1268
|
-
- [ ] Committed with clear message
|
|
1269
|
-
- [ ] Updated change log
|
|
1270
|
-
- [ ] Verified CI/CD passes
|
|
1271
|
-
```
|
|
1272
|
-
|
|
1273
|
-
### 6.5 Quick Reference Commands
|
|
1274
|
-
|
|
1275
|
-
```bash
|
|
1276
|
-
# Run all tests
|
|
1277
|
-
vitest
|
|
1278
|
-
|
|
1279
|
-
# Run with coverage
|
|
1280
|
-
vitest --coverage
|
|
1281
|
-
|
|
1282
|
-
# Run specific file
|
|
1283
|
-
vitest run path/to/test.ts
|
|
1284
|
-
|
|
1285
|
-
# Run in watch mode
|
|
1286
|
-
vitest --watch
|
|
1287
|
-
|
|
1288
|
-
# Run with UI
|
|
1289
|
-
vitest --ui
|
|
1290
|
-
|
|
1291
|
-
# Debug mode
|
|
1292
|
-
vitest --inspect-brk
|
|
1293
|
-
|
|
1294
|
-
# Run only changed tests
|
|
1295
|
-
vitest --changed
|
|
1296
|
-
|
|
1297
|
-
# Update snapshots
|
|
1298
|
-
vitest -u
|
|
1299
|
-
|
|
1300
|
-
# Run tests matching pattern
|
|
1301
|
-
vitest run -t "pattern"
|
|
1302
|
-
```
|
|
1303
|
-
|
|
1304
|
-
---
|
|
1305
|
-
|
|
1306
|
-
## Conclusion
|
|
1307
|
-
|
|
1308
|
-
This research document provides comprehensive guidance on test maintenance after bug fixes, with a focus on Vitest and TypeScript. Key takeaways:
|
|
1309
|
-
|
|
1310
|
-
1. **Always understand the root cause** before modifying tests
|
|
1311
|
-
2. **Prefer behavior testing** over implementation details
|
|
1312
|
-
3. **Document changes** thoroughly for future maintainers
|
|
1313
|
-
4. **Use Vitest's debugging tools** effectively
|
|
1314
|
-
5. **Add regression tests** when fixing bugs
|
|
1315
|
-
6. **Keep tests isolated** and independent
|
|
1316
|
-
|
|
1317
|
-
Following these practices will help maintain a healthy, reliable test suite that catches bugs without becoming a maintenance burden.
|
|
1318
|
-
|
|
1319
|
-
---
|
|
1320
|
-
|
|
1321
|
-
**Document Version:** 1.0
|
|
1322
|
-
**Last Updated:** 2026-01-12
|
|
1323
|
-
**Maintained By:** Groundswell Development Team
|