Skip to main content
Glama

NervusDB MCP Server

Official
by nervusdb
refactoringSuggester.spec.ts6 kB
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { RefactoringSuggester } from '../../src/services/refactoringSuggester.js'; import type { QueryService, CodeEntityInfo } from '../../src/domain/query/queryService.js'; describe('RefactoringSuggester', () => { let suggester: RefactoringSuggester; let mockQueryService: QueryService; beforeEach(() => { mockQueryService = { getCallHierarchy: vi.fn(), findReferences: vi.fn(), } as unknown as QueryService; suggester = new RefactoringSuggester({ queryService: mockQueryService }); }); describe('suggestRefactorings', () => { it('should suggest extract method refactoring for long functions', async () => { const mockEntity: CodeEntityInfo = { nodeId: '1', name: 'longFunction', type: 'function', filePath: '/project/src/long.ts', metadata: { lines: 120, complexity: 15, }, }; const mockHierarchy = { entity: mockEntity, callers: [], callees: [], }; vi.mocked(mockQueryService.getCallHierarchy).mockResolvedValue(mockHierarchy as any); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['longFunction'], }); expect(result).toBeDefined(); expect(result.suggestions.length).toBeGreaterThanOrEqual(0); const extractMethodSuggestion = result.suggestions.find( (s) => s.type === 'extract-method' || s.type === 'extract-function', ); if (extractMethodSuggestion) { expect(extractMethodSuggestion.priority).toMatch(/HIGH|MEDIUM/); } }); it('should suggest simplify parameters for functions with many params', async () => { const mockEntity: CodeEntityInfo = { nodeId: '2', name: 'manyParamsFunction', type: 'function', filePath: '/project/src/params.ts', metadata: { parameters: 9, }, }; const mockHierarchy = { entity: mockEntity, callers: [], callees: [], }; vi.mocked(mockQueryService.getCallHierarchy).mockResolvedValue(mockHierarchy as any); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['manyParamsFunction'], }); expect(result).toBeDefined(); const simplifyParamsSuggestion = result.suggestions.find( (s) => s.type === 'simplify-parameters' || s.type === 'introduce-parameter-object', ); if (simplifyParamsSuggestion) { expect(simplifyParamsSuggestion.description).toBeDefined(); } }); it('should suggest removing unused code', async () => { const mockEntity: CodeEntityInfo = { nodeId: '3', name: 'unusedFunction', type: 'function', filePath: '/project/src/unused.ts', }; const mockHierarchy = { entity: mockEntity, callers: [], callees: [], }; vi.mocked(mockQueryService.getCallHierarchy).mockResolvedValue(mockHierarchy as any); vi.mocked(mockQueryService.findReferences).mockResolvedValue([]); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['unusedFunction'], }); expect(result).toBeDefined(); const removeDeadCodeSuggestion = result.suggestions.find( (s) => s.type === 'remove-dead-code', ); if (removeDeadCodeSuggestion) { expect(removeDeadCodeSuggestion.impact).toBe('LOW'); } }); it('should prioritize suggestions by impact and effort', async () => { const mockEntity: CodeEntityInfo = { nodeId: '4', name: 'refactorMe', type: 'function', filePath: '/project/src/refactor.ts', metadata: { complexity: 20, lines: 100, parameters: 7, }, }; const mockHierarchy = { entity: mockEntity, callers: [ { entity: { nodeId: '5', name: 'caller1', type: 'function', filePath: '/project/src/caller1.ts', }, callers: [], callees: [], }, ], callees: [], }; vi.mocked(mockQueryService.getCallHierarchy).mockResolvedValue(mockHierarchy as any); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['refactorMe'], }); expect(result).toBeDefined(); expect(result.summary).toBeDefined(); expect(result.summary.totalSuggestions).toBeGreaterThanOrEqual(0); }); it('should handle symbols not found', async () => { vi.mocked(mockQueryService.getCallHierarchy).mockRejectedValue(new Error('Symbol not found')); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['nonExistent'], }); expect(result).toBeDefined(); expect(result.suggestions).toEqual([]); expect(result.summary.totalSuggestions).toBe(0); }); it('should provide summary statistics', async () => { const mockEntity: CodeEntityInfo = { nodeId: '6', name: 'testFunction', type: 'function', filePath: '/project/src/test.ts', metadata: { complexity: 5, }, }; const mockHierarchy = { entity: mockEntity, callers: [], callees: [], }; vi.mocked(mockQueryService.getCallHierarchy).mockResolvedValue(mockHierarchy as any); const result = await suggester.suggestRefactorings({ projectPath: '/project', symbols: ['testFunction'], }); expect(result).toBeDefined(); expect(result.summary).toBeDefined(); expect(result.summary.byPriority).toBeDefined(); expect(result.summary.byPattern).toBeDefined(); }); }); });

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/nervusdb/nervusdb-mcp'

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