UNPKG

credl-parser-evaluator

Version:

TypeScript-based CREDL Parser and Evaluator that processes CREDL files and outputs complete Intermediate Representations

346 lines โ€ข 13 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.createTestCommand = createTestCommand; exports.executeTestCommand = executeTestCommand; exports.runSingleFileTest = runSingleFileTest; exports.runJestTests = runJestTests; exports.buildJestArgs = buildJestArgs; const commander_1 = require("commander"); const path = __importStar(require("path")); const fs = __importStar(require("fs/promises")); const child_process_1 = require("child_process"); const index_1 = require("../../api/index"); // Error exit codes var ExitCode; (function (ExitCode) { ExitCode[ExitCode["SUCCESS"] = 0] = "SUCCESS"; ExitCode[ExitCode["TEST_FAILURE"] = 1] = "TEST_FAILURE"; ExitCode[ExitCode["FILE_NOT_FOUND"] = 2] = "FILE_NOT_FOUND"; ExitCode[ExitCode["INVALID_ARGUMENTS"] = 6] = "INVALID_ARGUMENTS"; ExitCode[ExitCode["GENERAL_ERROR"] = 10] = "GENERAL_ERROR"; })(ExitCode || (ExitCode = {})); function createTestCommand() { const testCommand = new commander_1.Command('test'); testCommand .description('Run CREDL tests and validation (developer command)') .option('-w, --watch', 'Run tests in watch mode') .option('-c, --coverage', 'Generate coverage report') .option('-s, --single <file>', 'Test a single CREDL file for validation') .option('-p, --pattern <pattern>', 'Run tests matching specific pattern') .option('-e, --examples', 'Run only example file tests') .option('--performance', 'Run only performance tests') .option('--ci', 'Run in CI mode (non-interactive)') .option('--max-workers <number>', 'Maximum number of worker processes', parseInt) .option('--timeout <number>', 'Test timeout in milliseconds', parseInt) .option('-v, --verbose', 'Verbose test output') .option('-q, --quiet', 'Suppress output except errors') .action(async (options) => { await executeTestCommand(options); }); return testCommand; } async function executeTestCommand(options) { try { if (!options.quiet) { console.log('๐Ÿงช CREDL Test Runner'); console.log(''); } // Handle single file validation if (options.single) { await runSingleFileTest(options.single, options); return; } // Handle Jest test execution await runJestTests(options); } catch (error) { console.error('โŒ Error running tests:'); if (error instanceof Error) { console.error(` ${error.message}`); if (options.verbose && error.stack) { console.error('\n๐Ÿ› Stack trace:'); console.error(error.stack); } } else { console.error(` ${String(error)}`); } process.exit(ExitCode.GENERAL_ERROR); } } async function runSingleFileTest(filePath, options) { if (!options.quiet) { console.log(`๐Ÿ” Testing single CREDL file: ${filePath}`); console.log(''); } // Validate file exists const resolvedPath = path.resolve(filePath); try { await fs.access(resolvedPath); } catch { console.error(`โŒ File not found: ${filePath}`); console.error(` Resolved path: ${resolvedPath}`); process.exit(ExitCode.FILE_NOT_FOUND); } const startTime = process.hrtime.bigint(); try { // Test parsing const parseStartTime = process.hrtime.bigint(); const parseResult = await (0, index_1.parseFileFromPath)(resolvedPath); const parseEndTime = process.hrtime.bigint(); const parseTime = Number(parseEndTime - parseStartTime) / 1000000; if (!parseResult.isValid) { console.error('โŒ Parsing failed:'); parseResult.errors.forEach(error => { console.error(` โ€ข ${error.message}`); }); if (parseResult.warnings.length > 0) { console.error('\nโš ๏ธ Warnings:'); parseResult.warnings.forEach(warning => { console.error(` โ€ข ${warning.message}`); }); } process.exit(ExitCode.TEST_FAILURE); } // Test IR generation const irStartTime = process.hrtime.bigint(); const ir = await (0, index_1.processFileFromPath)(resolvedPath); const irEndTime = process.hrtime.bigint(); const irTime = Number(irEndTime - irStartTime) / 1000000; const totalTime = Number(process.hrtime.bigint() - startTime) / 1000000; // Display results if (!options.quiet) { console.log('โœ… File validation successful!'); console.log(''); console.log('๐Ÿ“Š Test Results:'); console.log(` โ€ข File: ${path.basename(filePath)}`); console.log(` โ€ข Parse time: ${parseTime.toFixed(2)}ms`); console.log(` โ€ข IR generation: ${irTime.toFixed(2)}ms`); console.log(` โ€ข Total time: ${totalTime.toFixed(2)}ms`); console.log(''); console.log('๐Ÿ“‹ Content Summary:'); console.log(` โ€ข Assets: ${ir.assets.length}`); console.log(` โ€ข Spaces: ${ir.spaces.length}`); console.log(` โ€ข Assumptions: ${ir.assumptions.length}`); console.log(` โ€ข Models: ${ir.models.length}`); console.log(` โ€ข Valid: ${ir.validation.isValid ? 'โœ…' : 'โŒ'}`); if (ir.validation.errors.length > 0) { console.log(''); console.log('โŒ Validation Errors:'); ir.validation.errors.forEach(error => { console.log(` โ€ข ${error.message}`); }); } if (ir.validation.warnings.length > 0) { console.log(''); console.log('โš ๏ธ Validation Warnings:'); ir.validation.warnings.forEach(warning => { console.log(` โ€ข ${warning.message}`); }); } } // Performance analysis (verbose mode) if (options.verbose) { console.log(''); console.log('๐Ÿš€ Performance Analysis:'); if (ir.spaces.length > 0) { console.log(` โ€ข Time per space: ${(totalTime / ir.spaces.length).toFixed(3)}ms`); } if (totalTime > 1000) { console.log(' โš ๏ธ Processing time exceeded 1 second'); } else { console.log(' โœ… Processing within performance target (<1s)'); } // Additional verbose metrics console.log(` โ€ข Parse efficiency: ${(parseTime / totalTime * 100).toFixed(1)}% of total time`); console.log(` โ€ข IR generation: ${(irTime / totalTime * 100).toFixed(1)}% of total time`); if (ir.assumptions.length > 0) { console.log(` โ€ข Time per assumption: ${(totalTime / ir.assumptions.length).toFixed(3)}ms`); } // Memory recommendations if (ir.spaces.length > 50) { console.log(' ๐Ÿ’ก Large file detected - consider processing in batches for better performance'); } } if (!ir.validation.isValid) { process.exit(ExitCode.TEST_FAILURE); } } catch (error) { console.error('โŒ Test execution failed:'); if (error instanceof Error) { console.error(` ${error.message}`); } process.exit(ExitCode.TEST_FAILURE); } } async function runJestTests(options) { const jestArgs = buildJestArgs(options); if (!options.quiet) { console.log(`๐Ÿš€ Running Jest tests with: ${jestArgs.join(' ')}`); console.log(''); } return new Promise((resolve, reject) => { const jestProcess = (0, child_process_1.spawn)('npx', ['jest', ...jestArgs], { stdio: options.quiet ? 'pipe' : 'inherit', cwd: process.cwd(), env: { ...process.env, NODE_ENV: 'test', ...(options.ci && { CI: 'true' }) } }); let stdout = ''; let stderr = ''; if (options.quiet) { jestProcess.stdout?.on('data', (data) => { stdout += data.toString(); }); jestProcess.stderr?.on('data', (data) => { stderr += data.toString(); }); } jestProcess.on('close', (code) => { if (code === 0) { if (!options.quiet) { console.log('\nโœ… All tests passed!'); } // Parse test results for summary if (options.quiet && stdout) { const results = parseJestOutput(stdout); displayTestSummary(results, options); } resolve(); } else { if (options.quiet && stderr) { console.error('โŒ Tests failed:'); console.error(stderr); } if (!options.quiet) { console.log('\nโŒ Some tests failed'); } process.exit(ExitCode.TEST_FAILURE); } }); jestProcess.on('error', (error) => { console.error('โŒ Failed to start Jest:'); console.error(` ${error.message}`); reject(error); }); // Handle process termination process.on('SIGINT', () => { jestProcess.kill('SIGINT'); }); process.on('SIGTERM', () => { jestProcess.kill('SIGTERM'); }); }); } function buildJestArgs(options) { const args = []; // Watch mode if (options.watch) { args.push('--watch'); } // Coverage if (options.coverage) { args.push('--coverage'); } // Test pattern if (options.pattern) { args.push('--testNamePattern', options.pattern); } // Specific test suites if (options.examples) { args.push('examples/'); } else if (options.performance) { args.push('--testPathPattern', 'performance'); } // CI mode if (options.ci) { args.push('--ci'); args.push('--watchAll=false'); } // Worker configuration if (options.maxWorkers) { args.push('--maxWorkers', options.maxWorkers.toString()); } // Timeout if (options.timeout) { args.push('--testTimeout', options.timeout.toString()); } // Verbosity if (options.verbose) { args.push('--verbose'); } // Output format if (options.quiet) { args.push('--silent'); } return args; } function parseJestOutput(output) { // Simple Jest output parsing - in a real implementation you'd use Jest's programmatic API const lines = output.split('\n'); let passed = 0; let failed = 0; let skipped = 0; for (const line of lines) { if (line.includes('โœ“')) passed++; if (line.includes('โœ—')) failed++; if (line.includes('โ—‹ skipped')) skipped++; } return { success: failed === 0, duration: 0, // Would need to parse from Jest output passed, failed, skipped }; } function displayTestSummary(results, options) { if (options.quiet) { console.log(`โœ… Tests: ${results.passed} passed, ${results.failed} failed, ${results.skipped} skipped`); } } //# sourceMappingURL=test.js.map