claude-flow
Version:
Enterprise-grade AI agent orchestration with WASM-powered ReasoningBank memory and AgentDB vector database (always uses latest agentic-flow)
251 lines (207 loc) โข 6.11 kB
text/typescript
/**
* MCP Test Runner
* Comprehensive test suite for the MCP implementation
*/
import { parseArgs } from 'https://deno.land/std@0.208.0/cli/parse_args.ts';
import { join } from 'https://deno.land/std@0.208.0/path/mod.ts';
interface TestConfig {
unit: boolean;
integration: boolean;
coverage: boolean;
watch: boolean;
filter?: string;
verbose: boolean;
}
async function runTests(config: TestConfig): Promise<void> {
const testFiles: string[] = [];
if (config.unit) {
console.log('๐ Discovering unit tests...');
const unitTests = await discoverTests('tests/unit', config.filter);
testFiles.push(...unitTests);
}
if (config.integration) {
console.log('๐ Discovering integration tests...');
const integrationTests = await discoverTests('tests/integration', config.filter);
testFiles.push(...integrationTests);
}
if (testFiles.length === 0) {
console.log('โ No test files found');
Deno.exit(1);
}
console.log(`๐ Found ${testFiles.length} test files:`);
for (const file of testFiles) {
console.log(` - ${file}`);
}
console.log();
// Build Deno test command
const args = [
'test',
'--allow-all',
'--unstable',
...testFiles,
];
if (config.coverage) {
args.push('--coverage=coverage');
}
if (config.watch) {
args.push('--watch');
}
if (config.verbose) {
args.push('--verbose');
}
console.log('๐งช Running tests...');
console.log(`Command: deno ${args.join(' ')}`);
console.log();
const process = new Deno.Command('deno', {
args,
stdout: 'inherit',
stderr: 'inherit',
});
const { code } = await process.output();
if (config.coverage && code === 0) {
console.log('\n๐ Generating coverage report...');
const coverageProcess = new Deno.Command('deno', {
args: ['coverage', '--html', 'coverage'],
stdout: 'inherit',
stderr: 'inherit',
});
await coverageProcess.output();
console.log('Coverage report generated in coverage/html/');
}
if (code !== 0) {
console.log('\nโ Tests failed');
Deno.exit(code);
}
console.log('\nโ
All tests passed!');
}
async function discoverTests(baseDir: string, filter?: string): Promise<string[]> {
const testFiles: string[] = [];
try {
for await (const entry of Deno.readDir(baseDir)) {
if (entry.isDirectory) {
const subDirTests = await discoverTests(
join(baseDir, entry.name),
filter
);
testFiles.push(...subDirTests);
} else if (entry.name.endsWith('.test.ts')) {
const filePath = join(baseDir, entry.name);
if (!filter || filePath.includes(filter)) {
testFiles.push(filePath);
}
}
}
} catch (error) {
if (!(error instanceof Deno.errors.NotFound)) {
throw error;
}
}
return testFiles;
}
async function validateEnvironment(): Promise<void> {
console.log('๐ง Validating environment...');
// Check Deno version
const { code, stdout } = await new Deno.Command('deno', {
args: ['--version'],
stdout: 'piped',
}).output();
if (code !== 0) {
console.error('โ Deno not found');
Deno.exit(1);
}
const versionOutput = new TextDecoder().decode(stdout);
console.log(`โ
${versionOutput.split('\n')[0]}`);
// Check required files exist
const requiredFiles = [
'src/mcp/server.ts',
'src/mcp/tools.ts',
'src/mcp/transports/stdio.ts',
'src/mcp/transports/http.ts',
'src/mcp/session-manager.ts',
'src/mcp/auth.ts',
'src/mcp/load-balancer.ts',
];
for (const file of requiredFiles) {
try {
await Deno.stat(file);
console.log(`โ
${file}`);
} catch {
console.error(`โ Missing required file: ${file}`);
Deno.exit(1);
}
}
console.log();
}
function printUsage(): void {
console.log(`
MCP Test Runner
Usage: deno run --allow-all scripts/test-mcp.ts [options]
Options:
--unit Run unit tests (default: true if no other type specified)
--integration Run integration tests
--all Run all tests (unit + integration)
--coverage Generate coverage report
--watch Watch files and re-run tests on changes
--filter <term> Filter test files by name
--verbose Verbose test output
--help, -h Show this help message
Examples:
deno run --allow-all scripts/test-mcp.ts
deno run --allow-all scripts/test-mcp.ts --all --coverage
deno run --allow-all scripts/test-mcp.ts --integration
deno run --allow-all scripts/test-mcp.ts --filter server
deno run --allow-all scripts/test-mcp.ts --watch --verbose
`);
}
async function main(): Promise<void> {
const args = parseArgs(Deno.args, {
boolean: [
'unit',
'integration',
'all',
'coverage',
'watch',
'verbose',
'help',
'h',
],
string: [
'filter',
],
alias: {
h: 'help',
},
});
if (args.help || args.h) {
printUsage();
return;
}
await validateEnvironment();
const config: TestConfig = {
unit: args.unit || args.all || (!args.integration && !args.all),
integration: args.integration || args.all,
coverage: args.coverage,
watch: args.watch,
filter: args.filter,
verbose: args.verbose,
};
console.log('โ๏ธ Test Configuration:');
console.log(` Unit tests: ${config.unit}`);
console.log(` Integration tests: ${config.integration}`);
console.log(` Coverage: ${config.coverage}`);
console.log(` Watch mode: ${config.watch}`);
console.log(` Filter: ${config.filter || 'none'}`);
console.log(` Verbose: ${config.verbose}`);
console.log();
await runTests(config);
}
// Performance monitoring
const startTime = performance.now();
process.on?.('exit', () => {
const duration = performance.now() - startTime;
console.log(`\nโฑ๏ธ Total execution time: ${(duration / 1000).toFixed(2)}s`);
});
if (import.meta.main) {
await main();
}