Skip to content

Commit 2ca5697

Browse files
Merge pull request #30 from claude-code-best/test/test-most-core-func
Test/test most core func
2 parents 3b0a5e4 + 717cc55 commit 2ca5697

40 files changed

Lines changed: 6128 additions & 9 deletions

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Claude Code Best V3 (CCB)
22

3-
牢 A (Anthropic) 官方 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI 工具的源码反编译/逆向还原项目。目标是将 Claude Code 大部分功能及工程化能力复现。虽然很难绷, 但是它叫做 CCB(踩踩背)...
3+
牢 A (Anthropic) 官方 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI 工具的源码反编译/逆向还原项目。目标是将 Claude Code 大部分功能及工程化能力复现 (问就是老佛爷已经付过钱了)。虽然很难绷, 但是它叫做 CCB(踩踩背)...
44

55
[文档在这里, 支持投稿 PR](https://ccb.agent-aura.top/)
66

@@ -12,21 +12,22 @@
1212
- [x] 构建流水线完成, 产物 Node/Bun 都可以运行
1313
- [x] V3 会写大量文档, 完善文档站点
1414
- [ ] V4 会完成大量的测试文件, 以提高稳定性
15+
- [ ] V5 大规模重构石山代码, 全面模块分包
16+
- [ ] V5 将会为全新分支, 届时 main 分支将会封存为历史版本
1517

16-
> 我不知道这个项目还会存在多久, Star + Fork + git clone + .zip 包最稳健;
18+
> 我不知道这个项目还会存在多久, Star + Fork + git clone + .zip 包最稳健; 说白了就是扛旗项目, 看看能走多远
1719
>
18-
> 这个项目更新很快, 后台有 Opus 持续优化, 所以你可以提 issues, 但是 PR 暂时不会接受;
20+
> 这个项目更新很快, 后台有 Opus 持续优化, 几乎几个小时就有新变化;
1921
>
20-
> Claude 已经烧了 800$ 以上, 如果你个人想赞助, 请随便找个机构捐款, 然后截图在 issues, 大家的力量是温暖的;
22+
> Claude 已经烧了 1000$ 以上, 继续玩;
2123
>
22-
> 某些模型提供商想要赞助, 那么请私发一个 1w 额度以上的账号到 <claude-code-best@proton.me>; 我们会在赞助商栏直接给你最亮的位置
2324
2425
存活记录:
2526

26-
1. 开源后 24 小时: 突破 6k Star, 感谢各位支持. 完成 docs 文档的站点构建, 达到 v3 版本, 后续开始进行测试用例维护, 完成之后可以接受 PR; 看来牢 A 是不想理我们了;
27-
2. 开源后 15 小时: 完成了构建产物的 node 支持, 现在是完全体了; star 快到 3k 了; 等待牢 A 的邮件
28-
3. 开源后 12 小时: 愚人节, star 破 1k, 并且牢 A 没有发邮件搞这个项目
29-
4. 如果你想要私人咨询服务, 那么可以发送邮件到 <claude-code-best@proton.me>, 备注咨询与联系方式即可; 由于后续工作非常多, 可能会忽略邮件, 半天没回复, 可以多发;
27+
1. 开源后 48 小时: 突破 7k Star; 测试代码小有成效;
28+
2. 开源后 24 小时: 突破 6k Star, 感谢各位支持. 完成 docs 文档的站点构建, 达到 v3 版本, 后续开始进行测试用例维护, 完成之后可以接受 PR; 看来牢 A 是不想理我们了;
29+
3. 开源后 15 小时: 完成了构建产物的 node 支持, 现在是完全体了; star 快到 3k 了; 等待牢 A 的邮件
30+
4. 开源后 12 小时: 愚人节, star 破 1k, 并且牢 A 没有发邮件搞这个项目
3031

3132
## 快速开始
3233

docs/test-plans/01-tool-system.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Tool 系统测试计划
2+
3+
## 概述
4+
5+
Tool 系统是 Claude Code 的核心,负责工具的定义、注册、发现和过滤。本计划覆盖 `src/Tool.ts` 中的工具接口与工具函数、`src/tools.ts` 中的注册/过滤逻辑,以及各工具目录下可独立测试的纯函数。
6+
7+
## 被测文件
8+
9+
| 文件 | 关键导出 |
10+
|------|----------|
11+
| `src/Tool.ts` | `buildTool`, `toolMatchesName`, `findToolByName`, `getEmptyToolPermissionContext`, `filterToolProgressMessages` |
12+
| `src/tools.ts` | `parseToolPreset`, `filterToolsByDenyRules`, `getAllBaseTools`, `getTools`, `assembleToolPool` |
13+
| `src/tools/shared/gitOperationTracking.ts` | `parseGitCommitId`, `detectGitOperation` |
14+
| `src/tools/shared/spawnMultiAgent.ts` | `resolveTeammateModel`, `generateUniqueTeammateName` |
15+
| `src/tools/GrepTool/GrepTool.ts` | `applyHeadLimit`, `formatLimitInfo`(内部辅助函数) |
16+
| `src/tools/FileEditTool/utils.ts` | 字符串匹配/补丁相关纯函数 |
17+
18+
---
19+
20+
## 测试用例
21+
22+
### src/Tool.ts
23+
24+
#### describe('buildTool')
25+
26+
- test('fills in default isEnabled as true') — 不传 isEnabled 时,构建的 tool.isEnabled() 应返回 true
27+
- test('fills in default isConcurrencySafe as false') — 默认值应为 false(fail-closed)
28+
- test('fills in default isReadOnly as false') — 默认假设有写操作
29+
- test('fills in default isDestructive as false') — 默认非破坏性
30+
- test('fills in default checkPermissions as allow') — 默认 checkPermissions 应返回 `{ behavior: 'allow', updatedInput }`
31+
- test('fills in default userFacingName from tool name') — userFacingName 默认应返回 tool.name
32+
- test('preserves explicitly provided methods') — 传入自定义 isEnabled 等方法时应覆盖默认值
33+
- test('preserves all non-defaultable properties') — name, inputSchema, call, description 等属性原样保留
34+
35+
#### describe('toolMatchesName')
36+
37+
- test('returns true for exact name match') — `{ name: 'Bash' }` 匹配 'Bash'
38+
- test('returns false for non-matching name') — `{ name: 'Bash' }` 不匹配 'Read'
39+
- test('returns true when name matches an alias') — `{ name: 'Bash', aliases: ['BashTool'] }` 匹配 'BashTool'
40+
- test('returns false when aliases is undefined') — `{ name: 'Bash' }` 不匹配 'BashTool'
41+
- test('returns false when aliases is empty') — `{ name: 'Bash', aliases: [] }` 不匹配 'BashTool'
42+
43+
#### describe('findToolByName')
44+
45+
- test('finds tool by primary name') — 从 tools 列表中按 name 找到工具
46+
- test('finds tool by alias') — 从 tools 列表中按 alias 找到工具
47+
- test('returns undefined when no match') — 找不到时返回 undefined
48+
- test('returns first match when duplicates exist') — 多个同名工具时返回第一个
49+
50+
#### describe('getEmptyToolPermissionContext')
51+
52+
- test('returns default permission mode') — mode 应为 'default'
53+
- test('returns empty maps and arrays') — additionalWorkingDirectories 为空 Map,rules 为空对象
54+
- test('returns isBypassPermissionsModeAvailable as false')
55+
56+
#### describe('filterToolProgressMessages')
57+
58+
- test('filters out hook_progress messages') — 移除 type 为 hook_progress 的消息
59+
- test('keeps tool progress messages') — 保留非 hook_progress 的消息
60+
- test('returns empty array for empty input')
61+
- test('handles messages without type field') — data 不含 type 时应保留
62+
63+
---
64+
65+
### src/tools.ts
66+
67+
#### describe('parseToolPreset')
68+
69+
- test('returns "default" for "default" input') — 精确匹配
70+
- test('returns "default" for "Default" input') — 大小写不敏感
71+
- test('returns null for unknown preset') — 未知字符串返回 null
72+
- test('returns null for empty string')
73+
74+
#### describe('filterToolsByDenyRules')
75+
76+
- test('returns all tools when no deny rules') — 空 deny 规则不过滤任何工具
77+
- test('filters out tools matching blanket deny rule') — deny rule `{ toolName: 'Bash' }` 应移除 Bash
78+
- test('does not filter tools with content-specific deny rules') — deny rule `{ toolName: 'Bash', ruleContent: 'rm -rf' }` 不移除 Bash(只在运行时阻止特定命令)
79+
- test('filters MCP tools by server name prefix') — deny rule `mcp__server` 应移除该 server 下所有工具
80+
- test('preserves tools not matching any deny rule')
81+
82+
#### describe('getAllBaseTools')
83+
84+
- test('returns a non-empty array of tools') — 至少包含核心工具
85+
- test('each tool has required properties') — 每个工具应有 name, inputSchema, call 等属性
86+
- test('includes BashTool, FileReadTool, FileEditTool') — 核心工具始终存在
87+
- test('includes TestingPermissionTool when NODE_ENV is test') — 需设置 env
88+
89+
#### describe('getTools')
90+
91+
- test('returns filtered tools based on permission context') — 根据 deny rules 过滤
92+
- test('returns simple tools in CLAUDE_CODE_SIMPLE mode') — 仅返回 Bash/Read/Edit
93+
- test('filters disabled tools via isEnabled') — isEnabled 返回 false 的工具被排除
94+
95+
---
96+
97+
### src/tools/shared/gitOperationTracking.ts
98+
99+
#### describe('parseGitCommitId')
100+
101+
- test('extracts commit hash from git commit output') — 从 `[main abc1234] message` 中提取 `abc1234`
102+
- test('returns null for non-commit output') — 无法解析时返回 null
103+
- test('handles various branch name formats') — `[feature/foo abc1234]`
104+
105+
#### describe('detectGitOperation')
106+
107+
- test('detects git commit operation') — 命令含 `git commit` 时识别为 commit
108+
- test('detects git push operation') — 命令含 `git push` 时识别
109+
- test('returns null for non-git commands') — 非 git 命令返回 null
110+
- test('detects git merge operation')
111+
- test('detects git rebase operation')
112+
113+
---
114+
115+
### src/tools/shared/spawnMultiAgent.ts
116+
117+
#### describe('resolveTeammateModel')
118+
119+
- test('returns specified model when provided')
120+
- test('falls back to default model when not specified')
121+
122+
#### describe('generateUniqueTeammateName')
123+
124+
- test('generates a name when no existing names') — 无冲突时返回基础名
125+
- test('appends suffix when name conflicts') — 与已有名称冲突时添加后缀
126+
- test('handles multiple conflicts') — 多次冲突时递增后缀
127+
128+
---
129+
130+
## Mock 需求
131+
132+
| 依赖 | Mock 方式 | 说明 |
133+
|------|-----------|------|
134+
| `bun:bundle` (feature) | 已 polyfill 为 `() => false` | 不需额外 mock |
135+
| `process.env` | `bun:test` mock | 测试 `USER_TYPE``NODE_ENV``CLAUDE_CODE_SIMPLE` |
136+
| `getDenyRuleForTool` | mock module | `filterToolsByDenyRules` 测试中需控制返回值 |
137+
| `isToolSearchEnabledOptimistic` | mock module | `getAllBaseTools` 中条件加载 |
138+
139+
## 集成测试场景
140+
141+
放在 `tests/integration/tool-chain.test.ts`
142+
143+
### describe('Tool registration and discovery')
144+
145+
- test('getAllBaseTools returns tools that can be found by findToolByName') — 注册 → 查找完整链路
146+
- test('filterToolsByDenyRules + getTools produces consistent results') — 过滤管线一致性
147+
- test('assembleToolPool deduplicates built-in and MCP tools') — 合并去重逻辑

0 commit comments

Comments
 (0)