Skip to content

Commit 247cd01

Browse files
committed
test: add comprehensive test script for new MCP features
1 parent 9c5a40c commit 247cd01

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#!/usr/bin/env tsx
2+
3+
import { spawn } from 'child_process';
4+
import * as path from 'path';
5+
import { fileURLToPath } from 'url';
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = path.dirname(__filename);
9+
10+
// Terminal color codes
11+
const colors = {
12+
reset: '\x1b[0m',
13+
bold: '\x1b[1m',
14+
red: '\x1b[31m',
15+
green: '\x1b[32m',
16+
yellow: '\x1b[33m',
17+
blue: '\x1b[34m',
18+
cyan: '\x1b[36m',
19+
magenta: '\x1b[35m',
20+
};
21+
22+
const colorize = (text: string, ...colorCodes: string[]): string => {
23+
return colorCodes.join('') + text + colors.reset;
24+
};
25+
26+
class MCPFeatureTester {
27+
private serverProcess: any = null;
28+
private messageId = 0;
29+
private responses: any[] = [];
30+
31+
async start(): Promise<void> {
32+
console.log(colorize('🚀 Testing MCP Server New Features', colors.bold, colors.cyan));
33+
console.log(colorize('='.repeat(50), colors.cyan));
34+
35+
try {
36+
await this.startServer();
37+
await this.initialize();
38+
39+
// Test all new features
40+
await this.testPrompts();
41+
await this.testResources();
42+
await this.testTools();
43+
44+
console.log(colorize('\n✅ All tests completed successfully!', colors.green, colors.bold));
45+
} catch (error) {
46+
console.error(colorize('❌ Test failed:', colors.red, colors.bold), error);
47+
process.exit(1);
48+
} finally {
49+
this.cleanup();
50+
}
51+
}
52+
53+
private async startServer(): Promise<void> {
54+
const serverPath = path.join(__dirname, '../../dist/index.js');
55+
console.log(colorize('📦 Starting server...', colors.blue));
56+
57+
this.serverProcess = spawn('node', [serverPath], {
58+
stdio: ['pipe', 'pipe', 'pipe'],
59+
env: {
60+
...process.env,
61+
DEBUG: 'false',
62+
},
63+
});
64+
65+
this.serverProcess.stdout?.on('data', (data: Buffer) => {
66+
const lines = data.toString().split('\n').filter(line => line.trim());
67+
lines.forEach(line => {
68+
try {
69+
const response = JSON.parse(line);
70+
this.responses.push(response);
71+
} catch {
72+
// Ignore non-JSON lines
73+
}
74+
});
75+
});
76+
77+
// Wait for server to start
78+
await new Promise(resolve => setTimeout(resolve, 1000));
79+
}
80+
81+
private async initialize(): Promise<void> {
82+
console.log(colorize('🔄 Initializing MCP connection...', colors.blue));
83+
84+
await this.sendRequest({
85+
jsonrpc: '2.0',
86+
id: this.messageId++,
87+
method: 'initialize',
88+
params: {
89+
protocolVersion: '1.0.0',
90+
capabilities: {},
91+
clientInfo: {
92+
name: 'mcp-feature-tester',
93+
version: '1.0.0',
94+
},
95+
},
96+
});
97+
98+
await this.waitForResponse();
99+
console.log(colorize('✅ Initialized', colors.green));
100+
}
101+
102+
private async testPrompts(): Promise<void> {
103+
console.log(colorize('\n📝 Testing Prompts...', colors.bold, colors.yellow));
104+
105+
// List prompts
106+
await this.sendRequest({
107+
jsonrpc: '2.0',
108+
id: this.messageId++,
109+
method: 'prompts/list',
110+
params: {},
111+
});
112+
113+
const promptsResponse = await this.waitForResponse();
114+
const prompts = promptsResponse?.result?.prompts || [];
115+
116+
console.log(` Found ${prompts.length} prompts:`);
117+
prompts.forEach((prompt: any) => {
118+
console.log(` - ${colorize(prompt.name, colors.cyan)}: ${prompt.description}`);
119+
});
120+
121+
// Test getting a specific prompt
122+
if (prompts.length > 0) {
123+
await this.sendRequest({
124+
jsonrpc: '2.0',
125+
id: this.messageId++,
126+
method: 'prompts/get',
127+
params: {
128+
name: 'analyze-project',
129+
arguments: {
130+
projectPath: '/test/path',
131+
profile: 'Default'
132+
}
133+
},
134+
});
135+
136+
const promptResponse = await this.waitForResponse();
137+
if (promptResponse?.result?.messages) {
138+
console.log(colorize(' ✅ Prompt "analyze-project" works correctly', colors.green));
139+
}
140+
}
141+
}
142+
143+
private async testResources(): Promise<void> {
144+
console.log(colorize('\n📚 Testing Resources...', colors.bold, colors.yellow));
145+
146+
// List resources
147+
await this.sendRequest({
148+
jsonrpc: '2.0',
149+
id: this.messageId++,
150+
method: 'resources/list',
151+
params: {},
152+
});
153+
154+
const resourcesResponse = await this.waitForResponse();
155+
const resources = resourcesResponse?.result?.resources || [];
156+
157+
console.log(` Found ${resources.length} resources:`);
158+
resources.forEach((resource: any) => {
159+
console.log(` - ${colorize(resource.uri, colors.cyan)}: ${resource.name}`);
160+
});
161+
162+
// Test reading each resource
163+
for (const resource of resources) {
164+
await this.sendRequest({
165+
jsonrpc: '2.0',
166+
id: this.messageId++,
167+
method: 'resources/read',
168+
params: {
169+
uri: resource.uri,
170+
},
171+
});
172+
173+
const readResponse = await this.waitForResponse();
174+
if (readResponse?.result?.contents) {
175+
console.log(colorize(` ✅ Resource "${resource.uri}" is accessible`, colors.green));
176+
}
177+
}
178+
}
179+
180+
private async testTools(): Promise<void> {
181+
console.log(colorize('\n🔧 Testing Tools...', colors.bold, colors.yellow));
182+
183+
// List tools
184+
await this.sendRequest({
185+
jsonrpc: '2.0',
186+
id: this.messageId++,
187+
method: 'tools/list',
188+
params: {},
189+
});
190+
191+
const toolsResponse = await this.waitForResponse();
192+
const tools = toolsResponse?.result?.tools || [];
193+
194+
console.log(` Found ${tools.length} tools:`);
195+
tools.forEach((tool: any) => {
196+
console.log(` - ${colorize(tool.name, colors.cyan)}: ${tool.description}`);
197+
});
198+
199+
if (tools.length > 0) {
200+
console.log(colorize(' ✅ Tool "get_jetbrains_code_inspections" is available', colors.green));
201+
}
202+
}
203+
204+
private async sendRequest(request: any): Promise<void> {
205+
const requestStr = JSON.stringify(request) + '\n';
206+
if (this.serverProcess?.stdin) {
207+
this.serverProcess.stdin.write(requestStr);
208+
}
209+
}
210+
211+
private async waitForResponse(timeout = 3000): Promise<any> {
212+
const startTime = Date.now();
213+
const initialLength = this.responses.length;
214+
215+
while (Date.now() - startTime < timeout) {
216+
if (this.responses.length > initialLength) {
217+
return this.responses[this.responses.length - 1];
218+
}
219+
await new Promise(resolve => setTimeout(resolve, 100));
220+
}
221+
222+
throw new Error('Timeout waiting for response');
223+
}
224+
225+
private cleanup(): void {
226+
if (this.serverProcess) {
227+
this.serverProcess.kill();
228+
}
229+
}
230+
}
231+
232+
// Main execution
233+
async function main() {
234+
const tester = new MCPFeatureTester();
235+
await tester.start();
236+
}
237+
238+
main().catch(error => {
239+
console.error(colorize('❌ Fatal error:', colors.red, colors.bold), error);
240+
process.exit(1);
241+
});

0 commit comments

Comments
 (0)