neo-neo-bblessed
Version:
A fork of neo-blessed (which is a fork of blessed) with bug fixes and maintenance.
173 lines (145 loc) โข 4.94 kB
text/typescript
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const testDir = path.join(__dirname, 'test');
const testFiles = fs.readdirSync(testDir)
.filter(file => file.startsWith('widget-') && file.endsWith('.ts'))
.sort();
testFiles.unshift('widget.ts');
const knownIssues = {
'widget-play.ts': 'Missing frames.json file',
'widget-shrink-fail.ts': 'Uses "blessed" instead of "../" (intentional failure test)',
'widget-shrink-fail-2.ts': 'Uses "blessed" instead of "../" (intentional failure test)',
'widget-term-blessed.ts': 'RangeError: Invalid array length in Terminal',
'widget-video.ts': 'RangeError: Invalid array length in Terminal',
'widget-huge-content.ts': 'Slow test - takes 5+ seconds',
'widget-image.ts': 'Slow test - takes 7+ seconds'
};
console.log(`Found ${testFiles.length} test files to run`);
let passedTests = 0;
let failedTests = 0;
const results = [];
async function runTest(testFile) {
return new Promise((resolve) => {
const testPath = path.join(testDir, testFile);
const startTime = Date.now();
console.log(`\n๐งช Testing: ${testFile}`);
const isKnownIssue = knownIssues[testFile];
if (isKnownIssue) {
console.log(` โ ๏ธ SKIP (0ms) - Known issue: ${isKnownIssue}`);
passedTests++;
results.push({
file: testFile,
success: true,
knownIssue: isKnownIssue,
duration: 0
});
return resolve();
}
const child = spawn('node', ['-r', 'ts-node/register', testPath], {
stdio: ['pipe', 'pipe', 'pipe'],
env: { ...process.env, TERM: 'xterm-256color' }
});
let stdout = '';
let stderr = '';
let hasOutput = false;
let ttyDetected = false;
let initialTtyTimeout;
child.stdout.on('data', (data) => {
const chunk = data.toString();
stdout += chunk;
hasOutput = true;
if (chunk.includes('\x1b[') || chunk.includes('\u001b[')) {
hasOutput = 'tty';
if (!ttyDetected) {
ttyDetected = true;
clearTimeout(initialTtyTimeout);
setTimeout(() => {
child.kill('SIGTERM');
}, 50);
}
}
});
child.stderr.on('data', (data) => {
stderr += data.toString();
});
initialTtyTimeout = setTimeout(() => {
child.kill('SIGTERM');
setTimeout(() => {
if (!child.killed) {
child.kill('SIGKILL');
}
}, 500);
}, 2000);
child.on('exit', (code, signal) => {
clearTimeout(initialTtyTimeout);
const duration = Date.now() - startTime;
const result = {
file: testFile,
success: signal === 'SIGTERM' || signal === 'SIGKILL' || code === 0,
code,
signal,
duration,
hasOutput,
stdout: stdout.slice(0, 200),
stderr: stderr.slice(0, 200)
};
if (result.success) {
const outputIndicator = hasOutput === 'tty' ? '๐ฅ๏ธ' : hasOutput ? '๐' : '๐';
console.log(` โ
PASS (${duration}ms) ${outputIndicator} - ${signal ? 'terminated cleanly' : 'exited normally'}`);
passedTests++;
} else {
console.log(` โ FAIL (${duration}ms) - code: ${code}, signal: ${signal}`);
if (stderr) {
console.log(` Error: ${stderr.slice(0, 100)}...`);
}
failedTests++;
}
results.push(result);
resolve(result);
});
child.on('error', (err) => {
clearTimeout(initialTtyTimeout);
console.log(` โ ERROR - ${err.message}`);
failedTests++;
results.push({
file: testFile,
success: false,
error: err.message,
duration: Date.now() - startTime
});
resolve();
});
});
}
async function runAllTests() {
console.log('๐ Starting neo-neo-blessed test runner\n');
for (const testFile of testFiles) {
await runTest(testFile);
await new Promise(resolve => setTimeout(resolve, 100));
}
console.log('\n' + '='.repeat(50));
console.log('๐ TEST SUMMARY');
console.log('='.repeat(50));
console.log(`Total tests: ${testFiles.length}`);
console.log(`Passed: ${passedTests} โ
`);
console.log(`Failed: ${failedTests} โ`);
console.log(`Success rate: ${((passedTests / testFiles.length) * 100).toFixed(1)}%`);
if (failedTests > 0) {
console.log('\nโ FAILED TESTS:');
results.filter(r => !r.success).forEach(result => {
console.log(` - ${result.file}: ${result.error || result.code || 'unknown error'}`);
});
}
console.log('\n' + '='.repeat(50));
process.exit(failedTests > 0 ? 1 : 0);
}
process.on('SIGINT', () => {
console.log('\n\nโ ๏ธ Test runner interrupted');
process.exit(1);
});
runAllTests().catch(err => {
console.error('Test runner failed:', err);
process.exit(1);
});