MIRROR: javascript for 🐜's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 149 lines 4.4 kB view raw
1import fs from 'ant:fs'; 2import path from 'ant:path'; 3 4const GREEN = '\x1b[32m'; 5const RED = '\x1b[31m'; 6const CYAN = '\x1b[36m'; 7const BOLD = '\x1b[1m'; 8const DIM = '\x1b[2m'; 9const RESET = '\x1b[0m'; 10 11const specDir = path.dirname(import.meta.url.replace('file://', '')); 12const nonSpecFiles = new Set(['run.js', 'helpers.js', 'import_abs_target.js']); 13 14const allFiles = fs 15 .readdirSync(specDir) 16 .filter(f => f.endsWith('.js') && !nonSpecFiles.has(f)) 17 .sort(); 18 19const cliArgs = process.argv.slice(2); 20const runAll = cliArgs.includes('--all'); 21const requestedSpecs = cliArgs.filter(arg => arg !== '--all'); 22 23function normalizeSpecName(arg) { 24 const base = path.basename(arg); 25 return base.endsWith('.js') ? base.slice(0, -3) : base; 26} 27 28const fileByName = new Map(allFiles.map(file => [path.basename(file, '.js'), file])); 29const files = (() => { 30 if (!runAll && requestedSpecs.length === 0) { 31 console.log(`${RED}No specs selected.${RESET} Use ${BOLD}--all${RESET} or pass one or more spec names.`); 32 process.exit(1); 33 } 34 if (runAll) return allFiles; 35 36 const selected = []; 37 const seen = new Set(); 38 const missing = []; 39 40 for (const raw of requestedSpecs) { 41 const name = normalizeSpecName(raw); 42 const file = fileByName.get(name); 43 44 if (!file) { 45 missing.push(raw); 46 continue; 47 } 48 49 if (seen.has(file)) continue; 50 seen.add(file); 51 selected.push(file); 52 } 53 54 if (missing.length > 0) console.log(`${RED}Unknown spec file(s):${RESET} ${missing.join(', ')}`); 55 if (selected.length === 0) process.exit(1); 56 57 return selected; 58})(); 59 60let totalPassed = 0; 61let totalFailed = 0; 62 63let filesPassed = 0; 64let filesFailed = 0; 65 66const fileTimes = []; 67const failedTests = []; 68 69console.log(`\n${BOLD}${CYAN}Running ${files.length} spec files...${RESET}\n`); 70const totalStart = performance.now(); 71 72async function runInProcessMode() { 73 const hook = { 74 current: null, 75 onSummary: null 76 }; 77 globalThis.__ANT_SPEC_HOOK__ = hook; 78 79 for (let i = 0; i < files.length; i++) { 80 const file = files[i]; 81 const name = path.basename(file, '.js'); 82 const fileUrl = `./${file}`; 83 const start = performance.now(); 84 85 hook.current = { passed: 0, failed: 0, failures: [] }; 86 let summaryResolve; 87 const summaryP = new Promise(resolve => { 88 summaryResolve = resolve; 89 }); 90 hook.onSummary = summaryResolve; 91 92 try { 93 await import(fileUrl); 94 const result = await summaryP; 95 const elapsed = performance.now() - start; 96 97 totalPassed += result.passed; 98 totalFailed += result.failed; 99 if (result.failures.length > 0) { 100 failedTests.push({ name, failures: result.failures }); 101 } 102 103 if (result.failed === 0) { 104 console.log(`${GREEN}${RESET} ${name} ${DIM}(${elapsed.toFixed(0)}ms)${RESET}\n`); 105 filesPassed++; 106 } else { 107 console.log(`${RED}${RESET} ${name} ${DIM}(${elapsed.toFixed(0)}ms)${RESET}\n`); 108 filesFailed++; 109 } 110 fileTimes.push({ name, elapsed }); 111 } catch (e) { 112 const elapsed = performance.now() - start; 113 console.log(`${RED}${RESET} ${name} ${DIM}(error, ${elapsed.toFixed(0)}ms)${RESET}\n`); 114 if (e && e.stack) console.log(String(e.stack)); 115 else console.log(String(e)); 116 filesFailed++; 117 totalFailed++; 118 failedTests.push({ name, failures: [`${RED}${RESET} import/exec error`] }); 119 fileTimes.push({ name, elapsed }); 120 } finally { 121 hook.onSummary = null; 122 hook.current = null; 123 } 124 } 125} 126 127await runInProcessMode(); 128const totalElapsed = performance.now() - totalStart; 129 130console.log(`\n${BOLD}Results:${RESET}`); 131console.log(` ${GREEN}${totalPassed} tests passed${RESET}`); 132console.log(` ${RED}${totalFailed} tests failed${RESET}`); 133console.log(` ${GREEN}${filesPassed} files passed${RESET}`); 134console.log(` ${RED}${filesFailed} files failed${RESET}`); 135 136console.log(`\n${BOLD}Timing:${RESET}`); 137for (const { name, elapsed } of fileTimes) console.log(` ${DIM}${name.padEnd(30)}${RESET} ${elapsed.toFixed(0)}ms`); 138console.log(`\n ${BOLD}Total${RESET}${' '.padEnd(26)}${totalElapsed.toFixed(0)}ms\n`); 139 140if (failedTests.length > 0) { 141 console.log(`${BOLD}${RED}Failed Tests:${RESET}`); 142 for (const { name, failures } of failedTests) { 143 console.log(`\n ${BOLD}${name}${RESET}`); 144 for (const line of failures) console.log(` ${line.trim()}`); 145 } 146 console.log(); 147} 148 149process.exit(totalFailed > 0 ? 1 : 0);