5.8 KiB
5.8 KiB
Context 构建测试计划
概述
Context 构建系统负责组装发送给 Claude API 的系统提示和用户上下文。包括 git 状态获取、CLAUDE.md 文件发现与加载、系统提示拼装三部分。
被测文件
| 文件 | 关键导出 |
|---|---|
src/context.ts |
getSystemContext, getUserContext, getGitStatus, setSystemPromptInjection |
src/utils/claudemd.ts |
stripHtmlComments, getClaudeMds, isMemoryFilePath, getLargeMemoryFiles, filterInjectedMemoryFiles, getExternalClaudeMdIncludes, hasExternalClaudeMdIncludes, processMemoryFile, getMemoryFiles |
src/utils/systemPrompt.ts |
buildEffectiveSystemPrompt |
测试用例
src/utils/claudemd.ts — 纯函数部分
describe('stripHtmlComments')
- test('strips block-level HTML comments') —
"text <!-- comment --> more"→ content 不含注释 - test('preserves inline content') — 行内文本保留
- test('preserves code block content') —
```html\n<!-- not stripped -->\n```内的注释不移除 - test('returns stripped: false when no comments') — 无注释时 stripped 为 false
- test('returns stripped: true when comments exist')
- test('handles empty string') —
""→{ content: "", stripped: false } - test('handles multiple comments') — 多个注释全部移除
describe('getClaudeMds')
- test('assembles memory files with type descriptions') — 不同 type 的文件有不同前缀描述
- test('includes instruction prompt prefix') — 输出包含指令前缀
- test('handles empty memory files array') — 空数组返回空字符串或最小前缀
- test('respects filter parameter') — filter 函数可过滤特定类型
- test('concatenates multiple files with separators')
describe('isMemoryFilePath')
- test('returns true for CLAUDE.md path') —
"/project/CLAUDE.md"→ true - test('returns true for .claude/rules/ path') —
"/project/.claude/rules/foo.md"→ true - test('returns true for memory file path') —
"~/.claude/memory/foo.md"→ true - test('returns false for regular file') —
"/project/src/main.ts"→ false - test('returns false for unrelated .md file') —
"/project/README.md"→ false
describe('getLargeMemoryFiles')
- test('returns files exceeding 40K chars') — 内容 > MAX_MEMORY_CHARACTER_COUNT 的文件被返回
- test('returns empty array when all files are small')
- test('correctly identifies threshold boundary')
describe('filterInjectedMemoryFiles')
- test('filters out AutoMem type files') — feature flag 开启时移除自动记忆
- test('filters out TeamMem type files')
- test('preserves other types') — 非 AutoMem/TeamMem 的文件保留
describe('getExternalClaudeMdIncludes')
- test('returns includes from outside CWD') — 外部 @include 路径被识别
- test('returns empty array when all includes are internal')
describe('hasExternalClaudeMdIncludes')
- test('returns true when external includes exist')
- test('returns false when no external includes')
src/utils/systemPrompt.ts
describe('buildEffectiveSystemPrompt')
- test('returns default system prompt when no overrides') — 无任何覆盖时使用默认提示
- test('overrideSystemPrompt replaces everything') — override 模式替换全部内容
- test('customSystemPrompt replaces default') —
--system-prompt参数替换默认 - test('appendSystemPrompt is appended after main prompt') — append 在主提示之后
- test('agent definition replaces default prompt') — agent 模式使用 agent prompt
- test('agent definition with append combines both') — agent prompt + append
- test('override takes precedence over agent and custom') — 优先级最高
- test('returns array of strings') — 返回值为 SystemPrompt 类型(字符串数组)
src/context.ts — 需 Mock 的部分
describe('getGitStatus')
- test('returns formatted git status string') — 包含 branch、status、log、user
- test('truncates status at 2000 chars') — 超长 status 被截断
- test('returns null in test environment') —
NODE_ENV=test时返回 null - test('returns null in non-git directory') — 非 git 仓库返回 null
- test('runs git commands in parallel') — 多个 git 命令并行执行
describe('getSystemContext')
- test('includes gitStatus key') — 返回对象包含 gitStatus
- test('returns memoized result on subsequent calls') — 多次调用返回同一结果
- test('skips git when instructions disabled')
describe('getUserContext')
- test('includes currentDate key') — 返回对象包含当前日期
- test('includes claudeMd key when CLAUDE.md exists') — 加载 CLAUDE.md 内容
- test('respects CLAUDE_CODE_DISABLE_CLAUDE_MDS env') — 设置后不加载 CLAUDE.md
- test('returns memoized result')
describe('setSystemPromptInjection')
- test('clears memoized context caches') — 调用后下次 getSystemContext/getUserContext 重新计算
- test('injection value is accessible via getSystemPromptInjection')
Mock 需求
| 依赖 | Mock 方式 | 用途 |
|---|---|---|
execFileNoThrow |
mock.module |
getGitStatus 中的 git 命令 |
getMemoryFiles |
mock.module |
getUserContext 中的 CLAUDE.md 加载 |
getCwd |
mock.module |
路径解析上下文 |
process.env.NODE_ENV |
直接设置 | 测试环境检测 |
process.env.CLAUDE_CODE_DISABLE_CLAUDE_MDS |
直接设置 | 禁用 CLAUDE.md |
集成测试场景
放在 tests/integration/context-build.test.ts:
describe('Context assembly pipeline')
- test('getUserContext produces claudeMd containing CLAUDE.md content') — 端到端验证 CLAUDE.md 被正确加载到 context
- test('buildEffectiveSystemPrompt + getUserContext produces complete prompt') — 系统提示 + 用户上下文完整性
- test('setSystemPromptInjection invalidates and rebuilds context') — 注入后重新构建上下文