Skip to content

Commit 645fdec

Browse files
prihclaude
andcommitted
fix: update tests to match stripped null/empty fields in MCP responses
- Expect undefined (not null/[]) for completedAt, subtasks, lastUsedAt, dependsOn - Add explicit absence checks for mtime and mimeType - Fix JSON.stringify replacer root-array bug (k !== '' guard) across search/list tools Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d26f1cb commit 645fdec

10 files changed

Lines changed: 14 additions & 14 deletions

File tree

src/api/tools/knowledge/search-notes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function register(server: McpServer, mgr: KnowledgeGraphManager): void {
2626
},
2727
async ({ query, topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode }) => {
2828
const results = await mgr.searchNotes(query, { topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode });
29-
const clean = (_k: string, v: any) => (Array.isArray(v) && v.length === 0 ? undefined : v);
29+
const clean = (k: string, v: any) => (k !== '' && Array.isArray(v) && v.length === 0 ? undefined : v);
3030
return { content: [{ type: 'text', text: JSON.stringify(results, clean, 2) }] };
3131
},
3232
);

src/api/tools/skills/list-skills.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function register(server: McpServer, mgr: SkillGraphManager): void {
2020
},
2121
async ({ source, tag, filter, limit }) => {
2222
const results = mgr.listSkills({ source, tag, filter, limit });
23-
const clean = (_k: string, v: any) => (v === null || (Array.isArray(v) && v.length === 0) ? undefined : v);
23+
const clean = (k: string, v: any) => (k !== '' && (v === null || (Array.isArray(v) && v.length === 0)) ? undefined : v);
2424
const output = results.map(({ version: _, ...r }) => r);
2525
return { content: [{ type: 'text', text: JSON.stringify(output, clean, 2) }] };
2626
},

src/api/tools/skills/recall-skills.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function register(server: McpServer, mgr: SkillGraphManager): void {
1919
},
2020
async ({ context, topK, minScore, searchMode }) => {
2121
const results = await mgr.searchSkills(context, { topK, minScore: minScore ?? 0.3, searchMode });
22-
const clean = (_k: string, v: any) => (Array.isArray(v) && v.length === 0 ? undefined : v);
22+
const clean = (k: string, v: any) => (k !== '' && Array.isArray(v) && v.length === 0 ? undefined : v);
2323
return { content: [{ type: 'text', text: JSON.stringify(results, clean, 2) }] };
2424
},
2525
);

src/api/tools/skills/search-skills.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function register(server: McpServer, mgr: SkillGraphManager): void {
2626
},
2727
async ({ query, topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode }) => {
2828
const results = await mgr.searchSkills(query, { topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode });
29-
const clean = (_k: string, v: any) => (Array.isArray(v) && v.length === 0 ? undefined : v);
29+
const clean = (k: string, v: any) => (k !== '' && Array.isArray(v) && v.length === 0 ? undefined : v);
3030
return { content: [{ type: 'text', text: JSON.stringify(results, clean, 2) }] };
3131
},
3232
);

src/api/tools/tasks/list-tasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function register(server: McpServer, mgr: TaskGraphManager): void {
2525
},
2626
async ({ status, priority, tag, filter, assignee, limit }) => {
2727
const results = mgr.listTasks({ status, priority, tag, filter, assignee, limit });
28-
const clean = (_k: string, v: any) => (v === null || (Array.isArray(v) && v.length === 0) ? undefined : v);
28+
const clean = (k: string, v: any) => (k !== '' && (v === null || (Array.isArray(v) && v.length === 0)) ? undefined : v);
2929
const output = results.map(({ version: _, ...r }) => r);
3030
return { content: [{ type: 'text', text: JSON.stringify(output, clean, 2) }] };
3131
},

src/api/tools/tasks/search-tasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function register(server: McpServer, mgr: TaskGraphManager): void {
2626
},
2727
async ({ query, topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode }) => {
2828
const results = await mgr.searchTasks(query, { topK, bfsDepth, maxResults, minScore, bfsDecay, searchMode });
29-
const clean = (_k: string, v: any) => (Array.isArray(v) && v.length === 0 ? undefined : v);
29+
const clean = (k: string, v: any) => (k !== '' && Array.isArray(v) && v.length === 0 ? undefined : v);
3030
return { content: [{ type: 'text', text: JSON.stringify(results, clean, 2) }] };
3131
},
3232
);

src/tests/mcp-docs.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ describe('MCP docs tools', () => {
348348
expect(typeof node.content).toBe('string');
349349
expect(node.content.length).toBeGreaterThan(0);
350350
expect(node.level).toBe(1);
351-
expect(node.mtime).toBe(DOC_MTIME);
351+
expect('mtime' in node).toBe(false);
352352
expect('embedding' in node).toBe(false);
353353
});
354354

src/tests/mcp-file-index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ describe('files_get_info', () => {
177177
expect(info.fileName).toBe('config.ts');
178178
expect(info.extension).toBe('.ts');
179179
expect(info.language).toBe('typescript');
180-
expect(info.mimeType).toBe('text/typescript');
180+
expect('mimeType' in info).toBe(false);
181181
expect(info.size).toBe(1024);
182182
expect(info.directory).toBe('src/lib');
183183
});

src/tests/mcp-skills.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ describe('MCP Skill Tools', () => {
154154
expect(skill.source).toBe('user');
155155
expect(skill.confidence).toBe(1);
156156
expect(skill.usageCount).toBe(0);
157-
expect(skill.lastUsedAt).toBeNull();
158-
expect(skill.dependsOn).toHaveLength(0);
157+
expect(skill.lastUsedAt).toBeUndefined();
158+
expect(skill.dependsOn).toBeUndefined();
159159
});
160160

161161
it('skills_get returns error for missing', async () => {

src/tests/mcp-tasks.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ describe('Task CRUD tools', () => {
125125
expect(task.status).toBe('backlog');
126126
expect(task.priority).toBe('high');
127127
expect(task.tags).toEqual(['bug', 'auth']);
128-
expect(task.subtasks).toHaveLength(0);
128+
expect(task.subtasks).toBeUndefined();
129129
});
130130

131131
it('get_task returns error for missing', async () => {
@@ -159,7 +159,7 @@ describe('Task CRUD tools', () => {
159159
await call('tasks_update', { taskId: 'fix-auth-redirect', status: 'todo' });
160160
const task = json<TaskResult>(await call('tasks_get', { taskId: 'fix-auth-redirect' }));
161161
expect(task.status).toBe('todo');
162-
expect(task.completedAt).toBeNull();
162+
expect(task.completedAt).toBeUndefined();
163163
});
164164

165165
// -- tasks_move --
@@ -170,7 +170,7 @@ describe('Task CRUD tools', () => {
170170
status: 'in_progress',
171171
}));
172172
expect(res.status).toBe('in_progress');
173-
expect(res.completedAt).toBeNull();
173+
expect(res.completedAt).toBeUndefined();
174174
});
175175

176176
it('move_task to done sets completedAt', async () => {
@@ -187,7 +187,7 @@ describe('Task CRUD tools', () => {
187187
taskId: 'add-search-feature',
188188
status: 'todo',
189189
}));
190-
expect(res.completedAt).toBeNull();
190+
expect(res.completedAt).toBeUndefined();
191191
});
192192

193193
// -- tasks_list --

0 commit comments

Comments
 (0)