mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
- Adds `scripts/run-test-audit.sh` to automate unit test execution with coverage. - Adds `scripts/analyze-flakiness.mjs` to detect test flakiness. - Adds `scripts/static-test-analysis.mjs` to find suspicious test patterns. - Adds `scripts/coverage-gap-analysis.mjs` to identify critical coverage gaps. - Adds `scripts/generate-audit-report.mjs` to produce markdown reports. - Generates initial audit report `test-audit-report-2025-02-18.md` and `issues/ISSUE_test_audit_findings.md`. - Documents findings in `decisions/DECISIONS_2025-02-18.md`. Co-authored-by: PR0M3TH3AN <[email protected]>
79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const rootDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
const testsDir = path.join(rootDir, 'tests');
|
|
const outputFile = path.join(rootDir, 'test-audit', 'suspicious-tests.json');
|
|
|
|
const checks = {
|
|
zeroAssertions: {
|
|
pattern: /(expect\(|assert\.|t\.is|chai\.expect|should\.)/g,
|
|
inverse: true,
|
|
message: 'No assertions found'
|
|
},
|
|
focusedOrSkipped: {
|
|
pattern: /\.(only|skip)\(/g,
|
|
message: 'Focused or skipped test'
|
|
},
|
|
timeDependence: {
|
|
pattern: /(setTimeout|setInterval|sleep|delay)\(/g,
|
|
message: 'Time dependence (sleep/timeout)'
|
|
},
|
|
networkDependence: {
|
|
pattern: /(fetch|axios\.|new WebSocket|WebSocket\()/g,
|
|
message: 'Network dependence (fetch/WebSocket)'
|
|
},
|
|
consoleUsage: {
|
|
pattern: /console\.(log|warn|error)/g,
|
|
message: 'Console usage'
|
|
}
|
|
};
|
|
|
|
async function scanFile(filePath) {
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
const fileIssues = [];
|
|
|
|
for (const [key, check] of Object.entries(checks)) {
|
|
const matches = content.match(check.pattern);
|
|
if (check.inverse) {
|
|
if (!matches) {
|
|
fileIssues.push(check.message);
|
|
}
|
|
} else {
|
|
if (matches) {
|
|
fileIssues.push(`${check.message} (${matches.length} occurrences)`);
|
|
}
|
|
}
|
|
}
|
|
return fileIssues;
|
|
}
|
|
|
|
async function walk(dir) {
|
|
let results = {};
|
|
const list = fs.readdirSync(dir);
|
|
for (const file of list) {
|
|
if (file === 'node_modules' || file === 'visual' || file === 'e2e') continue;
|
|
const filePath = path.join(dir, file);
|
|
const stat = fs.statSync(filePath);
|
|
if (stat && stat.isDirectory()) {
|
|
Object.assign(results, await walk(filePath));
|
|
} else if (file.endsWith('.test.mjs') || file.endsWith('.test.js')) {
|
|
const issues = await scanFile(filePath);
|
|
if (issues.length > 0) {
|
|
results[path.relative(rootDir, filePath)] = issues;
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
async function main() {
|
|
console.log('Scanning tests for suspicious patterns...');
|
|
const suspiciousTests = await walk(testsDir);
|
|
fs.writeFileSync(outputFile, JSON.stringify(suspiciousTests, null, 2));
|
|
console.log(`Wrote suspicious tests to ${outputFile}`);
|
|
}
|
|
|
|
main();
|