Skip to main content
Glama

AutoDev Codebase MCP Server

by anrgct
cache-manager.spec.ts5.56 kB
import { vitest, describe, it, expect, beforeEach } from "vitest" import type { Mock } from "vitest" import { createHash } from "crypto" import debounce from "lodash.debounce" import { CacheManager } from "../cache-manager" import { IFileSystem, IStorage } from "../../abstractions" // Mock debounce to execute immediately vitest.mock("lodash.debounce", () => ({ default: vitest.fn((fn) => fn) })) describe("CacheManager", () => { let mockFileSystem: IFileSystem let mockStorage: IStorage let mockWorkspacePath: string let mockCachePath: string let cacheManager: CacheManager beforeEach(() => { // Reset all mocks vitest.clearAllMocks() // Mock workspace path and cache path mockWorkspacePath = "/mock/workspace" mockCachePath = "/mock/storage/roo-index-cache-hash.json" // Mock file system mockFileSystem = { readFile: vitest.fn(), writeFile: vitest.fn(), exists: vitest.fn(), stat: vitest.fn(), readdir: vitest.fn(), mkdir: vitest.fn(), delete: vitest.fn(), } // Mock storage mockStorage = { getGlobalStorageUri: vitest.fn().mockReturnValue("/mock/storage"), createCachePath: vitest.fn().mockReturnValue(mockCachePath), getCacheBasePath: vitest.fn().mockReturnValue("/mock/storage"), } // Create cache manager instance cacheManager = new CacheManager(mockFileSystem, mockStorage, mockWorkspacePath) }) describe("constructor", () => { it("should correctly set up cachePath using storage.createCachePath and crypto.createHash", () => { const expectedHash = createHash("sha256").update(mockWorkspacePath).digest("hex") expect(mockStorage.createCachePath).toHaveBeenCalledWith( `roo-index-cache-${expectedHash}.json`, ) }) it("should set up debounced save function", () => { expect(debounce).toHaveBeenCalledWith(expect.any(Function), 1500) }) }) describe("initialize", () => { it("should load existing cache file successfully", async () => { const mockCache = { "file1.ts": "hash1", "file2.ts": "hash2" } const mockBuffer = new TextEncoder().encode(JSON.stringify(mockCache)) ;(mockFileSystem.readFile as Mock).mockResolvedValue(mockBuffer) await cacheManager.initialize() expect(mockFileSystem.readFile).toHaveBeenCalledWith(mockCachePath) expect(cacheManager.getAllHashes()).toEqual(mockCache) }) it("should handle missing cache file by creating empty cache", async () => { ;(mockFileSystem.readFile as Mock).mockRejectedValue(new Error("File not found")) await cacheManager.initialize() expect(cacheManager.getAllHashes()).toEqual({}) }) }) describe("hash management", () => { it("should update hash and trigger save", () => { const filePath = "test.ts" const hash = "testhash" cacheManager.updateHash(filePath, hash) expect(cacheManager.getHash(filePath)).toBe(hash) expect(mockFileSystem.writeFile).toHaveBeenCalled() }) it("should delete hash and trigger save", () => { const filePath = "test.ts" const hash = "testhash" cacheManager.updateHash(filePath, hash) cacheManager.deleteHash(filePath) expect(cacheManager.getHash(filePath)).toBeUndefined() expect(mockFileSystem.writeFile).toHaveBeenCalled() }) it("should return shallow copy of hashes", () => { const filePath = "test.ts" const hash = "testhash" cacheManager.updateHash(filePath, hash) const hashes = cacheManager.getAllHashes() // Modify the returned object hashes[filePath] = "modified" // Original should remain unchanged expect(cacheManager.getHash(filePath)).toBe(hash) }) }) describe("saving", () => { it("should save cache to disk with correct data", async () => { const filePath = "test.ts" const hash = "testhash" cacheManager.updateHash(filePath, hash) expect(mockFileSystem.writeFile).toHaveBeenCalledWith(mockCachePath, expect.any(Uint8Array)) // Verify the saved data const savedData = JSON.parse( new TextDecoder().decode((mockFileSystem.writeFile as Mock).mock.calls[0][1]), ) expect(savedData).toEqual({ [filePath]: hash }) }) it("should handle save errors gracefully", async () => { const consoleErrorSpy = vitest.spyOn(console, "error").mockImplementation(() => {}) ;(mockFileSystem.writeFile as Mock).mockRejectedValue(new Error("Save failed")) cacheManager.updateHash("test.ts", "hash") // Wait for any pending promises await new Promise((resolve) => setTimeout(resolve, 0)) expect(consoleErrorSpy).toHaveBeenCalledWith("Failed to save cache:", expect.any(Error)) consoleErrorSpy.mockRestore() }) }) describe("clearCacheFile", () => { it("should clear cache file and reset state", async () => { cacheManager.updateHash("test.ts", "hash") // Reset the mock to ensure writeFile succeeds for clearCacheFile ;(mockFileSystem.writeFile as Mock).mockClear() ;(mockFileSystem.writeFile as Mock).mockResolvedValue(undefined) await cacheManager.clearCacheFile() expect(mockFileSystem.writeFile).toHaveBeenCalledWith(mockCachePath, new TextEncoder().encode("{}")) expect(cacheManager.getAllHashes()).toEqual({}) }) it("should handle clear errors gracefully", async () => { const consoleErrorSpy = vitest.spyOn(console, "error").mockImplementation(() => {}) ;(mockFileSystem.writeFile as Mock).mockRejectedValue(new Error("Save failed")) await cacheManager.clearCacheFile() expect(consoleErrorSpy).toHaveBeenCalledWith( "Failed to clear cache file:", expect.any(Error), mockCachePath, ) consoleErrorSpy.mockRestore() }) }) })

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