@xiaohui-wang/mcpadvisor
Version:
MCP Advisor & Installation - Find the right MCP server for your needs
97 lines (96 loc) • 3.83 kB
JavaScript
/**
* 向量搜索引擎通用测试
* 测试各种向量搜索引擎实现的共同接口和行为
*/
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
import { normalizeVector } from '../../utils/vectorUtils.js';
// 创建一个模拟的向量搜索引擎实现
class MockVectorSearchEngine {
mockData = [];
async addEntry(id, vector, data) {
this.mockData.push({ id, vector, data });
}
async search(queryVector, limit = 10) {
// 模拟搜索实现
const results = this.mockData.map(item => {
const similarity = this.calculateSimilarity(queryVector, item.vector);
return {
...item.data,
similarity: similarity // 更新相似度字段
};
})
.sort((a, b) => b.similarity - a.similarity)
.slice(0, limit);
return results;
}
async clear() {
this.mockData = [];
}
// 辅助方法:计算余弦相似度
calculateSimilarity(v1, v2) {
const normalizedV1 = normalizeVector(v1);
const normalizedV2 = normalizeVector(v2);
let dotProduct = 0;
for (let i = 0; i < normalizedV1.length; i++) {
dotProduct += normalizedV1[i] * normalizedV2[i];
}
return dotProduct;
}
// 用于测试的方法:添加模拟数据
addMockData(id, vector, metadata) {
// 创建一个简单的 MCPServerResponse 对象
const data = {
id: id,
title: metadata.name || `MCP Server ${id}`,
description: metadata.description || `Description for ${id}`,
github_url: metadata.github_url || `https://github.com/example/${id}`,
similarity: 0, // 初始相似度为 0,在搜索时计算
categories: metadata.categories || 'test',
tags: metadata.tags || ['test', 'mock']
};
this.mockData.push({ id, vector, data });
}
// 用于测试的方法:清除模拟数据
clearMockData() {
this.mockData = [];
}
}
describe('向量搜索引擎通用测试', () => {
let vectorEngine;
beforeEach(() => {
vectorEngine = new MockVectorSearchEngine();
// 添加一些测试数据
vectorEngine.addMockData('1', [1, 0, 0], { name: '文档1' });
vectorEngine.addMockData('2', [0, 1, 0], { name: '文档2' });
vectorEngine.addMockData('3', [0, 0, 1], { name: '文档3' });
vectorEngine.addMockData('4', [0.7, 0.7, 0], { name: '文档4' });
});
afterEach(() => {
vectorEngine.clearMockData();
});
test('应该能够找到最相似的向量', async () => {
const queryVector = [0.9, 0.1, 0];
const results = await vectorEngine.search(queryVector, 2);
expect(results.length).toBe(2);
expect(results[0].id).toBe('1'); // 文档1应该是最相似的
expect(results[0].similarity).toBeGreaterThan(0.9);
});
test('应该返回按相似度排序的结果', async () => {
const queryVector = [0.5, 0.5, 0.5];
const results = await vectorEngine.search(queryVector);
// 确保结果按相似度降序排列
for (let i = 1; i < results.length; i++) {
expect(results[i - 1].similarity).toBeGreaterThanOrEqual(results[i].similarity);
}
});
test('应该限制返回结果数量', async () => {
const queryVector = [0.33, 0.33, 0.33];
const limit = 2;
const results = await vectorEngine.search(queryVector, limit);
expect(results.length).toBeLessThanOrEqual(limit);
});
// TODO: 添加更多测试用例
test.todo('应该正确处理空向量');
test.todo('应该正确处理不同维度的向量');
test.todo('应该正确处理大量数据');
});