@zerospacegg/anrubic
Version:
Anrubic - ZeroSpace.gg MCP Server for AI agents to access game data
238 lines (211 loc) • 5.23 kB
text/typescript
// Test setup file for Anrubic MCP Server
// This file provides utilities for testing MCP protocol interactions
import { Readable, Writable } from "node:stream";
import { afterEach, beforeEach, mock } from "node:test";
// Global test setup
beforeEach(() => {
// Reset all mocks before each test
mock.restoreAll();
// Reset environment variables
delete process.env.NODE_ENV;
});
afterEach(() => {
// Clean up after each test
mock.restoreAll();
});
// Helper to create mock MCP request
export function createMockMCPRequest(
method: string,
params?: any,
id: number = 1
) {
return {
jsonrpc: "2.0",
id,
method,
...(params && { params }),
};
}
// Helper to create mock stdio streams for MCP server testing
export function createMockStdioStreams() {
const mockInput = new Readable({
read() {
// Mock readable stream
},
});
const mockOutput = new Writable({
write(chunk, encoding, callback) {
// Store output for testing
this.lastOutput = chunk.toString();
callback();
},
});
// Add a property to store the last output
(mockOutput as any).lastOutput = "";
return { input: mockInput, output: mockOutput };
}
// Helper to parse MCP JSON-RPC response
export function parseMCPResponse(output: string) {
try {
const lines = output.trim().split("\n");
// Find the last line that looks like JSON
for (let i = lines.length - 1; i >= 0; i--) {
const line = lines[i].trim();
if (line.startsWith("{") && line.endsWith("}")) {
return JSON.parse(line);
}
}
throw new Error("No valid JSON response found");
} catch (error) {
throw new Error(`Failed to parse MCP response: ${output}`);
}
}
// Helper to send MCP request to server
export function sendMCPRequest(input: Readable, request: any) {
const requestStr = JSON.stringify(request) + "\n";
input.push(requestStr);
input.push(null); // End the stream
}
// Mock iolin data for testing
export const mockIolinData = {
units: [
{
id: "faction/grell/unit/lasher",
slug: "lasher",
name: "Lasher",
faction: "grell",
tier: "T1.5",
type: "unit",
inGame: true,
},
{
id: "faction/protectorate/unit/griffin",
slug: "griffin",
name: "Griffin",
faction: "protectorate",
tier: "T3",
type: "unit",
inGame: true,
},
],
buildings: [
{
id: "faction/grell/building/hive",
slug: "hive",
name: "Hive",
faction: "grell",
tier: "T0",
type: "building",
inGame: true,
},
],
tags: [
{
tag: "attacker",
label: "Attacker",
description: "Has a basic auto-attack",
},
{
tag: "flyer",
label: "Flyer",
description: "Flyer",
},
{
tag: "healer",
label: "Healer",
description: "Heals or repairs units or buildings",
},
],
};
// Helper to validate MCP tool schema
export function validateToolSchema(tool: any) {
const requiredFields = ["name", "inputSchema"];
for (const field of requiredFields) {
if (!tool[field]) {
throw new Error(`Tool missing required field: ${field}`);
}
}
// Validate inputSchema is a valid JSON schema
if (typeof tool.inputSchema !== "object") {
throw new Error("Tool inputSchema must be an object");
}
if (tool.inputSchema.type !== "object") {
throw new Error('Tool inputSchema type must be "object"');
}
return true;
}
// Helper to validate MCP response format
export function validateMCPResponse(response: any, expectedId?: number) {
if (!response.jsonrpc || response.jsonrpc !== "2.0") {
throw new Error("Invalid JSON-RPC version");
}
if (expectedId !== undefined && response.id !== expectedId) {
throw new Error(`Expected id ${expectedId}, got ${response.id}`);
}
if (response.error) {
throw new Error(`MCP Error: ${response.error.message}`);
}
if (!response.result) {
throw new Error("MCP response missing result");
}
return true;
}
// Expected MCP tools that should be available
export const expectedMCPTools = [
"get_tags",
"get_faction_data",
"fetch_entity_by_id",
"all_ids",
"search_entities",
"compare_units",
"get_tech_tree",
"find_by_tags",
];
// Test data for common MCP tool calls
export const testToolCalls = {
get_tags: {
name: "get_tags",
arguments: {},
},
search_entities: {
name: "search_entities",
arguments: {
query: "lasher",
limit: 3,
},
},
find_by_tags: {
name: "find_by_tags",
arguments: {
tags: ["attacker"],
matchAll: true,
limit: 5,
},
},
fetch_entity_by_id: {
name: "fetch_entity_by_id",
arguments: {
id: "faction/protectorate/unit/griffin",
},
},
get_faction_data: {
name: "get_faction_data",
arguments: {
faction: "grell",
},
},
};
// Console override for cleaner test output
const originalConsole = { ...console };
export function suppressConsole() {
global.console = {
...console,
log: mock.fn(),
warn: mock.fn(),
error: mock.fn(),
info: mock.fn(),
};
}
export function restoreConsole() {
global.console = originalConsole;
}