|
1 | 1 | import { describe, it, expect, beforeAll } from "vitest"; |
2 | 2 | import { getFixturePipeline } from "./helpers/pipeline.js"; |
3 | 3 | import { setGraph } from "../src/server/graph-store.js"; |
| 4 | +import { createFixtureMcp } from "./helpers/mcp.js"; |
4 | 5 |
|
5 | 6 | beforeAll(() => { |
6 | 7 | const { codebaseGraph } = getFixturePipeline(); |
@@ -71,7 +72,53 @@ describe("2.2 — BM25 empty results return suggestions", () => { |
71 | 72 | }); |
72 | 73 |
|
73 | 74 | describe("2.3 — search MCP tool", () => { |
74 | | - it.todo("search tool returns file-grouped results with symbol locations and nextSteps"); |
| 75 | + it("search tool returns file-grouped results with symbol locations and nextSteps", async () => { |
| 76 | + const { callTool } = await createFixtureMcp(); |
| 77 | + const result = await callTool("search", { query: "auth", limit: 5 }); |
| 78 | + |
| 79 | + expect(result).toHaveProperty("query", "auth"); |
| 80 | + expect(result).toHaveProperty("results"); |
| 81 | + expect(result).toHaveProperty("nextSteps"); |
| 82 | + |
| 83 | + const results = result.results; |
| 84 | + expect(Array.isArray(results)).toBe(true); |
| 85 | + if (!Array.isArray(results)) return; |
| 86 | + expect(results.length).toBeGreaterThan(0); |
| 87 | + |
| 88 | + const files = new Set<string>(); |
| 89 | + const first = results[0]; |
| 90 | + expect(typeof first).toBe("object"); |
| 91 | + expect(first).not.toBeNull(); |
| 92 | + if (typeof first !== "object" || first === null) return; |
| 93 | + expect(first).toHaveProperty("file"); |
| 94 | + expect(first).toHaveProperty("symbols"); |
| 95 | + |
| 96 | + for (const item of results) { |
| 97 | + expect(typeof item).toBe("object"); |
| 98 | + expect(item).not.toBeNull(); |
| 99 | + if (typeof item !== "object" || item === null) continue; |
| 100 | + const file = "file" in item ? item.file : undefined; |
| 101 | + const symbols = "symbols" in item ? item.symbols : undefined; |
| 102 | + expect(typeof file).toBe("string"); |
| 103 | + if (typeof file === "string") files.add(file); |
| 104 | + expect(Array.isArray(symbols)).toBe(true); |
| 105 | + if (!Array.isArray(symbols) || symbols.length === 0) continue; |
| 106 | + const symbol = symbols[0]; |
| 107 | + expect(typeof symbol).toBe("object"); |
| 108 | + expect(symbol).not.toBeNull(); |
| 109 | + if (typeof symbol !== "object" || symbol === null) continue; |
| 110 | + expect(symbol).toHaveProperty("name"); |
| 111 | + expect(symbol).toHaveProperty("type"); |
| 112 | + expect(symbol).toHaveProperty("loc"); |
| 113 | + const loc = "loc" in symbol ? symbol.loc : undefined; |
| 114 | + expect(typeof loc).toBe("number"); |
| 115 | + } |
| 116 | + |
| 117 | + expect(files.size).toBe(results.length); |
| 118 | + const nextSteps = result.nextSteps; |
| 119 | + expect(Array.isArray(nextSteps)).toBe(true); |
| 120 | + if (Array.isArray(nextSteps)) expect(nextSteps.length).toBeGreaterThan(0); |
| 121 | + }); |
75 | 122 | }); |
76 | 123 |
|
77 | 124 | describe("2.6 — existing tools include nextSteps", () => { |
|
0 commit comments