Skip to content

Commit f8cba1f

Browse files
test: add regression tests for non-numeric threshold sanitization
1 parent 18837ab commit f8cba1f

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

tests/integration/complexity.test.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ import fs from 'node:fs';
99
import os from 'node:os';
1010
import path from 'node:path';
1111
import Database from 'better-sqlite3';
12-
import { afterAll, beforeAll, describe, expect, test } from 'vitest';
12+
import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest';
1313
import { complexityData } from '../../src/complexity.js';
14+
import { loadConfig } from '../../src/config.js';
1415
import { initSchema } from '../../src/db.js';
1516

17+
vi.mock('../../src/config.js', () => ({
18+
loadConfig: vi.fn(() => ({})),
19+
}));
20+
1621
// ─── Helpers ───────────────────────────────────────────────────────────
1722

1823
function insertNode(db, name, kind, file, line, endLine = null) {
@@ -320,4 +325,42 @@ describe('complexityData', () => {
320325
expect(typeof fn.maintainabilityIndex).toBe('number');
321326
}
322327
});
328+
329+
// ─── Threshold sanitization (regression) ────────────────────────────
330+
331+
test('non-numeric threshold values do not crash SQL query', () => {
332+
vi.mocked(loadConfig).mockReturnValueOnce({
333+
manifesto: {
334+
rules: {
335+
cognitive: { warn: 'abc' },
336+
cyclomatic: { warn: '123xyz' },
337+
maxNesting: { warn: undefined },
338+
},
339+
},
340+
});
341+
// Should not throw — invalid thresholds are silently skipped
342+
const data = complexityData(dbPath, { aboveThreshold: true });
343+
expect(data.functions).toBeDefined();
344+
expect(Array.isArray(data.functions)).toBe(true);
345+
// With all thresholds invalid, no filtering occurs — all functions returned
346+
expect(data.functions.length).toBeGreaterThanOrEqual(4);
347+
expect(data.summary.aboveWarn).toBe(0);
348+
});
349+
350+
test('string-numeric thresholds are rejected (strict type check)', () => {
351+
vi.mocked(loadConfig).mockReturnValueOnce({
352+
manifesto: {
353+
rules: {
354+
cognitive: { warn: '15' },
355+
cyclomatic: { warn: '10' },
356+
maxNesting: { warn: '4' },
357+
},
358+
},
359+
});
360+
const data = complexityData(dbPath, { aboveThreshold: true });
361+
// String thresholds fail typeof === 'number' — treated as no threshold
362+
// so all functions are returned (no HAVING filter applied)
363+
expect(data.functions.length).toBeGreaterThanOrEqual(4);
364+
expect(data.summary.aboveWarn).toBe(0);
365+
});
323366
});

0 commit comments

Comments
 (0)