mcp-prompt-optimizer 1.4.2 โ 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -53
- package/CROSS-PLATFORM.md +3 -3
- package/README.md +99 -39
- package/index.js +843 -187
- package/lib/api-key-manager.js +191 -138
- package/lib/check-status.js +1 -1
- package/package.json +80 -5
- package/tests/README.md +0 -232
- package/tests/comprehensive-test.js +0 -692
- package/tests/integration-test.js +0 -446
- package/tests/minimal-test.js +0 -265
- package/tests/quick-test.js +0 -256
- package/tests/simple-test.js +0 -171
- package/tests/test-runner.js +0 -322
|
@@ -1,692 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ๐งช COMPREHENSIVE MCP PROMPT OPTIMIZER TEST SUITE
|
|
5
|
-
*
|
|
6
|
-
* This script tests the complete functionality of the MCP Prompt Optimizer package
|
|
7
|
-
* before NPM registry publication. It can run with or without an API key.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* - With API Key: OPTIMIZER_API_KEY=sk-opt-xxx node tests/comprehensive-test.js
|
|
11
|
-
* - Without API Key (Mock Mode): node tests/comprehensive-test.js
|
|
12
|
-
* - Development Mode: OPTIMIZER_DEV_MODE=true node tests/comprehensive-test.js
|
|
13
|
-
*
|
|
14
|
-
* Version: 1.0.0
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const { exec, spawn } = require('child_process');
|
|
18
|
-
const fs = require('fs').promises;
|
|
19
|
-
const path = require('path');
|
|
20
|
-
const https = require('https');
|
|
21
|
-
const http = require('http');
|
|
22
|
-
const os = require('os');
|
|
23
|
-
|
|
24
|
-
// Import our package components
|
|
25
|
-
const CloudApiKeyManager = require('../lib/api-key-manager');
|
|
26
|
-
const { MCPPromptOptimizer } = require('../index');
|
|
27
|
-
const packageJson = require('../package.json');
|
|
28
|
-
|
|
29
|
-
class ComprehensiveTestSuite {
|
|
30
|
-
constructor() {
|
|
31
|
-
this.testResults = {
|
|
32
|
-
passed: 0,
|
|
33
|
-
failed: 0,
|
|
34
|
-
warnings: 0,
|
|
35
|
-
errors: [],
|
|
36
|
-
details: []
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
this.apiKey = process.env.OPTIMIZER_API_KEY;
|
|
40
|
-
this.hasApiKey = !!this.apiKey;
|
|
41
|
-
this.devMode = process.env.OPTIMIZER_DEV_MODE === 'true' || process.env.NODE_ENV === 'development';
|
|
42
|
-
this.testStartTime = Date.now();
|
|
43
|
-
|
|
44
|
-
console.log(`๐งช MCP Prompt Optimizer Comprehensive Test Suite v1.0.0`);
|
|
45
|
-
console.log(`๐ฆ Testing Package: ${packageJson.name} v${packageJson.version}`);
|
|
46
|
-
console.log(`๐ API Key Available: ${this.hasApiKey ? 'YES' : 'NO (will use mock mode)'}`);
|
|
47
|
-
console.log(`๐ ๏ธ Development Mode: ${this.devMode ? 'YES' : 'NO'}`);
|
|
48
|
-
console.log(`๐ฅ๏ธ Platform: ${os.platform()} ${os.arch()}`);
|
|
49
|
-
console.log(`๐
Node.js: ${process.version}`);
|
|
50
|
-
console.log(`\n${'='.repeat(80)}\n`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Utility methods
|
|
54
|
-
log(message, type = 'info') {
|
|
55
|
-
const timestamp = new Date().toLocaleTimeString();
|
|
56
|
-
const prefix = `[${timestamp}]`;
|
|
57
|
-
|
|
58
|
-
switch(type) {
|
|
59
|
-
case 'success':
|
|
60
|
-
console.log(`${prefix} โ
${message}`);
|
|
61
|
-
break;
|
|
62
|
-
case 'error':
|
|
63
|
-
console.log(`${prefix} โ ${message}`);
|
|
64
|
-
break;
|
|
65
|
-
case 'warning':
|
|
66
|
-
console.log(`${prefix} โ ๏ธ ${message}`);
|
|
67
|
-
break;
|
|
68
|
-
case 'test':
|
|
69
|
-
console.log(`${prefix} ๐งช ${message}`);
|
|
70
|
-
break;
|
|
71
|
-
default:
|
|
72
|
-
console.log(`${prefix} โน๏ธ ${message}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async assertTrue(condition, testName, details = '') {
|
|
77
|
-
if (condition) {
|
|
78
|
-
this.testResults.passed++;
|
|
79
|
-
this.log(`PASS: ${testName}`, 'success');
|
|
80
|
-
if (details) this.testResults.details.push(`โ
${testName}: ${details}`);
|
|
81
|
-
} else {
|
|
82
|
-
this.testResults.failed++;
|
|
83
|
-
this.testResults.errors.push(testName);
|
|
84
|
-
this.log(`FAIL: ${testName}`, 'error');
|
|
85
|
-
if (details) this.testResults.details.push(`โ ${testName}: ${details}`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async assertWarning(condition, testName, details = '') {
|
|
90
|
-
if (!condition) {
|
|
91
|
-
this.testResults.warnings++;
|
|
92
|
-
this.log(`WARNING: ${testName}`, 'warning');
|
|
93
|
-
if (details) this.testResults.details.push(`โ ๏ธ ${testName}: ${details}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Test Suite Methods
|
|
98
|
-
|
|
99
|
-
async testPackageStructure() {
|
|
100
|
-
this.log('Testing Package Structure...', 'test');
|
|
101
|
-
|
|
102
|
-
// Test main files exist
|
|
103
|
-
const requiredFiles = [
|
|
104
|
-
'index.js',
|
|
105
|
-
'package.json',
|
|
106
|
-
'lib/api-key-manager.js',
|
|
107
|
-
'README.md'
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
for (const file of requiredFiles) {
|
|
111
|
-
try {
|
|
112
|
-
await fs.access(path.join(__dirname, '..', file));
|
|
113
|
-
await this.assertTrue(true, `Required file exists: ${file}`);
|
|
114
|
-
} catch (error) {
|
|
115
|
-
await this.assertTrue(false, `Required file missing: ${file}`, error.message);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Test package.json structure
|
|
120
|
-
try {
|
|
121
|
-
const pkg = require('../package.json');
|
|
122
|
-
await this.assertTrue(pkg.name === 'mcp-prompt-optimizer', 'Package name is correct');
|
|
123
|
-
await this.assertTrue(pkg.version && pkg.version.match(/^\d+\.\d+\.\d+$/), 'Version follows semver', pkg.version);
|
|
124
|
-
await this.assertTrue(pkg.main === 'index.js', 'Main entry point is correct');
|
|
125
|
-
await this.assertTrue(pkg.bin && pkg.bin['mcp-prompt-optimizer'], 'Binary is defined');
|
|
126
|
-
await this.assertTrue(Array.isArray(pkg.os), 'OS array is defined');
|
|
127
|
-
await this.assertTrue(Array.isArray(pkg.cpu), 'CPU array is defined');
|
|
128
|
-
await this.assertTrue(pkg.dependencies && pkg.dependencies['@modelcontextprotocol/sdk'], 'MCP SDK dependency exists');
|
|
129
|
-
await this.assertTrue(pkg.devDependencies && pkg.devDependencies['cross-env'], 'Cross-env dev dependency exists');
|
|
130
|
-
} catch (error) {
|
|
131
|
-
await this.assertTrue(false, 'Package.json structure validation', error.message);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async testCrossPlatformCompatibility() {
|
|
136
|
-
this.log('Testing Cross-Platform Compatibility...', 'test');
|
|
137
|
-
|
|
138
|
-
// Test platform declarations
|
|
139
|
-
const pkg = require('../package.json');
|
|
140
|
-
const supportedOS = ['win32', 'darwin', 'linux'];
|
|
141
|
-
const supportedCPU = ['x64', 'arm64'];
|
|
142
|
-
|
|
143
|
-
await this.assertTrue(
|
|
144
|
-
supportedOS.every(os => pkg.os.includes(os)),
|
|
145
|
-
'All required OS platforms supported',
|
|
146
|
-
pkg.os.join(', ')
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
await this.assertTrue(
|
|
150
|
-
supportedCPU.every(cpu => pkg.cpu.includes(cpu)),
|
|
151
|
-
'All required CPU architectures supported',
|
|
152
|
-
pkg.cpu.join(', ')
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// Test environment variable handling (cross-platform)
|
|
156
|
-
process.env.TEST_VAR = 'test_value';
|
|
157
|
-
await this.assertTrue(process.env.TEST_VAR === 'test_value', 'Environment variable handling works');
|
|
158
|
-
delete process.env.TEST_VAR;
|
|
159
|
-
|
|
160
|
-
// Test path handling (cross-platform)
|
|
161
|
-
const testPath = path.join('test', 'path', 'file.js');
|
|
162
|
-
await this.assertTrue(testPath.includes(path.sep), 'Path separator handling is cross-platform');
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async testApiKeyValidation() {
|
|
166
|
-
this.log('Testing API Key Validation...', 'test');
|
|
167
|
-
|
|
168
|
-
// Test API key format validation
|
|
169
|
-
const manager = new CloudApiKeyManager('dummy-key');
|
|
170
|
-
|
|
171
|
-
// Test valid formats
|
|
172
|
-
const validKeys = [
|
|
173
|
-
'sk-opt-1234567890abcdef1234567890',
|
|
174
|
-
'sk-team-abcdef1234567890abcdef12',
|
|
175
|
-
'sk-dev-test1234567890abcdef',
|
|
176
|
-
'sk-local-dev1234567890abcdef'
|
|
177
|
-
];
|
|
178
|
-
|
|
179
|
-
for (const key of validKeys) {
|
|
180
|
-
const validation = manager.validateApiKeyFormat(key);
|
|
181
|
-
await this.assertTrue(validation.valid, `Valid key format: ${key.substring(0, 10)}...`);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Test invalid formats
|
|
185
|
-
const invalidKeys = [
|
|
186
|
-
'invalid-key',
|
|
187
|
-
'sk-wrong-format',
|
|
188
|
-
'sk-opt-123', // too short
|
|
189
|
-
'', // empty
|
|
190
|
-
null, // null
|
|
191
|
-
undefined // undefined
|
|
192
|
-
];
|
|
193
|
-
|
|
194
|
-
for (const key of invalidKeys) {
|
|
195
|
-
const validation = manager.validateApiKeyFormat(key);
|
|
196
|
-
await this.assertTrue(!validation.valid, `Invalid key format rejected: ${key || 'null/undefined'}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async testApiKeyManagerFunctionality() {
|
|
201
|
-
this.log('Testing API Key Manager Functionality...', 'test');
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
if (this.hasApiKey) {
|
|
205
|
-
// Test with real API key
|
|
206
|
-
this.log('Testing with real API key...', 'info');
|
|
207
|
-
const manager = new CloudApiKeyManager(this.apiKey, { developmentMode: this.devMode });
|
|
208
|
-
|
|
209
|
-
const validation = await manager.validateApiKey();
|
|
210
|
-
await this.assertTrue(validation && validation.valid, 'Real API key validation successful');
|
|
211
|
-
|
|
212
|
-
if (validation.valid) {
|
|
213
|
-
await this.assertTrue(typeof validation.tier === 'string', 'Tier information returned');
|
|
214
|
-
await this.assertTrue(typeof validation.quota === 'object', 'Quota information returned');
|
|
215
|
-
await this.assertTrue(typeof validation.features === 'object', 'Features information returned');
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Test quota status
|
|
219
|
-
try {
|
|
220
|
-
const quotaStatus = await manager.getQuotaStatus();
|
|
221
|
-
await this.assertTrue(quotaStatus && typeof quotaStatus === 'object', 'Quota status retrieved');
|
|
222
|
-
await this.assertTrue(typeof quotaStatus.tier === 'string', 'Quota status has tier');
|
|
223
|
-
} catch (error) {
|
|
224
|
-
await this.assertWarning(false, 'Quota status retrieval', error.message);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
} else {
|
|
228
|
-
// Test with development/mock mode
|
|
229
|
-
this.log('Testing with mock mode (no API key)...', 'info');
|
|
230
|
-
const manager = new CloudApiKeyManager('sk-dev-test-key-1234567890abcdef', {
|
|
231
|
-
developmentMode: true
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
const validation = await manager.validateApiKey();
|
|
235
|
-
await this.assertTrue(validation && validation.valid, 'Mock API key validation successful');
|
|
236
|
-
await this.assertTrue(validation.mock_mode === true, 'Mock mode properly detected');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Test caching functionality
|
|
240
|
-
const manager = new CloudApiKeyManager(this.apiKey || 'sk-dev-test-key-1234567890abcdef', {
|
|
241
|
-
developmentMode: !this.hasApiKey
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Test cache file paths
|
|
245
|
-
const cacheFile = path.join(os.homedir(), '.mcp-cloud-api-cache.json');
|
|
246
|
-
const healthFile = path.join(os.homedir(), '.mcp-cloud-health.json');
|
|
247
|
-
|
|
248
|
-
await this.assertTrue(typeof cacheFile === 'string' && cacheFile.length > 0, 'Cache file path generated');
|
|
249
|
-
await this.assertTrue(typeof healthFile === 'string' && healthFile.length > 0, 'Health file path generated');
|
|
250
|
-
|
|
251
|
-
} catch (error) {
|
|
252
|
-
await this.assertTrue(false, 'API Key Manager functionality test', error.message);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
async testMCPServerFunctionality() {
|
|
257
|
-
this.log('Testing MCP Server Functionality...', 'test');
|
|
258
|
-
|
|
259
|
-
try {
|
|
260
|
-
// Test MCP server creation
|
|
261
|
-
const server = new MCPPromptOptimizer();
|
|
262
|
-
await this.assertTrue(server !== null && server !== undefined, 'MCP server instance created');
|
|
263
|
-
await this.assertTrue(typeof server.server === 'object', 'MCP server has server property');
|
|
264
|
-
await this.assertTrue(typeof server.backendUrl === 'string', 'Backend URL configured');
|
|
265
|
-
|
|
266
|
-
// Test AI context detection
|
|
267
|
-
const testPrompts = [
|
|
268
|
-
{ prompt: 'Create a photorealistic image of a sunset', expected: 'image_generation' },
|
|
269
|
-
{ prompt: 'You are a helpful assistant. Help me write code.', expected: 'llm_interaction' },
|
|
270
|
-
{ prompt: 'def process_data(data): return data.clean()', expected: 'technical_automation' },
|
|
271
|
-
{ prompt: 'Return this data as JSON format', expected: 'structured_output' },
|
|
272
|
-
{ prompt: 'Write me a simple hello world function', expected: 'code_generation' },
|
|
273
|
-
{ prompt: 'Call the GET /users endpoint', expected: 'api_automation' },
|
|
274
|
-
{ prompt: 'Please help me write a letter', expected: 'human_communication' }
|
|
275
|
-
];
|
|
276
|
-
|
|
277
|
-
for (const test of testPrompts) {
|
|
278
|
-
const detected = server.detectAIContext(test.prompt);
|
|
279
|
-
await this.assertTrue(
|
|
280
|
-
detected === test.expected,
|
|
281
|
-
`AI context detection: "${test.prompt.substring(0, 30)}..." โ ${detected}`,
|
|
282
|
-
`Expected: ${test.expected}, Got: ${detected}`
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Test goal enhancement
|
|
287
|
-
const originalGoals = ['clarity'];
|
|
288
|
-
const enhancedGoals = server.enhanceGoalsForContext(originalGoals, 'image_generation');
|
|
289
|
-
await this.assertTrue(
|
|
290
|
-
enhancedGoals.length > originalGoals.length,
|
|
291
|
-
'Goal enhancement adds context-specific goals',
|
|
292
|
-
`Enhanced: ${enhancedGoals.join(', ')}`
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
// Test mock optimization generation
|
|
296
|
-
const mockResult = server.generateMockOptimization(
|
|
297
|
-
'Test prompt for optimization',
|
|
298
|
-
['clarity', 'conciseness'],
|
|
299
|
-
'llm_interaction'
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
await this.assertTrue(typeof mockResult.optimized_prompt === 'string', 'Mock optimization generates optimized prompt');
|
|
303
|
-
await this.assertTrue(typeof mockResult.confidence_score === 'number', 'Mock optimization generates confidence score');
|
|
304
|
-
await this.assertTrue(mockResult.mock_mode === true, 'Mock mode flag properly set');
|
|
305
|
-
await this.assertTrue(Array.isArray(mockResult.templates_found), 'Mock optimization includes template results');
|
|
306
|
-
await this.assertTrue(typeof mockResult.optimization_insights === 'object', 'Mock optimization includes insights');
|
|
307
|
-
|
|
308
|
-
} catch (error) {
|
|
309
|
-
await this.assertTrue(false, 'MCP Server functionality test', error.message);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
async testNetworkResilience() {
|
|
314
|
-
this.log('Testing Network Resilience...', 'test');
|
|
315
|
-
|
|
316
|
-
try {
|
|
317
|
-
// Test with invalid backend URL
|
|
318
|
-
const manager = new CloudApiKeyManager(this.apiKey || 'sk-dev-test-key-1234567890abcdef', {
|
|
319
|
-
backendUrl: 'https://invalid-nonexistent-domain-12345.com',
|
|
320
|
-
developmentMode: !this.hasApiKey,
|
|
321
|
-
maxRetries: 2,
|
|
322
|
-
requestTimeout: 2000
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
try {
|
|
326
|
-
const validation = await manager.validateApiKey();
|
|
327
|
-
// Should either work (with cache/mock) or fail gracefully
|
|
328
|
-
if (validation) {
|
|
329
|
-
await this.assertTrue(
|
|
330
|
-
validation.fallback_mode || validation.mock_mode || validation.offline_mode,
|
|
331
|
-
'Network resilience: Fallback mode activated on network failure'
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
} catch (error) {
|
|
335
|
-
// Network failure is expected, test if error is handled gracefully
|
|
336
|
-
await this.assertTrue(
|
|
337
|
-
error.message.includes('DNS') || error.message.includes('Network') || error.message.includes('timeout'),
|
|
338
|
-
'Network resilience: Proper error message on network failure',
|
|
339
|
-
error.message
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Test retry logic (if real API key available)
|
|
344
|
-
if (this.hasApiKey) {
|
|
345
|
-
const retryManager = new CloudApiKeyManager(this.apiKey, {
|
|
346
|
-
maxRetries: 3,
|
|
347
|
-
baseRetryDelay: 500,
|
|
348
|
-
requestTimeout: 5000
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
const delay1 = retryManager.calculateRetryDelay(1);
|
|
352
|
-
const delay2 = retryManager.calculateRetryDelay(2);
|
|
353
|
-
const delay3 = retryManager.calculateRetryDelay(3);
|
|
354
|
-
|
|
355
|
-
await this.assertTrue(delay2 > delay1, 'Exponential backoff: Delay increases with attempts');
|
|
356
|
-
await this.assertTrue(delay3 > delay2, 'Exponential backoff: Further increase in delay');
|
|
357
|
-
await this.assertTrue(delay1 >= 500, 'Base retry delay respected');
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
} catch (error) {
|
|
361
|
-
await this.assertTrue(false, 'Network resilience test', error.message);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
async testCommandLineInterface() {
|
|
366
|
-
this.log('Testing Command Line Interface...', 'test');
|
|
367
|
-
|
|
368
|
-
return new Promise((resolve) => {
|
|
369
|
-
// Test the main CLI commands
|
|
370
|
-
const commands = [
|
|
371
|
-
{ cmd: 'node lib/validate-key.js', desc: 'Validate key command' },
|
|
372
|
-
{ cmd: 'node lib/check-status.js', desc: 'Check status command' },
|
|
373
|
-
{ cmd: 'node lib/clear-cache.js', desc: 'Clear cache command' },
|
|
374
|
-
{ cmd: 'node lib/diagnose.js', desc: 'Diagnose command' }
|
|
375
|
-
];
|
|
376
|
-
|
|
377
|
-
let testsCompleted = 0;
|
|
378
|
-
const totalTests = commands.length;
|
|
379
|
-
|
|
380
|
-
for (const command of commands) {
|
|
381
|
-
exec(command.cmd, { cwd: path.join(__dirname, '..') }, (error, stdout, stderr) => {
|
|
382
|
-
if (error) {
|
|
383
|
-
// Commands might fail without API key, but should not crash
|
|
384
|
-
this.assertWarning(
|
|
385
|
-
!error.message.includes('Cannot read properties') && !error.message.includes('TypeError'),
|
|
386
|
-
command.desc,
|
|
387
|
-
`Command executed without crashing: ${error.message.substring(0, 100)}`
|
|
388
|
-
);
|
|
389
|
-
} else {
|
|
390
|
-
this.assertTrue(true, command.desc, 'Command executed successfully');
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
testsCompleted++;
|
|
394
|
-
if (testsCompleted === totalTests) {
|
|
395
|
-
resolve();
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
async testEnvironmentVariables() {
|
|
403
|
-
this.log('Testing Environment Variable Handling...', 'test');
|
|
404
|
-
|
|
405
|
-
// Test environment variable detection
|
|
406
|
-
const originalBackendUrl = process.env.OPTIMIZER_BACKEND_URL;
|
|
407
|
-
const originalDevMode = process.env.OPTIMIZER_DEV_MODE;
|
|
408
|
-
|
|
409
|
-
// Test custom backend URL
|
|
410
|
-
process.env.OPTIMIZER_BACKEND_URL = 'https://test-backend.example.com';
|
|
411
|
-
const server1 = new MCPPromptOptimizer();
|
|
412
|
-
await this.assertTrue(
|
|
413
|
-
server1.backendUrl === 'https://test-backend.example.com',
|
|
414
|
-
'Custom backend URL from environment variable'
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
// Test development mode detection
|
|
418
|
-
process.env.OPTIMIZER_DEV_MODE = 'true';
|
|
419
|
-
const server2 = new MCPPromptOptimizer();
|
|
420
|
-
await this.assertTrue(server2.developmentMode === true, 'Development mode detection from env var');
|
|
421
|
-
|
|
422
|
-
process.env.NODE_ENV = 'development';
|
|
423
|
-
const server3 = new MCPPromptOptimizer();
|
|
424
|
-
await this.assertTrue(server3.developmentMode === true, 'Development mode detection from NODE_ENV');
|
|
425
|
-
|
|
426
|
-
// Restore original values
|
|
427
|
-
if (originalBackendUrl) {
|
|
428
|
-
process.env.OPTIMIZER_BACKEND_URL = originalBackendUrl;
|
|
429
|
-
} else {
|
|
430
|
-
delete process.env.OPTIMIZER_BACKEND_URL;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (originalDevMode) {
|
|
434
|
-
process.env.OPTIMIZER_DEV_MODE = originalDevMode;
|
|
435
|
-
} else {
|
|
436
|
-
delete process.env.OPTIMIZER_DEV_MODE;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
delete process.env.NODE_ENV;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
async testErrorHandling() {
|
|
443
|
-
this.log('Testing Error Handling...', 'test');
|
|
444
|
-
|
|
445
|
-
try {
|
|
446
|
-
// Test invalid optimization request
|
|
447
|
-
const server = new MCPPromptOptimizer();
|
|
448
|
-
|
|
449
|
-
try {
|
|
450
|
-
await server.handleOptimizePrompt({ prompt: '' });
|
|
451
|
-
await this.assertTrue(false, 'Empty prompt should throw error');
|
|
452
|
-
} catch (error) {
|
|
453
|
-
await this.assertTrue(
|
|
454
|
-
error.message.includes('required') || error.message.includes('empty'),
|
|
455
|
-
'Empty prompt properly rejected',
|
|
456
|
-
error.message
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Test API key manager error handling
|
|
461
|
-
const manager = new CloudApiKeyManager(null);
|
|
462
|
-
try {
|
|
463
|
-
await manager.validateApiKey();
|
|
464
|
-
await this.assertTrue(false, 'Null API key should throw error');
|
|
465
|
-
} catch (error) {
|
|
466
|
-
await this.assertTrue(
|
|
467
|
-
error.message.includes('required') || error.message.includes('API key'),
|
|
468
|
-
'Null API key properly rejected',
|
|
469
|
-
error.message
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// Test invalid API key format
|
|
474
|
-
const invalidManager = new CloudApiKeyManager('invalid-key-format');
|
|
475
|
-
try {
|
|
476
|
-
await invalidManager.validateApiKey();
|
|
477
|
-
await this.assertTrue(false, 'Invalid key format should throw error');
|
|
478
|
-
} catch (error) {
|
|
479
|
-
await this.assertTrue(
|
|
480
|
-
error.message.includes('format') || error.message.includes('Invalid'),
|
|
481
|
-
'Invalid key format properly rejected',
|
|
482
|
-
error.message
|
|
483
|
-
);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
} catch (error) {
|
|
487
|
-
await this.assertTrue(false, 'Error handling test', error.message);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
async testPackageIntegrity() {
|
|
492
|
-
this.log('Testing Package Integrity...', 'test');
|
|
493
|
-
|
|
494
|
-
try {
|
|
495
|
-
// Test package.json integrity
|
|
496
|
-
const pkg = require('../package.json');
|
|
497
|
-
await this.assertTrue(pkg.name && pkg.version && pkg.main, 'Package.json has required fields');
|
|
498
|
-
|
|
499
|
-
// Test main module can be required
|
|
500
|
-
const mainModule = require('../index.js');
|
|
501
|
-
await this.assertTrue(typeof mainModule === 'object', 'Main module can be imported');
|
|
502
|
-
await this.assertTrue(typeof mainModule.MCPPromptOptimizer === 'function', 'Main class is exported');
|
|
503
|
-
|
|
504
|
-
// Test dependencies can be loaded
|
|
505
|
-
const sdk = require('@modelcontextprotocol/sdk/server/index.js');
|
|
506
|
-
await this.assertTrue(typeof sdk.Server === 'function', 'MCP SDK loads correctly');
|
|
507
|
-
|
|
508
|
-
// Test lib modules can be loaded
|
|
509
|
-
const apiKeyManager = require('../lib/api-key-manager.js');
|
|
510
|
-
await this.assertTrue(typeof apiKeyManager === 'function', 'API Key Manager loads correctly');
|
|
511
|
-
|
|
512
|
-
// Test package file structure
|
|
513
|
-
const files = await fs.readdir(path.join(__dirname, '..'));
|
|
514
|
-
const requiredFiles = ['index.js', 'package.json', 'lib', 'README.md'];
|
|
515
|
-
|
|
516
|
-
for (const file of requiredFiles) {
|
|
517
|
-
await this.assertTrue(files.includes(file), `Required file/directory exists: ${file}`);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
// Test lib directory structure
|
|
521
|
-
const libFiles = await fs.readdir(path.join(__dirname, '..', 'lib'));
|
|
522
|
-
const requiredLibFiles = ['api-key-manager.js'];
|
|
523
|
-
|
|
524
|
-
for (const file of requiredLibFiles) {
|
|
525
|
-
await this.assertTrue(libFiles.includes(file), `Required lib file exists: ${file}`);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
} catch (error) {
|
|
529
|
-
await this.assertTrue(false, 'Package integrity test', error.message);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
async testMCPProtocolCompliance() {
|
|
534
|
-
this.log('Testing MCP Protocol Compliance...', 'test');
|
|
535
|
-
|
|
536
|
-
try {
|
|
537
|
-
const server = new MCPPromptOptimizer();
|
|
538
|
-
|
|
539
|
-
// Test MCP server configuration
|
|
540
|
-
await this.assertTrue(
|
|
541
|
-
server.server.serverInfo.name === 'mcp-prompt-optimizer',
|
|
542
|
-
'MCP server name is correct'
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
await this.assertTrue(
|
|
546
|
-
server.server.serverInfo.version === packageJson.version,
|
|
547
|
-
'MCP server version matches package version'
|
|
548
|
-
);
|
|
549
|
-
|
|
550
|
-
// Test tool definitions would be returned correctly
|
|
551
|
-
// (We can't easily test the actual MCP handlers without setting up full MCP communication)
|
|
552
|
-
await this.assertTrue(typeof server.setupMCPHandlers === 'function', 'MCP handlers setup method exists');
|
|
553
|
-
|
|
554
|
-
// Test mock response format compliance
|
|
555
|
-
const mockOptimization = server.generateMockOptimization('test', ['clarity'], 'llm_interaction');
|
|
556
|
-
const formattedResponse = server.formatOptimizationResult(mockOptimization, { detectedContext: 'llm_interaction' });
|
|
557
|
-
|
|
558
|
-
await this.assertTrue(typeof formattedResponse === 'string', 'MCP response format is string');
|
|
559
|
-
await this.assertTrue(formattedResponse.includes('# ๐ฏ Optimized Prompt'), 'Response includes proper markdown header');
|
|
560
|
-
await this.assertTrue(formattedResponse.includes('**Confidence:**'), 'Response includes confidence metric');
|
|
561
|
-
|
|
562
|
-
} catch (error) {
|
|
563
|
-
await this.assertTrue(false, 'MCP protocol compliance test', error.message);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
async runAllTests() {
|
|
568
|
-
console.log(`๐ Starting Comprehensive Test Suite...\n`);
|
|
569
|
-
|
|
570
|
-
try {
|
|
571
|
-
await this.testPackageStructure();
|
|
572
|
-
console.log('');
|
|
573
|
-
|
|
574
|
-
await this.testCrossPlatformCompatibility();
|
|
575
|
-
console.log('');
|
|
576
|
-
|
|
577
|
-
await this.testApiKeyValidation();
|
|
578
|
-
console.log('');
|
|
579
|
-
|
|
580
|
-
await this.testApiKeyManagerFunctionality();
|
|
581
|
-
console.log('');
|
|
582
|
-
|
|
583
|
-
await this.testMCPServerFunctionality();
|
|
584
|
-
console.log('');
|
|
585
|
-
|
|
586
|
-
await this.testNetworkResilience();
|
|
587
|
-
console.log('');
|
|
588
|
-
|
|
589
|
-
await this.testCommandLineInterface();
|
|
590
|
-
console.log('');
|
|
591
|
-
|
|
592
|
-
await this.testEnvironmentVariables();
|
|
593
|
-
console.log('');
|
|
594
|
-
|
|
595
|
-
await this.testErrorHandling();
|
|
596
|
-
console.log('');
|
|
597
|
-
|
|
598
|
-
await this.testPackageIntegrity();
|
|
599
|
-
console.log('');
|
|
600
|
-
|
|
601
|
-
await this.testMCPProtocolCompliance();
|
|
602
|
-
console.log('');
|
|
603
|
-
|
|
604
|
-
} catch (error) {
|
|
605
|
-
this.log(`Test suite execution error: ${error.message}`, 'error');
|
|
606
|
-
this.testResults.failed++;
|
|
607
|
-
this.testResults.errors.push('Test suite execution');
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
this.generateReport();
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
generateReport() {
|
|
614
|
-
const duration = ((Date.now() - this.testStartTime) / 1000).toFixed(2);
|
|
615
|
-
const total = this.testResults.passed + this.testResults.failed;
|
|
616
|
-
const successRate = total > 0 ? ((this.testResults.passed / total) * 100).toFixed(1) : 0;
|
|
617
|
-
|
|
618
|
-
console.log('\n' + '='.repeat(80));
|
|
619
|
-
console.log('๐ COMPREHENSIVE TEST RESULTS REPORT');
|
|
620
|
-
console.log('='.repeat(80));
|
|
621
|
-
|
|
622
|
-
console.log(`๐ฆ Package: ${packageJson.name} v${packageJson.version}`);
|
|
623
|
-
console.log(`โฑ๏ธ Duration: ${duration} seconds`);
|
|
624
|
-
console.log(`๐ฅ๏ธ Platform: ${os.platform()} ${os.arch()}`);
|
|
625
|
-
console.log(`๐ API Key: ${this.hasApiKey ? 'Available' : 'Mock Mode'}`);
|
|
626
|
-
console.log();
|
|
627
|
-
|
|
628
|
-
console.log('๐ SUMMARY:');
|
|
629
|
-
console.log(`โ
Tests Passed: ${this.testResults.passed}`);
|
|
630
|
-
console.log(`โ Tests Failed: ${this.testResults.failed}`);
|
|
631
|
-
console.log(`โ ๏ธ Warnings: ${this.testResults.warnings}`);
|
|
632
|
-
console.log(`๐ Success Rate: ${successRate}%`);
|
|
633
|
-
console.log();
|
|
634
|
-
|
|
635
|
-
if (this.testResults.failed > 0) {
|
|
636
|
-
console.log('โ FAILED TESTS:');
|
|
637
|
-
this.testResults.errors.forEach(error => {
|
|
638
|
-
console.log(` โข ${error}`);
|
|
639
|
-
});
|
|
640
|
-
console.log();
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
if (this.testResults.warnings > 0) {
|
|
644
|
-
console.log('โ ๏ธ WARNINGS NOTED (non-critical):');
|
|
645
|
-
this.testResults.details
|
|
646
|
-
.filter(detail => detail.startsWith('โ ๏ธ'))
|
|
647
|
-
.forEach(warning => {
|
|
648
|
-
console.log(` โข ${warning.substring(2)}`);
|
|
649
|
-
});
|
|
650
|
-
console.log();
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// Publication readiness assessment
|
|
654
|
-
console.log('๐ PUBLICATION READINESS ASSESSMENT:');
|
|
655
|
-
if (this.testResults.failed === 0) {
|
|
656
|
-
console.log('โ
READY FOR NPM PUBLICATION');
|
|
657
|
-
console.log(' All critical tests passed successfully');
|
|
658
|
-
if (this.testResults.warnings > 0) {
|
|
659
|
-
console.log(' โน๏ธ Minor warnings noted but do not block publication');
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
console.log('\n๐ RECOMMENDED PUBLICATION STEPS:');
|
|
663
|
-
console.log(' 1. npm version patch # Increment version if needed');
|
|
664
|
-
console.log(' 2. npm publish # Publish to NPM registry');
|
|
665
|
-
console.log(' 3. git tag v' + packageJson.version + ' # Tag the release');
|
|
666
|
-
console.log(' 4. git push --tags # Push tags to repository');
|
|
667
|
-
|
|
668
|
-
} else {
|
|
669
|
-
console.log('โ NOT READY FOR PUBLICATION');
|
|
670
|
-
console.log(' Critical issues must be resolved before publishing');
|
|
671
|
-
console.log(' Please fix the failed tests and re-run this test suite');
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
console.log('\n' + '='.repeat(80));
|
|
675
|
-
console.log(`Test suite completed at ${new Date().toLocaleString()}`);
|
|
676
|
-
console.log('='.repeat(80) + '\n');
|
|
677
|
-
|
|
678
|
-
// Exit with appropriate code
|
|
679
|
-
process.exit(this.testResults.failed > 0 ? 1 : 0);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// Main execution
|
|
684
|
-
if (require.main === module) {
|
|
685
|
-
const testSuite = new ComprehensiveTestSuite();
|
|
686
|
-
testSuite.runAllTests().catch(error => {
|
|
687
|
-
console.error('โ Test suite crashed:', error);
|
|
688
|
-
process.exit(1);
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
module.exports = ComprehensiveTestSuite;
|