Skip to main content
Glama

MCP Advisor

MIT License
88
64
  • Apple
  • Linux
testUtils.ts6.42 kB
import { MCPServerResponse } from '../../../types/index.js'; // 类型守卫,确保对象具有正确格式的 tags 属性 function hasValidTags(result: any): result is { tags: string[] } { return Array.isArray(result.tags) && result.tags.every((tag: any) => typeof tag === 'string'); } // 类型守卫,检查对象是否具有 score 属性 function hasScore(result: any): result is { score: number } { return 'score' in result && typeof result.score === 'number'; } /** * 检查结果中是否包含指定的服务器名称 */ export function containsServerNames( results: MCPServerResponse[], serverNames: string[], ): { contains: boolean; missing: string[]; found: string[] } { if (!results || !Array.isArray(results) || results.length === 0) { return { contains: false, missing: [...serverNames], found: [] }; } const foundServers: string[] = []; const missingServers: string[] = []; // 检查每个需要验证的服务器名称 for (const serverName of serverNames) { const found = results.some(result => { // 使用类型断言来处理可能的属性 const serverInfo = result as any; return ( serverInfo.id === serverName || serverInfo.name === serverName || serverInfo.display_name === serverName ); }); if (found) { foundServers.push(serverName); } else { missingServers.push(serverName); } } return { contains: missingServers.length === 0, missing: missingServers, found: foundServers }; } /** * 检查结果中是否包含指定关键词 */ export function containsKeywords( results: MCPServerResponse[], keywords: string[], ): { contains: boolean; matchedItems: MCPServerResponse[] } { if (!results || !Array.isArray(results)) { return { contains: false, matchedItems: [] }; } const lowerKeywords = keywords.map(k => k.toLowerCase()); const matchedItems = results.filter(result => { if (!result) return false; const title = result.title?.toLowerCase() || ''; const description = result.description?.toLowerCase() || ''; // 处理 tags 属性,确保是字符串数组 let tags: string[] = []; if (hasValidTags(result)) { tags = result.tags.map(t => t.toLowerCase()); } else if (result.tags) { // 如果 tags 存在但不是字符串数组,则尝试转换 tags = [String(result.tags)].flat().map(t => t.toLowerCase()); } return lowerKeywords.some( keyword => title.includes(keyword) || description.includes(keyword) || tags.some(tag => tag.includes(keyword)), ); }); return { contains: matchedItems.length > 0, matchedItems, }; } /** * 创建搜索测试函数 */ export function createSearchTest( testCase: { name: string; query: string; options: any; textWeight?: number; expectedKeywords: string[]; expectedServerNames?: string[]; description: string; skip?: boolean; }, searchFn: ( query: string, options: any, fallbackPath: string, textWeight?: number, ) => Promise<MCPServerResponse[]>, fallbackPath: string, ) { const testFn = async () => { const { query, options, textWeight, expectedKeywords, expectedServerNames } = testCase; try { // 执行搜索 const results = await searchFn(query, options, fallbackPath, textWeight); // 基础断言 expect(results).toBeDefined(); expect(Array.isArray(results)).toBe(true); // 记录测试信息 console.log(`[${testCase.name}] 搜索结果数量: ${results.length}`); // 如果有结果,进行验证 if (results.length > 0) { // 输出服务器列表,便于调试 console.log(`[${testCase.name}] 返回的服务器:`, results.map((item: any) => ({ id: item.id, name: item.name || '', display_name: item.display_name || '', })) ); // 验证关键词 if (expectedKeywords && expectedKeywords.length > 0) { const { contains, matchedItems } = containsKeywords(results, expectedKeywords); // 输出匹配到的项目信息,便于调试 if (matchedItems.length > 0) { console.log(`[${testCase.name}] 匹配关键词的项目:`, matchedItems.map(item => { const itemInfo: any = { title: item.title, tags: item.tags, }; // 安全地添加 score 属性(如果存在) if (hasScore(item)) { itemInfo.score = item.score; } return itemInfo; }) ); } // 断言关键词匹配 const keywordMessage = `应该包含关键词 ${expectedKeywords.join(', ')}`; expect(contains).toBe(true); } // 验证特定服务器名称 if (expectedServerNames && expectedServerNames.length > 0) { const { contains, missing, found } = containsServerNames(results, expectedServerNames); // 输出验证结果,便于调试 console.log(`[${testCase.name}] 验证服务器名称:`, { expected: expectedServerNames, found, missing }); // 断言服务器名称匹配 const serverMessage = `应该包含服务器 ${expectedServerNames.join(', ')} 但缺失 ${missing.join(', ')}`; expect(contains).toBe(true); } } else { // 如果有预期的服务器名称,但结果为空,则测试失败 if (expectedServerNames && expectedServerNames.length > 0) { const emptyMessage = `搜索结果不应为空,应该包含服务器 ${expectedServerNames.join(', ')}`; expect(results.length).toBeGreaterThan(0); } else { console.warn(`[${testCase.name}] 警告: 搜索结果为空`); } } } catch (error) { console.error(`[${testCase.name}] 测试执行出错:`, error); throw error; // 重新抛出错误,确保测试失败 } }; if (testCase.skip) { return test.skip(testCase.description, testFn); } return test(testCase.description, testFn); }

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/istarwyh/mcpadvisor'

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