UNPKG

jay-code

Version:

Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability

302 lines (262 loc) โ€ข 8.55 kB
#!/usr/bin/env -S deno run --allow-all /** * Test runner specifically for the init command tests * Runs all unit, integration, and performance tests for the init command */ import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts"; import { join } from "@std/path/mod.ts"; import { exists } from "@std/fs/mod.ts"; interface TestSuite { name: string; path: string; type: "unit" | "integration" | "performance"; description: string; } const TEST_SUITES: TestSuite[] = [ { name: "init-command", path: "tests/unit/cli/commands/init/init-command.test.ts", type: "unit", description: "Core init command functionality" }, { name: "templates", path: "tests/unit/cli/commands/init/templates.test.ts", type: "unit", description: "Template generation and content validation" }, { name: "sparc-structure", path: "tests/unit/cli/commands/init/sparc-structure.test.ts", type: "unit", description: "SPARC structure creation and validation" }, { name: "validation", path: "tests/unit/cli/commands/init/validation.test.ts", type: "unit", description: "File integrity and configuration validation" }, { name: "rollback", path: "tests/unit/cli/commands/init/rollback.test.ts", type: "unit", description: "Error handling and rollback functionality" }, { name: "full-init-flow", path: "tests/integration/cli/init/full-init-flow.test.ts", type: "integration", description: "Complete initialization flow integration" }, { name: "selective-modes", path: "tests/integration/cli/init/selective-modes.test.ts", type: "integration", description: "Selective mode initialization (minimal, SPARC, etc.)" }, { name: "e2e-workflow", path: "tests/integration/cli/init/e2e-workflow.test.ts", type: "integration", description: "End-to-end workflow and real-world scenarios" }, { name: "init-performance", path: "tests/performance/cli/init/init-performance.test.ts", type: "performance", description: "Performance and resource usage validation" } ]; async function runTests( suites: TestSuite[], options: { verbose?: boolean; coverage?: boolean; failFast?: boolean; parallel?: boolean; } = {} ): Promise<boolean> { console.log(`๐Ÿงช Running ${suites.length} test suite(s) for init command\n`); const results: Array<{ suite: TestSuite; success: boolean; duration: number; output: string }> = []; for (const suite of suites) { console.log(`๐Ÿ“‹ Running ${suite.name} (${suite.type}): ${suite.description}`); // Check if test file exists if (!await exists(suite.path)) { console.log(` โŒ Test file not found: ${suite.path}`); results.push({ suite, success: false, duration: 0, output: "Test file not found" }); if (options.failFast) break; continue; } const startTime = performance.now(); const denoArgs = [ "test", "--allow-all", "--no-check", suite.path ]; if (options.coverage) { denoArgs.push("--coverage=coverage"); } if (options.failFast) { denoArgs.push("--fail-fast"); } const command = new Deno.Command("deno", { args: denoArgs, stdout: options.verbose ? "inherit" : "piped", stderr: options.verbose ? "inherit" : "piped" }); try { const result = await command.output(); const endTime = performance.now(); const duration = endTime - startTime; const output = options.verbose ? "" : new TextDecoder().decode(result.stdout) + new TextDecoder().decode(result.stderr); if (result.success) { console.log(` โœ… Passed in ${duration.toFixed(2)}ms`); } else { console.log(` โŒ Failed in ${duration.toFixed(2)}ms`); if (!options.verbose) { console.log(` Error output:\n${output}`); } } results.push({ suite, success: result.success, duration, output }); if (!result.success && options.failFast) { break; } } catch (error) { const endTime = performance.now(); const duration = endTime - startTime; console.log(` โŒ Error running test: ${error.message}`); results.push({ suite, success: false, duration, output: `Error: ${error.message}` }); if (options.failFast) { break; } } } // Summary console.log("\n๐Ÿ“Š Test Results Summary:"); console.log("=" .repeat(60)); const passed = results.filter(r => r.success).length; const failed = results.filter(r => r.success === false).length; const totalDuration = results.reduce((sum, r) => sum + r.duration, 0); console.log(`Total suites: ${results.length}`); console.log(`Passed: ${passed}`); console.log(`Failed: ${failed}`); console.log(`Total time: ${(totalDuration / 1000).toFixed(2)}s`); if (failed > 0) { console.log("\nโŒ Failed test suites:"); for (const result of results) { if (!result.success) { console.log(` - ${result.suite.name}: ${result.suite.description}`); } } } // Generate coverage report if requested if (options.coverage && passed > 0) { console.log("\n๐Ÿ“ˆ Generating coverage report..."); try { const coverageCommand = new Deno.Command("deno", { args: ["coverage", "coverage", "--html"], stdout: "inherit", stderr: "inherit" }); await coverageCommand.output(); console.log("Coverage report generated in coverage/ directory"); } catch (error) { console.log(`Error generating coverage: ${error.message}`); } } return failed === 0; } async function main() { const args = parseArgs(Deno.args, { boolean: ["help", "verbose", "coverage", "fail-fast", "unit", "integration", "performance", "list"], string: ["suite"], alias: { h: "help", v: "verbose", c: "coverage", f: "fail-fast", s: "suite", l: "list" } }); if (args.help) { console.log(` ๐Ÿงช Init Command Test Runner Usage: deno run --allow-all scripts/test-init-command.ts [options] Options: -h, --help Show this help message -v, --verbose Show detailed test output -c, --coverage Generate coverage report -f, --fail-fast Stop on first failure -s, --suite <name> Run specific test suite -l, --list List available test suites --unit Run only unit tests --integration Run only integration tests --performance Run only performance tests Examples: ./scripts/test-init-command.ts # Run all tests ./scripts/test-init-command.ts --unit # Run only unit tests ./scripts/test-init-command.ts --suite templates # Run specific suite ./scripts/test-init-command.ts --coverage # Run with coverage `); return; } if (args.list) { console.log("๐Ÿ“‹ Available test suites:\n"); for (const suite of TEST_SUITES) { console.log(` ${suite.name.padEnd(20)} (${suite.type.padEnd(11)}) - ${suite.description}`); } return; } let suitesToRun = TEST_SUITES; // Filter by type if (args.unit) { suitesToRun = suitesToRun.filter(suite => suite.type === "unit"); } else if (args.integration) { suitesToRun = suitesToRun.filter(suite => suite.type === "integration"); } else if (args.performance) { suitesToRun = suitesToRun.filter(suite => suite.type === "performance"); } // Filter by specific suite if (args.suite) { const requestedSuite = suitesToRun.find(suite => suite.name === args.suite); if (!requestedSuite) { console.error(`โŒ Test suite '${args.suite}' not found.`); console.log("\nAvailable suites:"); for (const suite of TEST_SUITES) { console.log(` - ${suite.name}`); } Deno.exit(1); } suitesToRun = [requestedSuite]; } if (suitesToRun.length === 0) { console.error("โŒ No test suites to run"); Deno.exit(1); } console.log(`๐Ÿš€ Claude Flow Init Command Test Suite`); console.log(`Running ${suitesToRun.length} test suite(s)\n`); const success = await runTests(suitesToRun, { verbose: args.verbose, coverage: args.coverage, failFast: args["fail-fast"] }); if (success) { console.log("\nโœ… All tests passed!"); Deno.exit(0); } else { console.log("\nโŒ Some tests failed!"); Deno.exit(1); } } if (import.meta.main) { await main(); }