hivecast-sdk/scripts/run-node-tests.cjs

105 lines
2.8 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
const { execFileSync } = require('child_process');
const { globSync } = require('glob');
const path = require('path');
const fs = require('fs');
const args = process.argv.slice(2);
const nodeArgs = ['--import', 'tsx'];
const patterns = [];
const excludePatterns = [];
let perFile = false;
const nodeMajor = Number.parseInt(process.versions.node.split('.')[0], 10);
const nativeTestArgs = nodeMajor >= 22 ? ['--test-force-exit'] : [];
// Derive a unique package name for JUnit XML output
function getPackageName() {
try {
const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
return (pkg.name || 'unknown').replace(/[^a-zA-Z0-9-]/g, '_');
} catch {
return 'unknown';
}
}
let i = 0;
while (i < args.length) {
const arg = args[i];
if (arg === '--') {
i += 1;
break;
}
if (arg === '--per-file') {
perFile = true;
i += 1;
continue;
}
if (arg === '--exclude') {
const value = args[i + 1];
if (!value) {
console.error('Missing value for --exclude');
process.exit(1);
}
excludePatterns.push(value);
i += 2;
continue;
}
if (arg === '--import') {
const value = args[i + 1];
if (!value) {
console.error('Missing value for --import');
process.exit(1);
}
nodeArgs.push(arg, value);
i += 2;
continue;
}
nodeArgs.push(arg);
i += 1;
}
patterns.push(...args.slice(i));
if (patterns.length === 0) {
console.error('No test patterns provided');
process.exit(1);
}
const files = [...new Set(patterns.flatMap((pattern) => globSync(pattern)).sort())];
const excluded = new Set(excludePatterns.flatMap((pattern) => globSync(pattern)));
const filteredFiles = files.filter((file) => !excluded.has(file));
if (filteredFiles.length === 0) {
console.error('No test files found for patterns:', patterns.join(', '));
process.exit(1);
}
// When CI_JUNIT_DIR is set, add dual reporter: spec to stdout + junit to file
const junitArgs = [];
if (process.env.CI_JUNIT_DIR) {
const junitDir = process.env.CI_JUNIT_DIR;
const pkgName = getPackageName();
const junitFile = path.join(junitDir, `${pkgName}.xml`);
fs.mkdirSync(junitDir, { recursive: true });
junitArgs.push(
'--test-reporter=spec', '--test-reporter-destination=stdout',
'--test-reporter=junit', `--test-reporter-destination=${junitFile}`
);
}
const testRunnerArgs = junitArgs.length > 0 ? junitArgs : [];
if (perFile) {
for (const file of filteredFiles) {
execFileSync(process.execPath, [...nodeArgs, ...testRunnerArgs, ...nativeTestArgs, '--test', file], {
cwd: process.cwd(),
stdio: 'inherit',
});
}
} else {
execFileSync(process.execPath, [...nodeArgs, ...testRunnerArgs, ...nativeTestArgs, '--test', ...filteredFiles], {
cwd: process.cwd(),
stdio: 'inherit',
});
}