@kevinrabun/judges 3.55.0 → 3.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/api-versioning-audit.d.ts +6 -0
- package/dist/commands/api-versioning-audit.d.ts.map +1 -0
- package/dist/commands/api-versioning-audit.js +234 -0
- package/dist/commands/api-versioning-audit.js.map +1 -0
- package/dist/commands/boundary-enforce.d.ts +6 -0
- package/dist/commands/boundary-enforce.d.ts.map +1 -0
- package/dist/commands/boundary-enforce.js +256 -0
- package/dist/commands/boundary-enforce.js.map +1 -0
- package/dist/commands/cache-audit.d.ts +5 -0
- package/dist/commands/cache-audit.d.ts.map +1 -0
- package/dist/commands/cache-audit.js +220 -0
- package/dist/commands/cache-audit.js.map +1 -0
- package/dist/commands/comment-drift.d.ts +5 -0
- package/dist/commands/comment-drift.d.ts.map +1 -0
- package/dist/commands/comment-drift.js +229 -0
- package/dist/commands/comment-drift.js.map +1 -0
- package/dist/commands/error-taxonomy.d.ts +6 -0
- package/dist/commands/error-taxonomy.d.ts.map +1 -0
- package/dist/commands/error-taxonomy.js +227 -0
- package/dist/commands/error-taxonomy.js.map +1 -0
- package/dist/commands/error-ux.d.ts +5 -0
- package/dist/commands/error-ux.d.ts.map +1 -0
- package/dist/commands/error-ux.js +253 -0
- package/dist/commands/error-ux.js.map +1 -0
- package/dist/commands/event-leak.d.ts +5 -0
- package/dist/commands/event-leak.d.ts.map +1 -0
- package/dist/commands/event-leak.js +263 -0
- package/dist/commands/event-leak.js.map +1 -0
- package/dist/commands/idempotency-audit.d.ts +5 -0
- package/dist/commands/idempotency-audit.d.ts.map +1 -0
- package/dist/commands/idempotency-audit.js +223 -0
- package/dist/commands/idempotency-audit.js.map +1 -0
- package/dist/commands/log-quality.d.ts +6 -0
- package/dist/commands/log-quality.d.ts.map +1 -0
- package/dist/commands/log-quality.js +212 -0
- package/dist/commands/log-quality.js.map +1 -0
- package/dist/commands/null-safety-audit.d.ts +6 -0
- package/dist/commands/null-safety-audit.d.ts.map +1 -0
- package/dist/commands/null-safety-audit.js +222 -0
- package/dist/commands/null-safety-audit.js.map +1 -0
- package/dist/commands/ownership-map.d.ts +6 -0
- package/dist/commands/ownership-map.d.ts.map +1 -0
- package/dist/commands/ownership-map.js +229 -0
- package/dist/commands/ownership-map.js.map +1 -0
- package/dist/commands/privilege-path.d.ts +5 -0
- package/dist/commands/privilege-path.d.ts.map +1 -0
- package/dist/commands/privilege-path.js +234 -0
- package/dist/commands/privilege-path.js.map +1 -0
- package/dist/commands/retry-pattern-audit.d.ts +6 -0
- package/dist/commands/retry-pattern-audit.d.ts.map +1 -0
- package/dist/commands/retry-pattern-audit.js +216 -0
- package/dist/commands/retry-pattern-audit.js.map +1 -0
- package/dist/commands/test-isolation.d.ts +6 -0
- package/dist/commands/test-isolation.d.ts.map +1 -0
- package/dist/commands/test-isolation.js +235 -0
- package/dist/commands/test-isolation.js.map +1 -0
- package/dist/commands/timeout-audit.d.ts +5 -0
- package/dist/commands/timeout-audit.d.ts.map +1 -0
- package/dist/commands/timeout-audit.js +211 -0
- package/dist/commands/timeout-audit.js.map +1 -0
- package/dist/commands/type-boundary.d.ts +5 -0
- package/dist/commands/type-boundary.d.ts.map +1 -0
- package/dist/commands/type-boundary.js +236 -0
- package/dist/commands/type-boundary.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry pattern audit — analyze retry, backoff, and circuit-breaker patterns
|
|
3
|
+
* for correctness and consistency.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
6
|
+
import { join, extname } from "path";
|
|
7
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
8
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".rs"]);
|
|
9
|
+
function collectFiles(dir, max = 300) {
|
|
10
|
+
const files = [];
|
|
11
|
+
function walk(d) {
|
|
12
|
+
if (files.length >= max)
|
|
13
|
+
return;
|
|
14
|
+
let entries;
|
|
15
|
+
try {
|
|
16
|
+
entries = readdirSync(d);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const e of entries) {
|
|
22
|
+
if (files.length >= max)
|
|
23
|
+
return;
|
|
24
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
25
|
+
continue;
|
|
26
|
+
const full = join(d, e);
|
|
27
|
+
try {
|
|
28
|
+
if (statSync(full).isDirectory())
|
|
29
|
+
walk(full);
|
|
30
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
31
|
+
files.push(full);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* skip */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
walk(dir);
|
|
39
|
+
return files;
|
|
40
|
+
}
|
|
41
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
42
|
+
function analyzeFile(filepath) {
|
|
43
|
+
const issues = [];
|
|
44
|
+
let content;
|
|
45
|
+
try {
|
|
46
|
+
content = readFileSync(filepath, "utf-8");
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return issues;
|
|
50
|
+
}
|
|
51
|
+
const lines = content.split("\n");
|
|
52
|
+
for (let i = 0; i < lines.length; i++) {
|
|
53
|
+
const line = lines[i];
|
|
54
|
+
// Unbounded retry loops
|
|
55
|
+
if (/while\s*\(\s*true\s*\)|for\s*\(\s*;\s*;\s*\)/.test(line)) {
|
|
56
|
+
const block = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
|
|
57
|
+
if (/retry|attempt|fetch|request|connect/i.test(block) &&
|
|
58
|
+
!/maxRetries|maxAttempts|retryLimit|MAX_RETRIES/i.test(block)) {
|
|
59
|
+
issues.push({
|
|
60
|
+
file: filepath,
|
|
61
|
+
line: i + 1,
|
|
62
|
+
issue: "Unbounded retry loop",
|
|
63
|
+
severity: "critical",
|
|
64
|
+
detail: "Infinite retry without max attempts — will loop forever on persistent failures",
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Fixed delay (no backoff)
|
|
69
|
+
if (/(?:sleep|setTimeout|time\.Sleep|Thread\.sleep|delay)\s*\(\s*\d+\s*\)/i.test(line)) {
|
|
70
|
+
const block = lines.slice(Math.max(0, i - 5), Math.min(i + 5, lines.length)).join("\n");
|
|
71
|
+
if (/retry|attempt|retries/i.test(block) && !/exponential|backoff|Math\.pow|Math\.min|\*\s*2/i.test(block)) {
|
|
72
|
+
issues.push({
|
|
73
|
+
file: filepath,
|
|
74
|
+
line: i + 1,
|
|
75
|
+
issue: "Fixed retry delay",
|
|
76
|
+
severity: "high",
|
|
77
|
+
detail: "Use exponential backoff with jitter to avoid thundering herd",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Missing jitter
|
|
82
|
+
if (/exponential|backoff|Math\.pow.*2/i.test(line)) {
|
|
83
|
+
const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
|
|
84
|
+
if (!/jitter|Math\.random|random|rand\b/i.test(block)) {
|
|
85
|
+
issues.push({
|
|
86
|
+
file: filepath,
|
|
87
|
+
line: i + 1,
|
|
88
|
+
issue: "Backoff without jitter",
|
|
89
|
+
severity: "medium",
|
|
90
|
+
detail: "Add random jitter to prevent synchronized retry storms",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Retrying non-idempotent operations
|
|
95
|
+
if (/retry.*(?:POST|PUT|DELETE|INSERT|UPDATE|create|write)/i.test(line) ||
|
|
96
|
+
/(?:POST|create|write).*retry/i.test(line)) {
|
|
97
|
+
issues.push({
|
|
98
|
+
file: filepath,
|
|
99
|
+
line: i + 1,
|
|
100
|
+
issue: "Retrying non-idempotent operation",
|
|
101
|
+
severity: "high",
|
|
102
|
+
detail: "POSTs/writes may duplicate data on retry — ensure idempotency keys",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Hardcoded retry counts
|
|
106
|
+
if (/(?:maxRetries|retryCount|attempts)\s*[:=]\s*\d{2,}/i.test(line)) {
|
|
107
|
+
issues.push({
|
|
108
|
+
file: filepath,
|
|
109
|
+
line: i + 1,
|
|
110
|
+
issue: "High retry count",
|
|
111
|
+
severity: "medium",
|
|
112
|
+
detail: "Large retry counts delay failure detection — consider circuit breaker",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Catching all errors for retry (no differentiation)
|
|
116
|
+
if (/catch\s*\(\s*\w*\s*\)/.test(line)) {
|
|
117
|
+
const block = lines.slice(i, Math.min(i + 8, lines.length)).join("\n");
|
|
118
|
+
if (/retry|continue|attempt/i.test(block) &&
|
|
119
|
+
!/status|code|instanceof|isRetryable|isTransient|4\d{2}|5\d{2}/i.test(block)) {
|
|
120
|
+
issues.push({
|
|
121
|
+
file: filepath,
|
|
122
|
+
line: i + 1,
|
|
123
|
+
issue: "Retrying all errors indiscriminately",
|
|
124
|
+
severity: "high",
|
|
125
|
+
detail: "Only retry transient errors (5xx, timeouts) — 4xx errors won't resolve on retry",
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Missing circuit breaker for external calls
|
|
130
|
+
if (/(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(line)) {
|
|
131
|
+
const fileContent = content;
|
|
132
|
+
if (/retry|retries|maxAttempts/i.test(fileContent) &&
|
|
133
|
+
!/circuit.?breaker|CircuitBreaker|opossum|cockatiel|polly/i.test(fileContent)) {
|
|
134
|
+
if (i === lines.findIndex((l) => /(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(l))) {
|
|
135
|
+
issues.push({
|
|
136
|
+
file: filepath,
|
|
137
|
+
line: i + 1,
|
|
138
|
+
issue: "Retries without circuit breaker",
|
|
139
|
+
severity: "medium",
|
|
140
|
+
detail: "Add circuit breaker to fail fast when downstream is unhealthy",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Timeout not set
|
|
146
|
+
if (/(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(line)) {
|
|
147
|
+
const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
|
|
148
|
+
if (!/timeout|signal|AbortController|deadline/i.test(block)) {
|
|
149
|
+
issues.push({
|
|
150
|
+
file: filepath,
|
|
151
|
+
line: i + 1,
|
|
152
|
+
issue: "External call without timeout",
|
|
153
|
+
severity: "high",
|
|
154
|
+
detail: "Set timeouts on all external calls — retries compound unbounded waits",
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return issues;
|
|
160
|
+
}
|
|
161
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
162
|
+
export function runRetryPatternAudit(argv) {
|
|
163
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
164
|
+
console.log(`
|
|
165
|
+
judges retry-pattern-audit — Analyze retry, backoff, and circuit-breaker patterns
|
|
166
|
+
|
|
167
|
+
Usage:
|
|
168
|
+
judges retry-pattern-audit [dir]
|
|
169
|
+
judges retry-pattern-audit src/ --format json
|
|
170
|
+
|
|
171
|
+
Options:
|
|
172
|
+
[dir] Directory to scan (default: .)
|
|
173
|
+
--format json JSON output
|
|
174
|
+
--help, -h Show this help
|
|
175
|
+
|
|
176
|
+
Detects: unbounded retries, fixed delays, missing jitter, non-idempotent retries,
|
|
177
|
+
indiscriminate error catching, missing circuit breakers, missing timeouts.
|
|
178
|
+
`);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
182
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
183
|
+
const files = collectFiles(dir);
|
|
184
|
+
const allIssues = [];
|
|
185
|
+
for (const f of files)
|
|
186
|
+
allIssues.push(...analyzeFile(f));
|
|
187
|
+
const critCount = allIssues.filter((i) => i.severity === "critical").length;
|
|
188
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
189
|
+
const score = allIssues.length === 0 ? 100 : Math.max(0, 100 - critCount * 25 - highCount * 10);
|
|
190
|
+
if (format === "json") {
|
|
191
|
+
console.log(JSON.stringify({
|
|
192
|
+
issues: allIssues,
|
|
193
|
+
score,
|
|
194
|
+
summary: { critical: critCount, high: highCount, total: allIssues.length },
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
}, null, 2));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const badge = critCount > 0 ? "🚫 UNSAFE" : highCount > 0 ? "⚠️ FRAGILE" : "✅ RESILIENT";
|
|
200
|
+
console.log(`\n Retry Pattern Audit: ${badge} (${score}/100)\n ─────────────────────────────`);
|
|
201
|
+
if (allIssues.length === 0) {
|
|
202
|
+
console.log(" No retry pattern issues detected.\n");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
206
|
+
const icon = issue.severity === "critical" ? "🚫" : issue.severity === "high" ? "🔴" : "🟡";
|
|
207
|
+
console.log(` ${icon} [${issue.severity.toUpperCase()}] ${issue.issue}`);
|
|
208
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
209
|
+
console.log(` ${issue.detail}`);
|
|
210
|
+
}
|
|
211
|
+
if (allIssues.length > 25)
|
|
212
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
213
|
+
console.log(`\n Total: ${allIssues.length} | Critical: ${critCount} | High: ${highCount} | Score: ${score}/100\n`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=retry-pattern-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-pattern-audit.js","sourceRoot":"","sources":["../../src/commands/retry-pattern-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-isolation.d.ts","sourceRoot":"","sources":["../../src/commands/test-isolation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0MH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgErD"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test isolation — detect shared mutable state, ordering dependencies,
|
|
3
|
+
* and resource leaks between test cases.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
6
|
+
import { join, extname, basename } from "path";
|
|
7
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
8
|
+
const TEST_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go"]);
|
|
9
|
+
const TEST_PATTERNS = [/\.test\./i, /\.spec\./i, /test_/i, /_test\./i];
|
|
10
|
+
function isTestFile(name) {
|
|
11
|
+
return TEST_PATTERNS.some((p) => p.test(name));
|
|
12
|
+
}
|
|
13
|
+
function collectTestFiles(dir, max = 300) {
|
|
14
|
+
const files = [];
|
|
15
|
+
function walk(d) {
|
|
16
|
+
if (files.length >= max)
|
|
17
|
+
return;
|
|
18
|
+
let entries;
|
|
19
|
+
try {
|
|
20
|
+
entries = readdirSync(d);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const e of entries) {
|
|
26
|
+
if (files.length >= max)
|
|
27
|
+
return;
|
|
28
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
29
|
+
continue;
|
|
30
|
+
const full = join(d, e);
|
|
31
|
+
try {
|
|
32
|
+
if (statSync(full).isDirectory())
|
|
33
|
+
walk(full);
|
|
34
|
+
else if (TEST_EXTS.has(extname(full)) && isTestFile(basename(full)))
|
|
35
|
+
files.push(full);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
/* skip */
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
walk(dir);
|
|
43
|
+
return files;
|
|
44
|
+
}
|
|
45
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
46
|
+
function analyzeFile(filepath) {
|
|
47
|
+
const issues = [];
|
|
48
|
+
let content;
|
|
49
|
+
try {
|
|
50
|
+
content = readFileSync(filepath, "utf-8");
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return issues;
|
|
54
|
+
}
|
|
55
|
+
const lines = content.split("\n");
|
|
56
|
+
// Track scope context
|
|
57
|
+
let inDescribe = false;
|
|
58
|
+
let describeDepth = 0;
|
|
59
|
+
for (let i = 0; i < lines.length; i++) {
|
|
60
|
+
const line = lines[i];
|
|
61
|
+
if (/\b(?:describe|context|suite)\s*\(/.test(line)) {
|
|
62
|
+
inDescribe = true;
|
|
63
|
+
describeDepth++;
|
|
64
|
+
}
|
|
65
|
+
if (inDescribe && /^\s*\}\s*\)\s*;?\s*$/.test(line)) {
|
|
66
|
+
describeDepth--;
|
|
67
|
+
if (describeDepth <= 0)
|
|
68
|
+
inDescribe = false;
|
|
69
|
+
}
|
|
70
|
+
// Global mutable state
|
|
71
|
+
if (/^\s*(?:let|var)\s+\w+\s*=/.test(line) && !inDescribe) {
|
|
72
|
+
const varName = line.match(/(?:let|var)\s+(\w+)/)?.[1];
|
|
73
|
+
if (varName && /\b(?:state|data|count|result|output|db|conn|client|server)\b/i.test(varName)) {
|
|
74
|
+
issues.push({
|
|
75
|
+
file: filepath,
|
|
76
|
+
line: i + 1,
|
|
77
|
+
issue: "Mutable global test state",
|
|
78
|
+
severity: "high",
|
|
79
|
+
detail: `Global \`${varName}\` — tests sharing mutable state cause order-dependent failures`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Module-level side effects in test files
|
|
84
|
+
if (/^\s*(?:fs\.|writeFileSync|mkdirSync|execSync|spawn|createServer)/.test(line) && !inDescribe) {
|
|
85
|
+
issues.push({
|
|
86
|
+
file: filepath,
|
|
87
|
+
line: i + 1,
|
|
88
|
+
issue: "Module-level side effect",
|
|
89
|
+
severity: "high",
|
|
90
|
+
detail: "Side effects outside test blocks affect all tests in the file",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Shared fixtures without reset
|
|
94
|
+
if (/\b(?:beforeAll|before)\s*\(\s*(?:async\s+)?(?:function|\(|=>)/.test(line)) {
|
|
95
|
+
const beforeBlock = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
|
|
96
|
+
const hasAfter = /\b(?:afterAll|afterEach|after)\s*\(/.test(content);
|
|
97
|
+
if (!hasAfter && /(?:create|setup|init|connect|insert|write)/i.test(beforeBlock)) {
|
|
98
|
+
issues.push({
|
|
99
|
+
file: filepath,
|
|
100
|
+
line: i + 1,
|
|
101
|
+
issue: "Setup without teardown",
|
|
102
|
+
severity: "high",
|
|
103
|
+
detail: "beforeAll creates resources but no afterAll/afterEach cleans them — leaked state",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// File system operations without cleanup
|
|
108
|
+
if (/(?:writeFileSync|mkdirSync|writeFile|mkdir)\s*\(/.test(line)) {
|
|
109
|
+
const hasCleanup = /(?:unlinkSync|rmdirSync|rimraf|rm\s*\(|removeSync|afterEach.*unlink|afterAll.*unlink)/i.test(content);
|
|
110
|
+
if (!hasCleanup) {
|
|
111
|
+
issues.push({
|
|
112
|
+
file: filepath,
|
|
113
|
+
line: i + 1,
|
|
114
|
+
issue: "File system write without cleanup",
|
|
115
|
+
severity: "medium",
|
|
116
|
+
detail: "Test creates files but never cleans up — pollutes workspace",
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Network listeners without close
|
|
121
|
+
if (/(?:createServer|listen)\s*\(/.test(line)) {
|
|
122
|
+
const hasClose = /(?:\.close\s*\(|server\.close|afterAll.*close|afterEach.*close)/i.test(content);
|
|
123
|
+
if (!hasClose) {
|
|
124
|
+
issues.push({
|
|
125
|
+
file: filepath,
|
|
126
|
+
line: i + 1,
|
|
127
|
+
issue: "Server started without closing",
|
|
128
|
+
severity: "high",
|
|
129
|
+
detail: "Test starts a server but never closes it — port conflicts in parallel runs",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// setTimeout in tests (flakiness)
|
|
134
|
+
if (/setTimeout\s*\(\s*(?:resolve|done|callback|cb)\s*,\s*\d+/.test(line)) {
|
|
135
|
+
issues.push({
|
|
136
|
+
file: filepath,
|
|
137
|
+
line: i + 1,
|
|
138
|
+
issue: "setTimeout for async coordination",
|
|
139
|
+
severity: "medium",
|
|
140
|
+
detail: "Timer-based waits are flaky — use event-based or polling patterns",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// Order-dependent assertions (relying on previous test state)
|
|
144
|
+
if (/\.toBe\(.*\+\+|\.toEqual\(.*count/i.test(line)) {
|
|
145
|
+
issues.push({
|
|
146
|
+
file: filepath,
|
|
147
|
+
line: i + 1,
|
|
148
|
+
issue: "Assertion relies on accumulated state",
|
|
149
|
+
severity: "medium",
|
|
150
|
+
detail: "Tests should be independently runnable — avoid cross-test counters",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Shared database connections
|
|
154
|
+
if (/(?:mongoose\.connect|createConnection|pg\.Pool|knex|prisma\.\$connect|sequelize)/i.test(line) && !inDescribe) {
|
|
155
|
+
issues.push({
|
|
156
|
+
file: filepath,
|
|
157
|
+
line: i + 1,
|
|
158
|
+
issue: "Shared database connection",
|
|
159
|
+
severity: "medium",
|
|
160
|
+
detail: "Use per-test or per-suite DB connections with transaction rollback",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// Environment variable mutation
|
|
164
|
+
if (/process\.env\.\w+\s*=/.test(line)) {
|
|
165
|
+
const hasRestore = /process\.env\.\w+\s*=.*original|delete\s+process\.env|afterEach.*env/i.test(content);
|
|
166
|
+
if (!hasRestore) {
|
|
167
|
+
issues.push({
|
|
168
|
+
file: filepath,
|
|
169
|
+
line: i + 1,
|
|
170
|
+
issue: "Environment mutation without restore",
|
|
171
|
+
severity: "high",
|
|
172
|
+
detail: "Setting process.env leaks to other tests — restore in afterEach",
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return issues;
|
|
178
|
+
}
|
|
179
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
180
|
+
export function runTestIsolation(argv) {
|
|
181
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
182
|
+
console.log(`
|
|
183
|
+
judges test-isolation — Detect test isolation violations
|
|
184
|
+
|
|
185
|
+
Usage:
|
|
186
|
+
judges test-isolation [dir]
|
|
187
|
+
judges test-isolation tests/ --format json
|
|
188
|
+
|
|
189
|
+
Options:
|
|
190
|
+
[dir] Directory to scan (default: .)
|
|
191
|
+
--format json JSON output
|
|
192
|
+
--help, -h Show this help
|
|
193
|
+
|
|
194
|
+
Detects: shared mutable state, missing teardown, file system leaks, unclosed servers,
|
|
195
|
+
setTimeout waits, environment mutations, shared DB connections.
|
|
196
|
+
`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
200
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
201
|
+
const files = collectTestFiles(dir);
|
|
202
|
+
const allIssues = [];
|
|
203
|
+
for (const f of files)
|
|
204
|
+
allIssues.push(...analyzeFile(f));
|
|
205
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
206
|
+
const medCount = allIssues.filter((i) => i.severity === "medium").length;
|
|
207
|
+
const score = Math.max(0, 100 - highCount * 10 - medCount * 5);
|
|
208
|
+
if (format === "json") {
|
|
209
|
+
console.log(JSON.stringify({
|
|
210
|
+
issues: allIssues,
|
|
211
|
+
score,
|
|
212
|
+
summary: { files: files.length, high: highCount, medium: medCount, total: allIssues.length },
|
|
213
|
+
timestamp: new Date().toISOString(),
|
|
214
|
+
}, null, 2));
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const badge = score >= 80 ? "✅ ISOLATED" : score >= 50 ? "⚠️ LEAKY" : "❌ COUPLED";
|
|
218
|
+
console.log(`\n Test Isolation: ${badge} (${score}/100)\n ─────────────────────────`);
|
|
219
|
+
console.log(` Test files: ${files.length}\n`);
|
|
220
|
+
if (allIssues.length === 0) {
|
|
221
|
+
console.log(" No isolation issues detected.\n");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
225
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
|
|
226
|
+
console.log(` ${icon} ${issue.issue}`);
|
|
227
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
228
|
+
console.log(` ${issue.detail}`);
|
|
229
|
+
}
|
|
230
|
+
if (allIssues.length > 25)
|
|
231
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
232
|
+
console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=test-isolation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-isolation.js","sourceRoot":"","sources":["../../src/commands/test-isolation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout-audit.d.ts","sourceRoot":"","sources":["../../src/commands/timeout-audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgLH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+DpD"}
|