Skip to main content
Glama

AutoDev Codebase MCP Server

by anrgct
scanner.spec.ts5.8 kB
// npx vitest services/code-index/processors/__tests__/scanner.spec.ts import { vi, describe, it, expect, beforeEach } from "vitest" import { DirectoryScanner } from "../scanner" import { stat } from "fs/promises" vi.mock("fs/promises", () => ({ default: { readFile: vi.fn(), writeFile: vi.fn(), mkdir: vi.fn(), access: vi.fn(), rename: vi.fn(), constants: {}, }, stat: vi.fn(), })) // Create a simple mock for vscode since we can't access the real one vi.mock("vscode", () => ({ workspace: { workspaceFolders: [ { uri: { fsPath: "/mock/workspace", }, }, ], getWorkspaceFolder: vi.fn().mockReturnValue({ uri: { fsPath: "/mock/workspace", }, }), fs: { readFile: vi.fn().mockResolvedValue(Buffer.from("test content")), }, }, Uri: { file: vi.fn().mockImplementation((path) => path), }, window: { activeTextEditor: { document: { uri: { fsPath: "/mock/workspace", }, }, }, }, })) vi.mock("../../../../core/ignore/RooIgnoreController") vi.mock("ignore") // Override the Jest-based mock with a vitest-compatible version vi.mock("../../../glob/list-files", () => ({ listFiles: vi.fn(), })) describe("DirectoryScanner", () => { let scanner: DirectoryScanner let mockEmbedder: any let mockVectorStore: any let mockCodeParser: any let mockCacheManager: any let mockIgnoreInstance: any let mockStats: any beforeEach(async () => { mockEmbedder = { createEmbeddings: vi.fn().mockResolvedValue({ embeddings: [[0.1, 0.2, 0.3]] }), embedderInfo: { name: "mock-embedder", dimensions: 384 }, } mockVectorStore = { upsertPoints: vi.fn().mockResolvedValue(undefined), deletePointsByFilePath: vi.fn().mockResolvedValue(undefined), deletePointsByMultipleFilePaths: vi.fn().mockResolvedValue(undefined), initialize: vi.fn().mockResolvedValue(true), search: vi.fn().mockResolvedValue([]), clearCollection: vi.fn().mockResolvedValue(undefined), deleteCollection: vi.fn().mockResolvedValue(undefined), collectionExists: vi.fn().mockResolvedValue(true), } mockCodeParser = { parseFile: vi.fn().mockResolvedValue([]), } mockCacheManager = { getHash: vi.fn().mockReturnValue(undefined), getAllHashes: vi.fn().mockReturnValue({}), updateHash: vi.fn().mockResolvedValue(undefined), deleteHash: vi.fn().mockResolvedValue(undefined), initialize: vi.fn().mockResolvedValue(undefined), clearCacheFile: vi.fn().mockResolvedValue(undefined), } mockIgnoreInstance = { ignores: vi.fn().mockReturnValue(false), } scanner = new DirectoryScanner( mockEmbedder, mockVectorStore, mockCodeParser, mockCacheManager, mockIgnoreInstance, ) // Mock default implementations - create proper Stats object mockStats = { size: 1024, isFile: () => true, isDirectory: () => false, isBlockDevice: () => false, isCharacterDevice: () => false, isSymbolicLink: () => false, isFIFO: () => false, isSocket: () => false, dev: 0, ino: 0, mode: 0, nlink: 0, uid: 0, gid: 0, rdev: 0, blksize: 0, blocks: 0, atimeMs: 0, mtimeMs: 0, ctimeMs: 0, birthtimeMs: 0, atime: new Date(), mtime: new Date(), ctime: new Date(), birthtime: new Date(), atimeNs: BigInt(0), mtimeNs: BigInt(0), ctimeNs: BigInt(0), birthtimeNs: BigInt(0), } vi.mocked(stat).mockResolvedValue(mockStats) // Get and mock the listFiles function const { listFiles } = await import("../../../glob/list-files") vi.mocked(listFiles).mockResolvedValue([["test/file1.js", "test/file2.js"], false]) }) describe("scanDirectory", () => { it("should skip files larger than MAX_FILE_SIZE_BYTES", async () => { const { listFiles } = await import("../../../glob/list-files") vi.mocked(listFiles).mockResolvedValue([["test/file1.js"], false]) // Create large file mock stats const largeFileStats = { ...mockStats, size: 2 * 1024 * 1024, // 2MB > 1MB limit } vi.mocked(stat).mockResolvedValueOnce(largeFileStats) const result = await scanner.scanDirectory("/test") expect(result.stats.skipped).toBe(1) expect(mockCodeParser.parseFile).not.toHaveBeenCalled() }) it("should parse changed files and return code blocks", async () => { const { listFiles } = await import("../../../glob/list-files") vi.mocked(listFiles).mockResolvedValue([["test/file1.js"], false]) const mockBlocks: any[] = [ { file_path: "test/file1.js", content: "test content", start_line: 1, end_line: 5, identifier: "test", type: "function", fileHash: "hash", segmentHash: "segment-hash", }, ] ;(mockCodeParser.parseFile as any).mockResolvedValue(mockBlocks) const result = await scanner.scanDirectory("/test") expect(result.codeBlocks).toEqual(mockBlocks) expect(result.stats.processed).toBe(1) }) it("should process embeddings for new/changed files", async () => { const mockBlocks: any[] = [ { file_path: "test/file1.js", content: "test content", start_line: 1, end_line: 5, identifier: "test", type: "function", fileHash: "hash", segmentHash: "segment-hash", }, ] ;(mockCodeParser.parseFile as any).mockResolvedValue(mockBlocks) await scanner.scanDirectory("/test") expect(mockEmbedder.createEmbeddings).toHaveBeenCalled() expect(mockVectorStore.upsertPoints).toHaveBeenCalled() }) it("should delete points for removed files", async () => { ;(mockCacheManager.getAllHashes as any).mockReturnValue({ "old/file.js": "old-hash" }) await scanner.scanDirectory("/test") expect(mockVectorStore.deletePointsByFilePath).toHaveBeenCalledWith("old/file.js") expect(mockCacheManager.deleteHash).toHaveBeenCalledWith("old/file.js") }) }) })

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/anrgct/autodev-codebase'

If you have feedback or need assistance with the MCP directory API, please join our Discord server