mirror of
https://github.com/harivansh-afk/evaluclaude-harness.git
synced 2026-04-18 19:03:46 +00:00
101 lines
3 KiB
TypeScript
101 lines
3 KiB
TypeScript
import type { Runner, TestFramework, RunnerConfig, ExecutionResult, ExecutionOptions, SandboxConfig } from './types.js';
|
|
import { PytestRunner } from './pytest-runner.js';
|
|
import { VitestRunner, JestRunner } from './vitest-runner.js';
|
|
import { DEFAULT_SANDBOX_CONFIG } from './types.js';
|
|
|
|
export * from './types.js';
|
|
export { PytestRunner } from './pytest-runner.js';
|
|
export { VitestRunner, JestRunner } from './vitest-runner.js';
|
|
export { sandboxedExec } from './sandbox.js';
|
|
|
|
const runnerRegistry: Record<TestFramework, new () => Runner> = {
|
|
pytest: PytestRunner,
|
|
vitest: VitestRunner,
|
|
jest: JestRunner,
|
|
};
|
|
|
|
export function createRunner(framework: TestFramework): Runner {
|
|
const RunnerClass = runnerRegistry[framework];
|
|
if (!RunnerClass) {
|
|
throw new Error(`Unknown test framework: ${framework}`);
|
|
}
|
|
return new RunnerClass();
|
|
}
|
|
|
|
export async function runTests(
|
|
testDir: string,
|
|
options: ExecutionOptions,
|
|
sandboxConfig: SandboxConfig = DEFAULT_SANDBOX_CONFIG
|
|
): Promise<ExecutionResult> {
|
|
const runner = createRunner(options.framework);
|
|
|
|
const config: RunnerConfig = {
|
|
testDir,
|
|
outputFile: `.evaluclaude/results/${options.framework}-${Date.now()}.json`,
|
|
options,
|
|
sandboxConfig: options.sandbox ? sandboxConfig : undefined,
|
|
};
|
|
|
|
return runner.run(config);
|
|
}
|
|
|
|
export function detectTestFramework(testDir: string): TestFramework {
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const pythonFiles = fs.readdirSync(testDir).filter((f: string) => f.endsWith('.py'));
|
|
const tsFiles = fs.readdirSync(testDir).filter((f: string) => f.endsWith('.ts') || f.endsWith('.js'));
|
|
|
|
if (pythonFiles.length > tsFiles.length) {
|
|
return 'pytest';
|
|
}
|
|
|
|
const packageJsonPath = path.join(testDir, '..', 'package.json');
|
|
if (fs.existsSync(packageJsonPath)) {
|
|
try {
|
|
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
if (pkg.devDependencies?.jest || pkg.dependencies?.jest) {
|
|
return 'jest';
|
|
}
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
return 'vitest';
|
|
}
|
|
|
|
export function formatResults(result: ExecutionResult): string {
|
|
const lines: string[] = [];
|
|
|
|
lines.push('');
|
|
lines.push('📊 Test Execution Results');
|
|
lines.push('═'.repeat(40));
|
|
lines.push(` Total: ${result.summary.total}`);
|
|
lines.push(` ✅ Passed: ${result.summary.passed}`);
|
|
lines.push(` ❌ Failed: ${result.summary.failed}`);
|
|
lines.push(` ⏭️ Skipped: ${result.summary.skipped}`);
|
|
lines.push(` ⏱️ Duration: ${result.summary.duration}ms`);
|
|
|
|
if (result.errors.length > 0) {
|
|
lines.push('');
|
|
lines.push('⚠️ Errors:');
|
|
for (const error of result.errors) {
|
|
lines.push(` • ${error}`);
|
|
}
|
|
}
|
|
|
|
const failures = result.tests.filter(t => t.status === 'failed' || t.status === 'error');
|
|
if (failures.length > 0) {
|
|
lines.push('');
|
|
lines.push('❌ Failed Tests:');
|
|
for (const test of failures) {
|
|
lines.push(` • ${test.name}`);
|
|
if (test.error) {
|
|
lines.push(` ${test.error.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
lines.push('');
|
|
return lines.join('\n');
|
|
}
|