@nathapp/nax 0.28.0 → 0.30.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/CHANGELOG.md +23 -2
- package/bin/nax.ts +2 -3
- package/dist/nax.js +72753 -0
- package/package.json +11 -3
- package/src/cli/analyze.ts +2 -7
- package/src/cli/config.ts +3 -1
- package/src/config/defaults.ts +1 -0
- package/src/config/schemas.ts +1 -0
- package/src/config/types.ts +1 -0
- package/src/context/builder.ts +10 -1
- package/src/execution/lifecycle/headless-formatter.ts +2 -4
- package/src/prompts/builder.ts +12 -69
- package/src/prompts/sections/isolation.ts +38 -8
- package/src/prompts/sections/role-task.ts +79 -17
- package/src/review/runner.ts +6 -1
- package/src/version.ts +2 -1
- package/.claude/rules/01-project-conventions.md +0 -34
- package/.claude/rules/02-test-architecture.md +0 -39
- package/.claude/rules/03-test-writing.md +0 -58
- package/.claude/rules/04-forbidden-patterns.md +0 -29
- package/.claude/settings.json +0 -15
- package/.githooks/pre-commit +0 -16
- package/.gitlab-ci.yml +0 -103
- package/.mcp.json +0 -8
- package/BRIEF.md +0 -140
- package/CLAUDE.md +0 -143
- package/US-007-IMPLEMENTATION.md +0 -139
- package/biome.json +0 -14
- package/bun.lock +0 -163
- package/bunfig.toml +0 -12
- package/docker-compose.test.yml +0 -15
- package/docs/20260216-fix-plan-context-review.md +0 -56
- package/docs/20260216-relentless-vs-ngent-comparison.md +0 -208
- package/docs/20260216-v02-plan.md +0 -136
- package/docs/20260216-v02-review.md +0 -685
- package/docs/20260217-dogfood-findings.md +0 -56
- package/docs/20260217-p2-plus-plan.md +0 -117
- package/docs/20260217-partial-fixes-plan.md +0 -62
- package/docs/20260217-plan-analyze-spec.md +0 -117
- package/docs/20260217-post-impl-review.md +0 -1137
- package/docs/20260217-quick-wins-plan.md +0 -66
- package/docs/20260217-split-runner-plan.md +0 -75
- package/docs/20260217-v03-impl-plan.md +0 -80
- package/docs/20260217-v03-post-impl-review.md +0 -589
- package/docs/20260217-v04-impl-plan.md +0 -86
- package/docs/20260217-v05-post-impl-review.md +0 -850
- package/docs/20260217-v06-post-impl-review.md +0 -817
- package/docs/20260218-adr003-port-plan.md +0 -151
- package/docs/20260218-review-adr003-verification.md +0 -175
- package/docs/20260219-fix-plan-bug16-19.md +0 -79
- package/docs/20260219-fix-plan-bug20-22.md +0 -114
- package/docs/20260219-plan-llm-routing.md +0 -116
- package/docs/20260219-review-bug20-22-fixes.md +0 -135
- package/docs/20260219-routing-baseline-keyword.md +0 -63
- package/docs/20260220-plan-structured-logging-p1.md +0 -80
- package/docs/20260220-plan-structured-logging-p2.md +0 -37
- package/docs/20260220-review-llm-routing.md +0 -180
- package/docs/20260220-review-post-fix-llm-routing.md +0 -70
- package/docs/20260221-fix-plan-relevantfiles-split.md +0 -101
- package/docs/20260221-fix-plan-routing-mode.md +0 -125
- package/docs/20260221-review-v0.9-implementation.md +0 -379
- package/docs/20260222-fix-plan-v091-routing-isolation.md +0 -197
- package/docs/20260223-fix-plan-prompt-audit.md +0 -62
- package/docs/20260224-nax-roadmap-phases.md +0 -189
- package/docs/20260225-phase2-llm-service-layer.md +0 -401
- package/docs/20260225-review-v0.10.1.md +0 -187
- package/docs/20260303-v010-implementation-plan.md +0 -165
- package/docs/20260304-review-nax.md +0 -492
- package/docs/CLAUDE.md.bak +0 -191
- package/docs/ROADMAP.md +0 -390
- package/docs/SPEC-rectification.md +0 -0
- package/docs/SPEC.md +0 -324
- package/docs/US-001-plugin-loading-verification.md +0 -152
- package/docs/adr/ADR-005-implementation-plan.md +0 -655
- package/docs/adr/ADR-005-pipeline-re-architecture.md +0 -464
- package/docs/architecture-analysis.md +0 -1076
- package/docs/bugs/BUG-21-escalation-null-attempts.md +0 -48
- package/docs/bugs-from-dogfood-run-c.md +0 -243
- package/docs/code-review-20260228.md +0 -612
- package/docs/code-review-v0.15.0.md +0 -629
- package/docs/hook-lifecycle-test-plan.md +0 -149
- package/docs/releases/v0.11.0-and-earlier.md +0 -20
- package/docs/releases/v0.12.0.md +0 -15
- package/docs/releases/v0.13.0.md +0 -14
- package/docs/releases/v0.14.0.md +0 -20
- package/docs/releases/v0.14.1.md +0 -36
- package/docs/releases/v0.14.2.md +0 -51
- package/docs/releases/v0.14.3.md +0 -174
- package/docs/releases/v0.14.4.md +0 -94
- package/docs/releases/v0.15.0.md +0 -502
- package/docs/releases/v0.15.1.md +0 -170
- package/docs/releases/v0.15.3.md +0 -193
- package/docs/specs/bug-039-orphan-processes.md +0 -131
- package/docs/specs/bug-040-review-rectification.md +0 -82
- package/docs/specs/bug-041-cross-story-test-isolation.md +0 -88
- package/docs/specs/bug-042-verifier-failure-capture.md +0 -117
- package/docs/specs/bun-pty-migration.md +0 -171
- package/docs/specs/central-run-registry.md +0 -116
- package/docs/specs/feat-010-smart-runner-git-history.md +0 -96
- package/docs/specs/feat-011-file-context-strategy.md +0 -73
- package/docs/specs/feat-012-tdd-writer-tier.md +0 -79
- package/docs/specs/feat-013-test-after-review.md +0 -89
- package/docs/specs/feat-014-heartbeat-observability.md +0 -127
- package/docs/specs/status-file-consolidation.md +0 -93
- package/docs/specs/status-file-v0.10.1.md +0 -812
- package/docs/specs/trigger-completion.md +0 -145
- package/docs/specs/verification-architecture-v2.md +0 -343
- package/docs/tdd/strategies.md +0 -97
- package/docs/v0.10-global-config.md +0 -206
- package/docs/v0.10-plugin-system.md +0 -415
- package/docs/v0.10-prompt-optimizer.md +0 -234
- package/docs/v0.3-spec.md +0 -244
- package/docs/v0.4-spec.md +0 -140
- package/docs/v0.5-spec.md +0 -237
- package/docs/v0.6-spec.md +0 -371
- package/docs/v0.7-spec.md +0 -177
- package/docs/v0.8-llm-routing.md +0 -206
- package/docs/v0.8-structured-logging.md +0 -132
- package/docs/v0.9.3-prompt-audit.md +0 -112
- package/examples/plugins/console-reporter/index.test.ts +0 -207
- package/examples/plugins/console-reporter/index.ts +0 -110
- package/memory/topic/feat-010-baseref.md +0 -28
- package/memory/topic/feat-013-test-after-deprecation.md +0 -22
- package/nax/config.json +0 -154
- package/nax/features/bug-039-medium/prd.json +0 -45
- package/nax/features/bugfix-v0171/prd.json +0 -52
- package/nax/features/central-run-registry/prd.json +0 -105
- package/nax/features/config-management/prd.json +0 -108
- package/nax/features/config-management/progress.txt +0 -5
- package/nax/features/diagnose/acceptance.test.ts +0 -414
- package/nax/features/diagnose/prd.json +0 -41
- package/nax/features/nax-compliance/prd.json +0 -52
- package/nax/features/nax-compliance/progress.txt +0 -1
- package/nax/features/orchestration-fixes/prd.json +0 -89
- package/nax/features/orchestration-fixes/progress.txt +0 -1
- package/nax/features/plugin-integration/US-007-VERIFICATION.md +0 -259
- package/nax/features/plugin-integration/prd.json +0 -208
- package/nax/features/plugin-integration/progress.txt +0 -5
- package/nax/features/post-rearch-bugfix/prd.json +0 -137
- package/nax/features/precheck/prd.json +0 -205
- package/nax/features/precheck/progress.txt +0 -15
- package/nax/features/prompt-builder/prd.json +0 -152
- package/nax/features/prompt-builder/progress.txt +0 -3
- package/nax/features/review-quality/prd.json +0 -55
- package/nax/features/routing-persistence/prd.json +0 -104
- package/nax/features/routing-persistence/progress.txt +0 -1
- package/nax/features/smart-test-runner/plan.md +0 -7
- package/nax/features/smart-test-runner/prd.json +0 -203
- package/nax/features/smart-test-runner/progress.txt +0 -13
- package/nax/features/smart-test-runner/spec.md +0 -7
- package/nax/features/smart-test-runner/tasks.md +0 -8
- package/nax/features/status-file-consolidation/prd.json +0 -106
- package/nax/features/structured-logging/prd.json +0 -199
- package/nax/features/trigger-completion/prd.json +0 -150
- package/nax/features/trigger-completion/progress.txt +0 -7
- package/nax/features/unlock/prd.json +0 -36
- package/nax/features/v0.18.3-execution-reliability/prd.json +0 -80
- package/nax/features/v0.18.3-execution-reliability/progress.txt +0 -3
- package/nax/features/v0.19.0-hardening/plan.md +0 -7
- package/nax/features/v0.19.0-hardening/prd.json +0 -84
- package/nax/features/v0.19.0-hardening/progress.txt +0 -7
- package/nax/features/v0.19.0-hardening/spec.md +0 -18
- package/nax/features/v0.19.0-hardening/tasks.md +0 -8
- package/nax/features/verify-v2/prd.json +0 -79
- package/nax/features/verify-v2/progress.txt +0 -3
- package/nax/status.json +0 -36
- package/src/prompts/templates/implementer.ts +0 -6
- package/src/prompts/templates/single-session.ts +0 -6
- package/src/prompts/templates/test-writer.ts +0 -6
- package/src/prompts/templates/verifier.ts +0 -6
- package/test/COVERAGE-GAPS.md +0 -333
- package/test/e2e/cm-003-default-view.test.ts +0 -195
- package/test/e2e/plan-analyze-run.test.ts +0 -902
- package/test/helpers/helpers.test.ts +0 -295
- package/test/helpers/timeout.ts +0 -42
- package/test/integration/US-002-TEST-SUMMARY.md +0 -107
- package/test/integration/US-003-TEST-SUMMARY.md +0 -149
- package/test/integration/US-004-TEST-SUMMARY.md +0 -106
- package/test/integration/US-005-TEST-SUMMARY.md +0 -138
- package/test/integration/US-007-TEST-SUMMARY.md +0 -100
- package/test/integration/cli/agent-validation.test.ts +0 -439
- package/test/integration/cli/cli-config-default-edge-cases.test.ts +0 -223
- package/test/integration/cli/cli-config-default-view.test.ts +0 -230
- package/test/integration/cli/cli-config-diff.test.ts +0 -461
- package/test/integration/cli/cli-config-prompts-explain.test.ts +0 -74
- package/test/integration/cli/cli-config.test.ts +0 -737
- package/test/integration/cli/cli-diagnose.test.ts +0 -595
- package/test/integration/cli/cli-logs.test.ts +0 -346
- package/test/integration/cli/cli-plugins.test.ts +0 -679
- package/test/integration/cli/cli-precheck.test.ts +0 -372
- package/test/integration/cli/cli-run-headless.test.ts +0 -174
- package/test/integration/cli/cli.test.ts +0 -76
- package/test/integration/cli/precheck-integration.test.ts +0 -476
- package/test/integration/cli/precheck-orchestrator.test.ts +0 -247
- package/test/integration/cli/precheck.test.ts +0 -806
- package/test/integration/config/config-loader.test.ts +0 -266
- package/test/integration/config/config.test.ts +0 -444
- package/test/integration/config/merger.test.ts +0 -466
- package/test/integration/config/paths.test.ts +0 -52
- package/test/integration/config/security-loader.test.ts +0 -83
- package/test/integration/context/context-integration.test.ts +0 -703
- package/test/integration/context/context-path-security.test.ts +0 -173
- package/test/integration/context/context-provider-injection.test.ts +0 -507
- package/test/integration/context/context-verification-integration.test.ts +0 -296
- package/test/integration/context/s5-greenfield-fallback.test.ts +0 -298
- package/test/integration/execution/execution-isolation.test.ts +0 -143
- package/test/integration/execution/execution.test.ts +0 -634
- package/test/integration/execution/feature-status-write.test.ts +0 -302
- package/test/integration/execution/parallel.test.ts +0 -251
- package/test/integration/execution/prd-pause.test.ts +0 -205
- package/test/integration/execution/prd-resolvers.test.ts +0 -186
- package/test/integration/execution/progress.test.ts +0 -34
- package/test/integration/execution/runner-batching.test.ts +0 -682
- package/test/integration/execution/runner-config-plugins.test.ts +0 -462
- package/test/integration/execution/runner-escalation.test.ts +0 -561
- package/test/integration/execution/runner-fixes.test.ts +0 -400
- package/test/integration/execution/runner-plugin-integration.test.ts +0 -544
- package/test/integration/execution/runner-queue-and-attempts.test.ts +0 -476
- package/test/integration/execution/status-file-integration.test.ts +0 -289
- package/test/integration/execution/status-file.test.ts +0 -380
- package/test/integration/execution/status-writer.test.ts +0 -447
- package/test/integration/execution/story-id-in-events.test.ts +0 -274
- package/test/integration/interaction/interaction-chain-pipeline.test.ts +0 -476
- package/test/integration/pipeline/hooks.test.ts +0 -363
- package/test/integration/pipeline/pipeline-acceptance.test.ts +0 -303
- package/test/integration/pipeline/pipeline-events.test.ts +0 -476
- package/test/integration/pipeline/pipeline.test.ts +0 -660
- package/test/integration/pipeline/reporter-lifecycle.test.ts +0 -862
- package/test/integration/pipeline/verify-stage.test.ts +0 -286
- package/test/integration/plan/analyze-integration.test.ts +0 -262
- package/test/integration/plan/analyze-scanner.test.ts +0 -132
- package/test/integration/plan/logger.test.ts +0 -461
- package/test/integration/plan/plan.test.ts +0 -157
- package/test/integration/plugins/config-integration.test.ts +0 -173
- package/test/integration/plugins/config-resolution.test.ts +0 -523
- package/test/integration/plugins/loader.test.ts +0 -644
- package/test/integration/plugins/plugins-registry.test.ts +0 -747
- package/test/integration/plugins/validator.test.ts +0 -564
- package/test/integration/prompts/pb-004-migration.test.ts +0 -523
- package/test/integration/review/review-config-commands.test.ts +0 -320
- package/test/integration/review/review-config-schema.test.ts +0 -117
- package/test/integration/review/review-plugin-integration.test.ts +0 -729
- package/test/integration/review/review.test.ts +0 -150
- package/test/integration/routing/plugin-routing-advanced.test.ts +0 -461
- package/test/integration/routing/plugin-routing-core.test.ts +0 -527
- package/test/integration/routing/routing-stage-bug-021.test.ts +0 -275
- package/test/integration/routing/routing-stage-greenfield.test.ts +0 -287
- package/test/integration/tdd/tdd-cleanup.test.ts +0 -246
- package/test/integration/tdd/tdd-orchestrator-core.test.ts +0 -565
- package/test/integration/tdd/tdd-orchestrator-failureCategory.test.ts +0 -355
- package/test/integration/tdd/tdd-orchestrator-fallback.test.ts +0 -311
- package/test/integration/tdd/tdd-orchestrator-lite.test.ts +0 -289
- package/test/integration/tdd/tdd-orchestrator-prompts.test.ts +0 -260
- package/test/integration/tdd/tdd-orchestrator-verdict.test.ts +0 -536
- package/test/integration/tmp/headless-test/test.jsonl +0 -30
- package/test/integration/verification/test-scanner.test.ts +0 -403
- package/test/integration/verification/verification-asset-check.test.ts +0 -143
- package/test/integration/worktree/manager.test.ts +0 -218
- package/test/integration/worktree/worktree-merge.test.ts +0 -341
- package/test/manual/logging-formatter-demo.ts +0 -158
- package/test/ui/tui-agent-panel.test.tsx +0 -99
- package/test/ui/tui-pty-integration.test.tsx +0 -146
- package/test/unit/acceptance.test.ts +0 -187
- package/test/unit/agent-stderr-capture.test.ts +0 -147
- package/test/unit/agents/claude.test.ts +0 -107
- package/test/unit/analyze-classifier.test.ts +0 -216
- package/test/unit/analyze.test.ts +0 -224
- package/test/unit/auto-detect.test.ts +0 -250
- package/test/unit/cli-status-project-level.test.ts +0 -283
- package/test/unit/cli-status.test.ts +0 -418
- package/test/unit/commands/common.test.ts +0 -321
- package/test/unit/commands/logs.test.ts +0 -458
- package/test/unit/commands/runs.test.ts +0 -303
- package/test/unit/commands/unlock.test.ts +0 -320
- package/test/unit/config/defaults.test.ts +0 -70
- package/test/unit/config/quality-commands-schema.test.ts +0 -72
- package/test/unit/config/regression-gate-schema.test.ts +0 -160
- package/test/unit/config/smart-runner-flag.test.ts +0 -250
- package/test/unit/constitution-generators.test.ts +0 -161
- package/test/unit/constitution.test.ts +0 -210
- package/test/unit/context/context-autodetect.test.ts +0 -297
- package/test/unit/context/context-build.test.ts +0 -575
- package/test/unit/context/context-coverage.test.ts +0 -236
- package/test/unit/context/context-error.test.ts +0 -93
- package/test/unit/context/context-estimate-tokens.test.ts +0 -201
- package/test/unit/context/context-format.test.ts +0 -302
- package/test/unit/context/context-isolation.test.ts +0 -267
- package/test/unit/context/context-sort.test.ts +0 -93
- package/test/unit/context/context-story.test.ts +0 -108
- package/test/unit/context/prior-failures.test.ts +0 -463
- package/test/unit/context.test.ts +0 -1726
- package/test/unit/cost.test.ts +0 -231
- package/test/unit/crash-recovery.test.ts +0 -309
- package/test/unit/escalation.test.ts +0 -127
- package/test/unit/execution/lifecycle/run-completion.test.ts +0 -240
- package/test/unit/execution/lifecycle/run-regression.test.ts +0 -420
- package/test/unit/execution/pid-registry.test.ts +0 -241
- package/test/unit/execution/sequential-executor.test.ts +0 -235
- package/test/unit/execution/sfc-004-dead-code-cleanup.test.ts +0 -89
- package/test/unit/execution/structured-failure.test.ts +0 -415
- package/test/unit/execution-logging-stderr.test.ts +0 -157
- package/test/unit/execution-stage.test.ts +0 -123
- package/test/unit/fix-generator.test.ts +0 -276
- package/test/unit/formatters.test.ts +0 -468
- package/test/unit/greenfield.test.ts +0 -180
- package/test/unit/hooks/shell-security.test.ts +0 -40
- package/test/unit/interaction/auto-plugin.test.ts +0 -162
- package/test/unit/interaction/human-review-trigger.test.ts +0 -165
- package/test/unit/interaction-network-failures.test.ts +0 -390
- package/test/unit/interaction-plugins.test.ts +0 -472
- package/test/unit/logging/formatter.test.ts +0 -456
- package/test/unit/merge.test.ts +0 -269
- package/test/unit/metrics/aggregator.test.ts +0 -164
- package/test/unit/metrics/tracker.test.ts +0 -186
- package/test/unit/metrics.test.ts +0 -276
- package/test/unit/optimizer/noop.optimizer.test.ts +0 -125
- package/test/unit/optimizer/rule-based.optimizer.test.ts +0 -358
- package/test/unit/pipeline/event-bus.test.ts +0 -105
- package/test/unit/pipeline/routing-partial-override.test.ts +0 -121
- package/test/unit/pipeline/runner-retry.test.ts +0 -89
- package/test/unit/pipeline/stages/autofix.test.ts +0 -97
- package/test/unit/pipeline/stages/completion-review-gate.test.ts +0 -218
- package/test/unit/pipeline/stages/execution-ambiguity.test.ts +0 -311
- package/test/unit/pipeline/stages/execution-merge-conflict.test.ts +0 -218
- package/test/unit/pipeline/stages/rectify.test.ts +0 -101
- package/test/unit/pipeline/stages/regression-stage.test.ts +0 -69
- package/test/unit/pipeline/stages/review.test.ts +0 -201
- package/test/unit/pipeline/stages/routing-idempotence.test.ts +0 -139
- package/test/unit/pipeline/stages/routing-initial-complexity.test.ts +0 -321
- package/test/unit/pipeline/stages/routing-persistence.test.ts +0 -380
- package/test/unit/pipeline/stages/verify.test.ts +0 -267
- package/test/unit/pipeline/subscribers/events-writer.test.ts +0 -227
- package/test/unit/pipeline/subscribers/hooks.test.ts +0 -84
- package/test/unit/pipeline/subscribers/interaction.test.ts +0 -313
- package/test/unit/pipeline/subscribers/registry.test.ts +0 -149
- package/test/unit/pipeline/subscribers/reporters.test.ts +0 -90
- package/test/unit/pipeline/verify-smart-runner.test.ts +0 -345
- package/test/unit/prd-auto-default.test.ts +0 -291
- package/test/unit/prd-failure-category.test.ts +0 -177
- package/test/unit/prd-get-next-story.test.ts +0 -215
- package/test/unit/precheck/checks-warnings.test.ts +0 -114
- package/test/unit/precheck-checks.test.ts +0 -841
- package/test/unit/precheck-story-size-gate.test.ts +0 -288
- package/test/unit/precheck-types.test.ts +0 -143
- package/test/unit/prompts/builder.test.ts +0 -258
- package/test/unit/prompts/loader.test.ts +0 -355
- package/test/unit/prompts/sections/conventions.test.ts +0 -30
- package/test/unit/prompts/sections/isolation.test.ts +0 -35
- package/test/unit/prompts/sections/role-task.test.ts +0 -40
- package/test/unit/prompts/sections/sections.test.ts +0 -238
- package/test/unit/prompts/sections/story.test.ts +0 -45
- package/test/unit/prompts/sections/verdict.test.ts +0 -58
- package/test/unit/prompts.test.ts +0 -476
- package/test/unit/queue.test.ts +0 -237
- package/test/unit/rectification.test.ts +0 -285
- package/test/unit/registry.test.ts +0 -288
- package/test/unit/review/runner.test.ts +0 -117
- package/test/unit/routing/content-hash.test.ts +0 -99
- package/test/unit/routing/routing-stability.test.ts +0 -208
- package/test/unit/routing/strategies/llm.test.ts +0 -306
- package/test/unit/routing-advanced.test.ts +0 -313
- package/test/unit/routing-core.test.ts +0 -341
- package/test/unit/routing-strategies.test.ts +0 -440
- package/test/unit/storyid-events.test.ts +0 -213
- package/test/unit/tdd-verdict.test.ts +0 -492
- package/test/unit/test-output-parser.test.ts +0 -377
- package/test/unit/ui/tui-controls.test.ts +0 -335
- package/test/unit/ui/tui-cost-and-pty.test.ts +0 -190
- package/test/unit/ui/tui-layout.test.ts +0 -379
- package/test/unit/ui/tui-stories.test.ts +0 -333
- package/test/unit/unit-isolation.test.ts +0 -135
- package/test/unit/utils/git.test.ts +0 -50
- package/test/unit/utils/path-security.test.ts +0 -47
- package/test/unit/utils-helpers.test.ts +0 -318
- package/test/unit/verdict.test.ts +0 -325
- package/test/unit/verification/orchestrator-types.test.ts +0 -54
- package/test/unit/verification/orchestrator.test.ts +0 -66
- package/test/unit/verification/smart-runner-config.test.ts +0 -163
- package/test/unit/verification/smart-runner-discovery.test.ts +0 -354
- package/test/unit/verification/smart-runner.test.ts +0 -262
- package/test/unit/verification/strategies/acceptance.test.ts +0 -33
- package/test/unit/verification/strategies/regression.test.ts +0 -87
- package/test/unit/verification/strategies/scoped.test.ts +0 -100
- package/test/unit/worktree-manager.test.ts +0 -159
- package/tsconfig.json +0 -27
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
// Dynamic imports used intentionally: mock.module() in verify-smart-runner.test.ts (which runs
|
|
4
|
-
// before this file alphabetically) poisons the ESM registry. Static imports capture the mock
|
|
5
|
-
// binding at eval time. Dynamic imports inside beforeAll resolve AFTER the other file's afterAll
|
|
6
|
-
// restores the real module, guaranteeing we test the real implementation.
|
|
7
|
-
let buildSmartTestCommand: (testFiles: string[], baseCommand: string) => string;
|
|
8
|
-
let mapSourceToTests: (sourceFiles: string[], workdir: string) => Promise<string[]>;
|
|
9
|
-
let getChangedSourceFiles: (workdir: string) => Promise<string[]>;
|
|
10
|
-
|
|
11
|
-
beforeAll(async () => {
|
|
12
|
-
const mod = await import("../../../src/verification/smart-runner");
|
|
13
|
-
buildSmartTestCommand = mod.buildSmartTestCommand;
|
|
14
|
-
mapSourceToTests = mod.mapSourceToTests;
|
|
15
|
-
getChangedSourceFiles = mod.getChangedSourceFiles;
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// buildSmartTestCommand
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
describe("buildSmartTestCommand", () => {
|
|
23
|
-
test("returns original command when testFiles is empty", () => {
|
|
24
|
-
const result = buildSmartTestCommand([], "bun test test/");
|
|
25
|
-
expect(result).toBe("bun test test/");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("replaces last path argument with specific test file", () => {
|
|
29
|
-
const result = buildSmartTestCommand(["test/unit/foo.test.ts"], "bun test test/");
|
|
30
|
-
expect(result).toBe("bun test test/unit/foo.test.ts");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("joins multiple test files with spaces", () => {
|
|
34
|
-
const result = buildSmartTestCommand(
|
|
35
|
-
["test/unit/foo.test.ts", "test/unit/bar.test.ts"],
|
|
36
|
-
"bun test test/",
|
|
37
|
-
);
|
|
38
|
-
expect(result).toBe("bun test test/unit/foo.test.ts test/unit/bar.test.ts");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test("appends test files when command has no path argument", () => {
|
|
42
|
-
const result = buildSmartTestCommand(["test/unit/foo.test.ts"], "bun test");
|
|
43
|
-
expect(result).toBe("bun test test/unit/foo.test.ts");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test("replaces last path-like token even when flags precede it", () => {
|
|
47
|
-
const result = buildSmartTestCommand(
|
|
48
|
-
["test/unit/foo.test.ts"],
|
|
49
|
-
"bun test --coverage test/",
|
|
50
|
-
);
|
|
51
|
-
expect(result).toBe("bun test --coverage test/unit/foo.test.ts");
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test("preserves trailing flags after path argument (BUG-043)", () => {
|
|
55
|
-
const result = buildSmartTestCommand(
|
|
56
|
-
["test/unit/foo.test.ts"],
|
|
57
|
-
"bun test test/ --timeout=60000",
|
|
58
|
-
);
|
|
59
|
-
expect(result).toBe("bun test test/unit/foo.test.ts --timeout=60000");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("preserves trailing flags with multiple test files", () => {
|
|
63
|
-
const result = buildSmartTestCommand(
|
|
64
|
-
["test/unit/foo.test.ts", "test/unit/bar.test.ts"],
|
|
65
|
-
"bun test test/ --timeout=60000 --bail",
|
|
66
|
-
);
|
|
67
|
-
expect(result).toBe("bun test test/unit/foo.test.ts test/unit/bar.test.ts --timeout=60000 --bail");
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
72
|
-
// Helpers to mock Bun.spawn (used internally via the "bun" import alias)
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
|
|
75
|
-
function makeProc(stdout: string, exitCode: number) {
|
|
76
|
-
return {
|
|
77
|
-
exited: Promise.resolve(exitCode),
|
|
78
|
-
stdout: new ReadableStream({
|
|
79
|
-
start(controller) {
|
|
80
|
-
controller.enqueue(new TextEncoder().encode(stdout));
|
|
81
|
-
controller.close();
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
stderr: new ReadableStream({
|
|
85
|
-
start(controller) {
|
|
86
|
-
controller.close();
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
// mapSourceToTests
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
|
|
96
|
-
describe("mapSourceToTests", () => {
|
|
97
|
-
let originalFile: typeof Bun.file;
|
|
98
|
-
|
|
99
|
-
beforeEach(() => {
|
|
100
|
-
originalFile = Bun.file;
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
afterEach(() => {
|
|
104
|
-
// biome-ignore lint/suspicious/noExplicitAny: restoring original
|
|
105
|
-
(Bun as any).file = originalFile;
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
function mockFileExists(existingPaths: string[]) {
|
|
109
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
110
|
-
(Bun as any).file = (path: string) => ({
|
|
111
|
-
exists: () => Promise.resolve(existingPaths.includes(path)),
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
test("maps src/foo/bar.ts to test/unit/foo/bar.test.ts", async () => {
|
|
116
|
-
mockFileExists(["/repo/test/unit/foo/bar.test.ts"]);
|
|
117
|
-
|
|
118
|
-
const result = await mapSourceToTests(["src/foo/bar.ts"], "/repo");
|
|
119
|
-
|
|
120
|
-
expect(result).toEqual(["/repo/test/unit/foo/bar.test.ts"]);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test("also checks test/integration/ path", async () => {
|
|
124
|
-
mockFileExists(["/repo/test/integration/foo/bar.test.ts"]);
|
|
125
|
-
|
|
126
|
-
const result = await mapSourceToTests(["src/foo/bar.ts"], "/repo");
|
|
127
|
-
|
|
128
|
-
expect(result).toEqual(["/repo/test/integration/foo/bar.test.ts"]);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("returns both unit and integration when both exist", async () => {
|
|
132
|
-
mockFileExists([
|
|
133
|
-
"/repo/test/unit/foo/bar.test.ts",
|
|
134
|
-
"/repo/test/integration/foo/bar.test.ts",
|
|
135
|
-
]);
|
|
136
|
-
|
|
137
|
-
const result = await mapSourceToTests(["src/foo/bar.ts"], "/repo");
|
|
138
|
-
|
|
139
|
-
expect(result).toEqual([
|
|
140
|
-
"/repo/test/unit/foo/bar.test.ts",
|
|
141
|
-
"/repo/test/integration/foo/bar.test.ts",
|
|
142
|
-
]);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
test("only returns files that exist on disk", async () => {
|
|
146
|
-
// Only unit test exists, integration does not
|
|
147
|
-
mockFileExists(["/repo/test/unit/utils/helper.test.ts"]);
|
|
148
|
-
|
|
149
|
-
const result = await mapSourceToTests(["src/utils/helper.ts"], "/repo");
|
|
150
|
-
|
|
151
|
-
expect(result).toEqual(["/repo/test/unit/utils/helper.test.ts"]);
|
|
152
|
-
expect(result).not.toContain("/repo/test/integration/utils/helper.test.ts");
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("returns empty array when no test files match", async () => {
|
|
156
|
-
mockFileExists([]); // nothing exists
|
|
157
|
-
|
|
158
|
-
const result = await mapSourceToTests(["src/foo/bar.ts"], "/repo");
|
|
159
|
-
|
|
160
|
-
expect(result).toEqual([]);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("returns empty array for empty sourceFiles input", async () => {
|
|
164
|
-
mockFileExists(["/repo/test/unit/foo/bar.test.ts"]);
|
|
165
|
-
|
|
166
|
-
const result = await mapSourceToTests([], "/repo");
|
|
167
|
-
|
|
168
|
-
expect(result).toEqual([]);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test("handles multiple source files and aggregates results", async () => {
|
|
172
|
-
mockFileExists([
|
|
173
|
-
"/repo/test/unit/foo/bar.test.ts",
|
|
174
|
-
"/repo/test/unit/baz/qux.test.ts",
|
|
175
|
-
]);
|
|
176
|
-
|
|
177
|
-
const result = await mapSourceToTests(
|
|
178
|
-
["src/foo/bar.ts", "src/baz/qux.ts"],
|
|
179
|
-
"/repo",
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
expect(result).toEqual([
|
|
183
|
-
"/repo/test/unit/foo/bar.test.ts",
|
|
184
|
-
"/repo/test/unit/baz/qux.test.ts",
|
|
185
|
-
]);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
describe("getChangedSourceFiles", () => {
|
|
190
|
-
let originalSpawn: typeof Bun.spawn;
|
|
191
|
-
|
|
192
|
-
beforeEach(() => {
|
|
193
|
-
originalSpawn = Bun.spawn;
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
afterEach(() => {
|
|
197
|
-
// biome-ignore lint/suspicious/noExplicitAny: restoring original
|
|
198
|
-
(Bun as any).spawn = originalSpawn;
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
test("returns only .ts files under src/", async () => {
|
|
202
|
-
const gitOutput = [
|
|
203
|
-
"src/verification/smart-runner.ts",
|
|
204
|
-
"src/utils/git.ts",
|
|
205
|
-
"README.md",
|
|
206
|
-
"src/index.js",
|
|
207
|
-
"test/unit/foo.test.ts",
|
|
208
|
-
"src/config/schema.ts",
|
|
209
|
-
].join("\n");
|
|
210
|
-
|
|
211
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
212
|
-
(Bun as any).spawn = mock(() => makeProc(gitOutput, 0));
|
|
213
|
-
|
|
214
|
-
const result = await getChangedSourceFiles("/fake/repo");
|
|
215
|
-
|
|
216
|
-
expect(result).toEqual([
|
|
217
|
-
"src/verification/smart-runner.ts",
|
|
218
|
-
"src/utils/git.ts",
|
|
219
|
-
"src/config/schema.ts",
|
|
220
|
-
]);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
test("returns empty array when git exits with non-zero code", async () => {
|
|
224
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
225
|
-
(Bun as any).spawn = mock(() => makeProc("", 128));
|
|
226
|
-
|
|
227
|
-
const result = await getChangedSourceFiles("/fake/repo");
|
|
228
|
-
|
|
229
|
-
expect(result).toEqual([]);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
test("returns empty array when git throws (e.g. not a repo)", async () => {
|
|
233
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
234
|
-
(Bun as any).spawn = mock(() => {
|
|
235
|
-
throw new Error("git not found");
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
const result = await getChangedSourceFiles("/fake/repo");
|
|
239
|
-
|
|
240
|
-
expect(result).toEqual([]);
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
test("filters out non-.ts src files", async () => {
|
|
244
|
-
const gitOutput = ["src/foo.js", "src/bar.tsx", "src/baz.ts"].join("\n");
|
|
245
|
-
|
|
246
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
247
|
-
(Bun as any).spawn = mock(() => makeProc(gitOutput, 0));
|
|
248
|
-
|
|
249
|
-
const result = await getChangedSourceFiles("/fake/repo");
|
|
250
|
-
|
|
251
|
-
expect(result).toEqual(["src/baz.ts"]);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
test("returns empty array when no files changed", async () => {
|
|
255
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking
|
|
256
|
-
(Bun as any).spawn = mock(() => makeProc("", 0));
|
|
257
|
-
|
|
258
|
-
const result = await getChangedSourceFiles("/fake/repo");
|
|
259
|
-
|
|
260
|
-
expect(result).toEqual([]);
|
|
261
|
-
});
|
|
262
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
import { describe, expect, test } from "bun:test";
|
|
3
|
-
import { AcceptanceStrategy } from "../../../../src/verification/strategies/acceptance";
|
|
4
|
-
import type { VerifyContext } from "../../../../src/verification/orchestrator-types";
|
|
5
|
-
|
|
6
|
-
function makeCtx(overrides: Partial<VerifyContext> = {}): VerifyContext {
|
|
7
|
-
return {
|
|
8
|
-
workdir: "/tmp/test-repo",
|
|
9
|
-
testCommand: "bun test",
|
|
10
|
-
timeoutSeconds: 60,
|
|
11
|
-
storyId: "US-001",
|
|
12
|
-
...overrides,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
describe("AcceptanceStrategy", () => {
|
|
17
|
-
test("name is acceptance", () => {
|
|
18
|
-
expect(new AcceptanceStrategy().name).toBe("acceptance");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("returns SKIPPED when no acceptanceTestPath", async () => {
|
|
22
|
-
const result = await new AcceptanceStrategy().execute(makeCtx());
|
|
23
|
-
expect(result.status).toBe("SKIPPED");
|
|
24
|
-
expect(result.success).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("returns SKIPPED when test file does not exist", async () => {
|
|
28
|
-
const result = await new AcceptanceStrategy().execute(
|
|
29
|
-
makeCtx({ acceptanceTestPath: "/nonexistent/path/acceptance.test.ts" }),
|
|
30
|
-
);
|
|
31
|
-
expect(result.status).toBe("SKIPPED");
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
import { describe, expect, test } from "bun:test";
|
|
3
|
-
import { RegressionStrategy, _regressionStrategyDeps } from "../../../../src/verification/strategies/regression";
|
|
4
|
-
import type { VerifyContext } from "../../../../src/verification/orchestrator-types";
|
|
5
|
-
import { DEFAULT_CONFIG } from "../../../../src/config";
|
|
6
|
-
|
|
7
|
-
function makeCtx(overrides: Partial<VerifyContext> = {}): VerifyContext {
|
|
8
|
-
return {
|
|
9
|
-
workdir: "/tmp/test-repo",
|
|
10
|
-
testCommand: "bun test",
|
|
11
|
-
timeoutSeconds: 120,
|
|
12
|
-
storyId: "US-001",
|
|
13
|
-
acceptOnTimeout: true,
|
|
14
|
-
config: DEFAULT_CONFIG,
|
|
15
|
-
...overrides,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe("RegressionStrategy", () => {
|
|
20
|
-
test("name is regression", () => {
|
|
21
|
-
expect(new RegressionStrategy().name).toBe("regression");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("returns SKIPPED when gate disabled", async () => {
|
|
25
|
-
const config = {
|
|
26
|
-
...DEFAULT_CONFIG,
|
|
27
|
-
execution: {
|
|
28
|
-
...DEFAULT_CONFIG.execution,
|
|
29
|
-
regressionGate: { enabled: false, timeoutSeconds: 120, mode: "inline" as const },
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
const result = await new RegressionStrategy().execute(makeCtx({ config }));
|
|
33
|
-
expect(result.status).toBe("SKIPPED");
|
|
34
|
-
expect(result.success).toBe(true);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test("returns PASS when tests pass", async () => {
|
|
38
|
-
const saved = { ...(_regressionStrategyDeps as any) };
|
|
39
|
-
_regressionStrategyDeps.runVerification = async () => ({
|
|
40
|
-
success: true,
|
|
41
|
-
status: "SUCCESS" as const,
|
|
42
|
-
countsTowardEscalation: false,
|
|
43
|
-
output: "10 pass",
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const result = await new RegressionStrategy().execute(makeCtx());
|
|
47
|
-
|
|
48
|
-
Object.assign(_regressionStrategyDeps, saved);
|
|
49
|
-
|
|
50
|
-
expect(result.success).toBe(true);
|
|
51
|
-
expect(result.status).toBe("PASS");
|
|
52
|
-
expect(result.strategy).toBe("regression");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("accepts TIMEOUT as pass when acceptOnTimeout=true", async () => {
|
|
56
|
-
const saved = { ...(_regressionStrategyDeps as any) };
|
|
57
|
-
_regressionStrategyDeps.runVerification = async () => ({
|
|
58
|
-
success: false,
|
|
59
|
-
status: "TIMEOUT" as const,
|
|
60
|
-
countsTowardEscalation: false,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const result = await new RegressionStrategy().execute(makeCtx({ acceptOnTimeout: true }));
|
|
64
|
-
|
|
65
|
-
Object.assign(_regressionStrategyDeps, saved);
|
|
66
|
-
|
|
67
|
-
expect(result.success).toBe(true);
|
|
68
|
-
expect(result.status).toBe("PASS");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test("returns TEST_FAILURE when tests fail", async () => {
|
|
72
|
-
const saved = { ...(_regressionStrategyDeps as any) };
|
|
73
|
-
_regressionStrategyDeps.runVerification = async () => ({
|
|
74
|
-
success: false,
|
|
75
|
-
status: "TEST_FAILURE" as const,
|
|
76
|
-
countsTowardEscalation: true,
|
|
77
|
-
output: "(fail) x > y\n2 fail",
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const result = await new RegressionStrategy().execute(makeCtx({ acceptOnTimeout: false }));
|
|
81
|
-
|
|
82
|
-
Object.assign(_regressionStrategyDeps, saved);
|
|
83
|
-
|
|
84
|
-
expect(result.success).toBe(false);
|
|
85
|
-
expect(result.status).toBe("TEST_FAILURE");
|
|
86
|
-
});
|
|
87
|
-
});
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
import { describe, expect, test } from "bun:test";
|
|
3
|
-
import { ScopedStrategy, _scopedDeps } from "../../../../src/verification/strategies/scoped";
|
|
4
|
-
import type { VerifyContext } from "../../../../src/verification/orchestrator-types";
|
|
5
|
-
|
|
6
|
-
function makeCtx(overrides: Partial<VerifyContext> = {}): VerifyContext {
|
|
7
|
-
return {
|
|
8
|
-
workdir: "/tmp/test-repo",
|
|
9
|
-
testCommand: "bun test",
|
|
10
|
-
timeoutSeconds: 60,
|
|
11
|
-
storyId: "US-001",
|
|
12
|
-
storyGitRef: "abc123",
|
|
13
|
-
regressionMode: "deferred",
|
|
14
|
-
acceptOnTimeout: true,
|
|
15
|
-
...overrides,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe("ScopedStrategy", () => {
|
|
20
|
-
test("name is scoped", () => {
|
|
21
|
-
expect(new ScopedStrategy().name).toBe("scoped");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("returns SKIPPED when deferred mode and no mapped tests", async () => {
|
|
25
|
-
const saved = { ..._scopedDeps };
|
|
26
|
-
_scopedDeps.getChangedSourceFiles = async () => [];
|
|
27
|
-
_scopedDeps.mapSourceToTests = async () => [];
|
|
28
|
-
_scopedDeps.importGrepFallback = async () => [];
|
|
29
|
-
|
|
30
|
-
const result = await new ScopedStrategy().execute(makeCtx({ regressionMode: "deferred" }));
|
|
31
|
-
|
|
32
|
-
Object.assign(_scopedDeps, saved);
|
|
33
|
-
|
|
34
|
-
expect(result.status).toBe("SKIPPED");
|
|
35
|
-
expect(result.success).toBe(true);
|
|
36
|
-
expect(result.countsTowardEscalation).toBe(false);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test("runs full suite when inline mode and no mapped tests", async () => {
|
|
40
|
-
const saved = { ..._scopedDeps };
|
|
41
|
-
_scopedDeps.getChangedSourceFiles = async () => [];
|
|
42
|
-
_scopedDeps.mapSourceToTests = async () => [];
|
|
43
|
-
_scopedDeps.importGrepFallback = async () => [];
|
|
44
|
-
_scopedDeps.regression = async () => ({
|
|
45
|
-
success: true,
|
|
46
|
-
status: "SUCCESS" as const,
|
|
47
|
-
countsTowardEscalation: false,
|
|
48
|
-
output: "1 pass",
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const result = await new ScopedStrategy().execute(makeCtx({ regressionMode: "inline" }));
|
|
52
|
-
|
|
53
|
-
Object.assign(_scopedDeps, saved);
|
|
54
|
-
|
|
55
|
-
expect(result.success).toBe(true);
|
|
56
|
-
expect(result.status).toBe("PASS");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test("returns PASS when tests pass", async () => {
|
|
60
|
-
const saved = { ..._scopedDeps };
|
|
61
|
-
_scopedDeps.getChangedSourceFiles = async () => ["src/foo.ts"];
|
|
62
|
-
_scopedDeps.mapSourceToTests = async () => ["test/unit/foo.test.ts"];
|
|
63
|
-
_scopedDeps.buildSmartTestCommand = (_files: string[], cmd: string) => `${cmd} test/unit/foo.test.ts`;
|
|
64
|
-
_scopedDeps.regression = async () => ({
|
|
65
|
-
success: true,
|
|
66
|
-
status: "SUCCESS" as const,
|
|
67
|
-
countsTowardEscalation: false,
|
|
68
|
-
output: "5 pass\n0 fail",
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const result = await new ScopedStrategy().execute(makeCtx());
|
|
72
|
-
|
|
73
|
-
Object.assign(_scopedDeps, saved);
|
|
74
|
-
|
|
75
|
-
expect(result.success).toBe(true);
|
|
76
|
-
expect(result.status).toBe("PASS");
|
|
77
|
-
expect(result.strategy).toBe("scoped");
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test("returns TEST_FAILURE when tests fail", async () => {
|
|
81
|
-
const saved = { ..._scopedDeps };
|
|
82
|
-
_scopedDeps.getChangedSourceFiles = async () => ["src/foo.ts"];
|
|
83
|
-
_scopedDeps.mapSourceToTests = async () => ["test/unit/foo.test.ts"];
|
|
84
|
-
_scopedDeps.buildSmartTestCommand = (_files: string[], cmd: string) => cmd;
|
|
85
|
-
_scopedDeps.regression = async () => ({
|
|
86
|
-
success: false,
|
|
87
|
-
status: "TEST_FAILURE" as const,
|
|
88
|
-
countsTowardEscalation: true,
|
|
89
|
-
output: "(fail) foo > bar\n1 fail",
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
const result = await new ScopedStrategy().execute(makeCtx());
|
|
93
|
-
|
|
94
|
-
Object.assign(_scopedDeps, saved);
|
|
95
|
-
|
|
96
|
-
expect(result.success).toBe(false);
|
|
97
|
-
expect(result.status).toBe("TEST_FAILURE");
|
|
98
|
-
expect(result.countsTowardEscalation).toBe(true);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Tests for src/worktree/manager.ts
|
|
4
|
-
*
|
|
5
|
-
* Covers: WorktreeManager create, remove, list, parseWorktreeList
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { describe, expect, it } from "bun:test";
|
|
9
|
-
import { WorktreeManager } from "../../src/worktree/manager";
|
|
10
|
-
|
|
11
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
12
|
-
// Test fixtures
|
|
13
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
14
|
-
|
|
15
|
-
const mockWorktreeListOutput = `worktree /path/to/project
|
|
16
|
-
HEAD abc123def456
|
|
17
|
-
branch refs/heads/master
|
|
18
|
-
|
|
19
|
-
worktree /path/to/project/.nax-wt/US-001
|
|
20
|
-
HEAD 123456abcdef
|
|
21
|
-
branch refs/heads/nax/US-001
|
|
22
|
-
|
|
23
|
-
worktree /path/to/project/.nax-wt/US-002
|
|
24
|
-
HEAD 789012abcdef
|
|
25
|
-
branch refs/heads/nax/US-002
|
|
26
|
-
|
|
27
|
-
`;
|
|
28
|
-
|
|
29
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
-
// WorktreeManager.parseWorktreeList
|
|
31
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
describe("WorktreeManager.parseWorktreeList", () => {
|
|
34
|
-
it("parses git worktree list --porcelain output", () => {
|
|
35
|
-
const manager = new WorktreeManager();
|
|
36
|
-
// @ts-expect-error - accessing private method for testing
|
|
37
|
-
const worktrees = manager.parseWorktreeList(mockWorktreeListOutput);
|
|
38
|
-
|
|
39
|
-
expect(worktrees.length).toBe(3);
|
|
40
|
-
|
|
41
|
-
expect(worktrees[0].path).toBe("/path/to/project");
|
|
42
|
-
expect(worktrees[0].branch).toBe("master");
|
|
43
|
-
|
|
44
|
-
expect(worktrees[1].path).toBe("/path/to/project/.nax-wt/US-001");
|
|
45
|
-
expect(worktrees[1].branch).toBe("nax/US-001");
|
|
46
|
-
|
|
47
|
-
expect(worktrees[2].path).toBe("/path/to/project/.nax-wt/US-002");
|
|
48
|
-
expect(worktrees[2].branch).toBe("nax/US-002");
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("handles empty output", () => {
|
|
52
|
-
const manager = new WorktreeManager();
|
|
53
|
-
// @ts-expect-error - accessing private method for testing
|
|
54
|
-
const worktrees = manager.parseWorktreeList("");
|
|
55
|
-
|
|
56
|
-
expect(worktrees.length).toBe(0);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("handles single worktree", () => {
|
|
60
|
-
const singleOutput = `worktree /path/to/project
|
|
61
|
-
HEAD abc123def456
|
|
62
|
-
branch refs/heads/master
|
|
63
|
-
|
|
64
|
-
`;
|
|
65
|
-
|
|
66
|
-
const manager = new WorktreeManager();
|
|
67
|
-
// @ts-expect-error - accessing private method for testing
|
|
68
|
-
const worktrees = manager.parseWorktreeList(singleOutput);
|
|
69
|
-
|
|
70
|
-
expect(worktrees.length).toBe(1);
|
|
71
|
-
expect(worktrees[0].path).toBe("/path/to/project");
|
|
72
|
-
expect(worktrees[0].branch).toBe("master");
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("handles output without trailing newline", () => {
|
|
76
|
-
const noTrailingNewline = `worktree /path/to/project
|
|
77
|
-
HEAD abc123def456
|
|
78
|
-
branch refs/heads/master`;
|
|
79
|
-
|
|
80
|
-
const manager = new WorktreeManager();
|
|
81
|
-
// @ts-expect-error - accessing private method for testing
|
|
82
|
-
const worktrees = manager.parseWorktreeList(noTrailingNewline);
|
|
83
|
-
|
|
84
|
-
expect(worktrees.length).toBe(1);
|
|
85
|
-
expect(worktrees[0].path).toBe("/path/to/project");
|
|
86
|
-
expect(worktrees[0].branch).toBe("master");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("strips refs/heads/ prefix from branches", () => {
|
|
90
|
-
const output = `worktree /path/to/project
|
|
91
|
-
branch refs/heads/feature/my-feature
|
|
92
|
-
|
|
93
|
-
`;
|
|
94
|
-
|
|
95
|
-
const manager = new WorktreeManager();
|
|
96
|
-
// @ts-expect-error - accessing private method for testing
|
|
97
|
-
const worktrees = manager.parseWorktreeList(output);
|
|
98
|
-
|
|
99
|
-
expect(worktrees[0].branch).toBe("feature/my-feature");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("handles worktrees with detached HEAD", () => {
|
|
103
|
-
const output = `worktree /path/to/project
|
|
104
|
-
HEAD abc123def456
|
|
105
|
-
|
|
106
|
-
worktree /path/to/project/.nax-wt/US-001
|
|
107
|
-
HEAD 123456abcdef
|
|
108
|
-
branch refs/heads/nax/US-001
|
|
109
|
-
|
|
110
|
-
`;
|
|
111
|
-
|
|
112
|
-
const manager = new WorktreeManager();
|
|
113
|
-
// @ts-expect-error - accessing private method for testing
|
|
114
|
-
const worktrees = manager.parseWorktreeList(output);
|
|
115
|
-
|
|
116
|
-
// First worktree has no branch, should be filtered out
|
|
117
|
-
expect(worktrees.length).toBe(1);
|
|
118
|
-
expect(worktrees[0].branch).toBe("nax/US-001");
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("filters incomplete entries missing path", () => {
|
|
122
|
-
const output = `branch refs/heads/master
|
|
123
|
-
|
|
124
|
-
worktree /path/to/project
|
|
125
|
-
branch refs/heads/feature
|
|
126
|
-
|
|
127
|
-
`;
|
|
128
|
-
|
|
129
|
-
const manager = new WorktreeManager();
|
|
130
|
-
// @ts-expect-error - accessing private method for testing
|
|
131
|
-
const worktrees = manager.parseWorktreeList(output);
|
|
132
|
-
|
|
133
|
-
expect(worktrees.length).toBe(1);
|
|
134
|
-
expect(worktrees[0].path).toBe("/path/to/project");
|
|
135
|
-
expect(worktrees[0].branch).toBe("feature");
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("handles multiple empty lines between entries", () => {
|
|
139
|
-
const output = `worktree /path/to/project
|
|
140
|
-
branch refs/heads/master
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
worktree /path/to/project/.nax-wt/US-001
|
|
144
|
-
branch refs/heads/nax/US-001
|
|
145
|
-
|
|
146
|
-
`;
|
|
147
|
-
|
|
148
|
-
const manager = new WorktreeManager();
|
|
149
|
-
// @ts-expect-error - accessing private method for testing
|
|
150
|
-
const worktrees = manager.parseWorktreeList(output);
|
|
151
|
-
|
|
152
|
-
expect(worktrees.length).toBe(2);
|
|
153
|
-
expect(worktrees[0].branch).toBe("master");
|
|
154
|
-
expect(worktrees[1].branch).toBe("nax/US-001");
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Note: Error handling tests for WorktreeManager require git integration
|
|
159
|
-
// and are better suited for integration tests rather than unit tests
|
package/tsconfig.json
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"lib": ["ESNext"],
|
|
7
|
-
"types": ["bun-types"],
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"declarationMap": true,
|
|
15
|
-
"sourceMap": true,
|
|
16
|
-
"outDir": "./dist",
|
|
17
|
-
"rootDir": ".",
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
"paths": {
|
|
20
|
-
"@/*": ["./src/*"]
|
|
21
|
-
},
|
|
22
|
-
"jsx": "react-jsx",
|
|
23
|
-
"jsxImportSource": "react"
|
|
24
|
-
},
|
|
25
|
-
"include": ["src/**/*.ts", "src/**/*.tsx", "bin/**/*.ts"],
|
|
26
|
-
"exclude": ["node_modules", "dist"]
|
|
27
|
-
}
|