|
| 1 | +# Test Migration Plan: Move CLI Tests to Proper Packages |
| 2 | + |
| 3 | +## Status: PLANNED |
| 4 | + |
| 5 | +## Problem |
| 6 | + |
| 7 | +The CLI package contains 63 test files (1557 pass, 10 fail, 3 skip) but only ~23 of |
| 8 | +those files actually test CLI-specific behavior. The remaining 40 files test SDK, Core, |
| 9 | +or KG functionality and were never moved when those packages were extracted. This creates: |
| 10 | + |
| 11 | +- **False ownership**: Tests live in CLI but test SDK/Core/KG code |
| 12 | +- **Import indirection**: Tests import via `@agents/sdk/...` from a sibling package |
| 13 | +- **Skewed metrics**: CLI appears heavily tested; SDK/Core/KG appear under-tested |
| 14 | +- **Maintenance burden**: Failures in CLI tests may actually be SDK regressions |
| 15 | + |
| 16 | +## Current State (baseline) |
| 17 | + |
| 18 | +| Package | Test files | Pass | Fail | Skip | |
| 19 | +|---------|-----------|------|------|------| |
| 20 | +| Core | 1 | 10 | 0 | 0 | |
| 21 | +| SDK | 23 | 381 | 0 | 1 | |
| 22 | +| KG | 3 | 127 | 0 | 0 | |
| 23 | +| CLI | 63 | 1557 | 10 | 3 | |
| 24 | +| **Total** | **90** | **2075** | **10** | **4** | |
| 25 | + |
| 26 | +## Target State (after migration) |
| 27 | + |
| 28 | +| Package | Test files | Estimated pass | |
| 29 | +|---------|-----------|----------------| |
| 30 | +| Core | 10 | ~19+ | |
| 31 | +| SDK | 51+ | ~1500+ | |
| 32 | +| KG | 5 | ~135+ | |
| 33 | +| CLI | 23 | ~400 | |
| 34 | +| **Total** | **89+** | **2075+** | |
| 35 | + |
| 36 | +Note: One file deleted (`graph-spike.test.ts`), so 90 - 1 = 89, plus any new |
| 37 | +test-utils files created in SDK. |
| 38 | + |
| 39 | +## Classification Summary |
| 40 | + |
| 41 | +| Destination | Count | Files | |
| 42 | +|------------|-------|-------| |
| 43 | +| Move to SDK | 28 (+3 duplicates resolved toward SDK) | catalog-*, skill-*, external-skills-*, manifest, lockfile, schemas, search, output, init-component, registry | |
| 44 | +| Move to Core | 9 | git, github, github-token, hash, uuid, symlink, source-parser, types, file-io | |
| 45 | +| Move to KG | 2 | degradation, kg-commands | |
| 46 | +| Keep in CLI | 23 | agents, prompts, commands/*, component/factory, component/skill-ops-impl, lib/config, mcp, plugin-*, skill-cli-wiring, skill-integration | |
| 47 | +| Delete | 1 | graph-spike.test.ts (exploratory spike, no maintained code) | |
| 48 | + |
| 49 | +## Duplicate Resolution Strategy |
| 50 | + |
| 51 | +Five test files exist in BOTH CLI and SDK. These must be resolved before any moves: |
| 52 | + |
| 53 | +| Test | CLI (lines) | SDK (lines) | Resolution | |
| 54 | +|------|------------|------------|------------| |
| 55 | +| `manager.test.ts` | 535 | 278 | Keep CLI version (more comprehensive), delete SDK `providers/manager.test.ts` | |
| 56 | +| `pagination.test.ts` | 74 | 110 | Keep SDK version (better coverage), delete CLI `component/pagination.test.ts` | |
| 57 | +| `types.test.ts` | 829 | 108 | Keep CLI version (massive), merge unique SDK tests, delete SDK `context/types.test.ts` | |
| 58 | +| `registry.test.ts` | 693 | 72 | Keep CLI version (much larger), delete SDK `context/registry.test.ts` | |
| 59 | +| `github.test.ts` | 149 | 111 | Different scope -- CLI tests `@agents/core/git`, SDK tests GitHub provider. Keep both, move CLI version to Core | |
| 60 | + |
| 61 | +## Complication Handling |
| 62 | + |
| 63 | +### 1. `mock.module()` paths (3 files) |
| 64 | + |
| 65 | +Files using `mock.module()`: |
| 66 | + |
| 67 | +- `skill-outdated.test.ts` -- mocks `@agents/core/git` |
| 68 | +- `skill-update.test.ts` -- mocks `@agents/sdk/providers/local/skill/outdated` and `@agents/sdk/providers/local/skill/add` |
| 69 | +- `external-skills-refactor.test.ts` -- mocks `@agents/core/git` |
| 70 | + |
| 71 | +These already use package-absolute paths (`@agents/core/...`, `@agents/sdk/...`), |
| 72 | +so they will work identically after moving to SDK. No path changes needed in the |
| 73 | +mock.module calls themselves. |
| 74 | + |
| 75 | +### 2. `createCliAgentResolver` dependency (6 files) |
| 76 | + |
| 77 | +Files importing `createCliAgentResolver` from `../src/lib/agents`: |
| 78 | + |
| 79 | +- `skill-filters.test.ts` |
| 80 | +- `skill-info.test.ts` |
| 81 | +- `skill-integration.test.ts` (stays in CLI) |
| 82 | +- `skill-remove.test.ts` |
| 83 | +- `skill-add.test.ts` |
| 84 | +- `skill-list.test.ts` |
| 85 | + |
| 86 | +**Strategy**: Create a `packages/sdk/test/_utils/mock-resolver.ts` that provides a |
| 87 | +test-only AgentResolver implementation. This breaks the cross-package test dependency. |
| 88 | +The mock resolver returns the same default agent paths that `createCliAgentResolver()` |
| 89 | +returns but without importing from CLI. |
| 90 | + |
| 91 | +### 3. `content/` fixture paths (7+ files) |
| 92 | + |
| 93 | +Files that read real `content/skills/`, `content/plugins/` fixtures: |
| 94 | + |
| 95 | +- `manifest.test.ts` -- uses `WORKTREE = resolve(import.meta.dir, '../../..')` |
| 96 | +- `schemas.test.ts` -- uses `REPO_ROOT = resolve(import.meta.dir, '../../..')` |
| 97 | +- `lockfile.test.ts` -- uses `REPO_ROOT = resolve(import.meta.dir, '../../..')` |
| 98 | +- `skill-commands.test.ts` -- uses `WORKTREE = resolve(import.meta.dir, '../../..')` |
| 99 | +- `skill-discovery.test.ts` -- uses `WORKTREE = resolve(import.meta.dir, '../../..')` |
| 100 | +- `kg-commands.test.ts` -- imports `PROJECT_ROOT` from module |
| 101 | + |
| 102 | +**Strategy**: After moving from `packages/cli/test/` to `packages/sdk/test/` (or |
| 103 | +`packages/core/test/`), the depth changes from `../../..` (3 up) to `../../../..` |
| 104 | +(4 up). Update each file's root resolution. |
| 105 | + |
| 106 | +**Better**: Create a shared `packages/sdk/test/_utils/paths.ts` helper: |
| 107 | + |
| 108 | +```ts |
| 109 | +import { resolve } from 'path' |
| 110 | +export const PROJECT_ROOT = resolve(import.meta.dir, '../../../..') |
| 111 | +export const CONTENT_DIR = resolve(PROJECT_ROOT, 'content') |
| 112 | +``` |
| 113 | + |
| 114 | +### 4. `WORKTREE`/`PROJECT_ROOT` constants |
| 115 | + |
| 116 | +Several tests compute project root via `resolve(import.meta.dir, '../../..')`. |
| 117 | +After moving one package level deeper, the depth changes. Each file must be audited. |
| 118 | + |
| 119 | +## Phase Summary |
| 120 | + |
| 121 | +| Phase | Description | Files | Dependencies | |
| 122 | +|-------|------------|-------|-------------| |
| 123 | +| 1 | Resolve duplicates | 5 pairs | None | |
| 124 | +| 2 | Move Core tests | 9 files | Phase 1 | |
| 125 | +| 3 | Move SDK tests | 28 files | Phase 1 | |
| 126 | +| 4 | Move KG tests | 2 files | Phase 1 | |
| 127 | +| 5 | Cleanup and verify | 1 delete + full suite | Phases 2-4 | |
| 128 | + |
| 129 | +Phases 2, 3, and 4 are independent of each other (can be done in any order after |
| 130 | +Phase 1). Phase 5 must be last. |
| 131 | + |
| 132 | +## Global Acceptance Criteria |
| 133 | + |
| 134 | +1. **Zero test regressions**: Total pass count >= 2075 (current total) |
| 135 | +2. **No cross-package test imports**: No test in SDK imports from `@agents/cli/*` |
| 136 | +3. **All 4 suites pass independently**: `bun test packages/<pkg>` works for each |
| 137 | +4. **File counts match target**: CLI has ~23 test files, SDK has ~51+, Core has ~10, KG has ~5 |
| 138 | +5. **No orphaned imports**: Every test file's imports resolve correctly |
| 139 | +6. **Duplicates eliminated**: No test file exists in two packages simultaneously |
| 140 | + |
| 141 | +## Risk Mitigation |
| 142 | + |
| 143 | +- **Run tests after every file move** -- catch import failures immediately |
| 144 | +- **Move in small batches** -- 3-5 files per sub-phase, verify green before continuing |
| 145 | +- **Keep git history** -- use `git mv` so blame/log survives |
| 146 | +- **Fallback**: If a file fails after move, temporarily revert that single file and continue with others |
0 commit comments