#!/usr/bin/env node /** * Local Testing Script * Validates TypeScript compilation and runs tests without requiring GitHub webhooks/PRs * * Usage: * npm run test:local - Run all tests * npm run test:local:patch - Test patch-utils only * npm run test:local:review - Test review integration only * npm run test:local:unit - Run unit tests only * npm run test:local:coverage - Run with coverage */ const { spawn } = require('child_process'); const path = require('path'); const args = process.argv.slice(2); const testArg = args[0] || 'all'; const testCommands = { all: ['npm', ['run', 'build', '&&', 'npm', 'run', 'test', '--', '--passWithNoTests'], { shell: true }], patch: ['npm', ['run', 'test', '--', '--testPathPattern', 'patch-utils', '--verbose']], review: ['npm', ['run', 'test', '--', '--testPathPattern', 'review.integration', '--verbose']], unit: ['npm', ['run', 'test', '--', '--testPathIgnorePatterns', 'integration', '--verbose']], coverage: ['npm', ['run', 'test', '--', '--coverage', '--coverageReporters', ['text', 'lcov', 'html']], watch: ['npm', ['run', 'test', '--', '--watch', '--testPathPattern', 'patch-utils']], }; function runCommand(cmd, args, options = {}) { return new Promise((resolve, reject) => { console.log(`\nšŸ”§ Running: ${cmd} ${args.join(' ')}\n`); const child = spawn(cmd, args, { stdio: 'inherit', cwd: path.resolve(__dirname, '..'), ...options, }); child.on('exit', (code) => { if (code === 0) { console.log(`\nāœ… Command succeeded: ${cmd} ${args.join(' ')}`); resolve(code); } else { console.error(`\nāŒ Command failed with code ${code}`); reject(code); } }); child.on('error', (err) => { console.error(`\nāŒ Command error: ${err.message}`); reject(err); }); }); } async function main() { console.log('╔════════════════════════════════════════════════════════════╗'); console.log('ā•‘ PRIX Local Testing System ā•‘'); console.log('ā•‘ Test your changes without raising PRs! ā•‘'); console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n'); const testTypes = { all: 'Run all tests (build + unit + integration)', patch: 'Run patch-utils tests only', review: 'Run review integration tests only', unit: 'Run unit tests only (exclude integration)', coverage: 'Run all tests with coverage report', watch: 'Watch mode for patch-utils', }; if (testArg === 'help' || testArg === '--help') { console.log('Usage: npm run test:local [test-type]\n'); console.log('Available test types:\n'); Object.entries(testTypes).forEach(([key, desc]) => { console.log(` ${key.padEnd(12)} - ${desc}`); }); console.log('\nExamples:'); console.log(' npm run test:local # Run all tests'); console.log(' npm run test:local patch # Test patch-utils only'); console.log(' npm run test:local coverage # Run with coverage'); process.exit(0); } const selectedTest = testCommands[testArg]; if (!selectedTest) { console.error(`āŒ Unknown test type: ${testArg}`); console.error('Run "npm run test:local help" for available options.'); process.exit(1); } try { await runCommand(selectedTest[0], selectedTest[1], selectedTest[2] || {}); console.log('\n╔════════════════════════════════════════════════════════════╗'); console.log('ā•‘ TESTS PASSED ā•‘'); console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n'); } catch (code) { console.log('\n╔════════════════════════════════════════════════════════════╗'); console.log('ā•‘ TESTS FAILED ā•‘'); console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n'); process.exit(code || 1); } } main().catch((err) => { console.error('Fatal error:', err); process.exit(1); });