UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

68 lines (67 loc) • 3.08 kB
/** * Shared test-framework-call recognition for `high-fan-out` and `high-complexity` * (#577). A normal `it()`/`describe()` body naturally invokes many assertion/mock * helpers — that's test structure, not a coordination smell or genuine complexity. * * Two complementary heuristics, both call-name-based (no `ctx.fileRole` gating — * these calls only exist in test-framework code, so the signal is safe to apply * unconditionally): * * 1. `isTestFrameworkNoiseCall` — filters individual "meaningful calls" the same * way `console.*`/`Math.*`/etc. are already excluded in high-fan-out. Handles * assertion-heavy `it()` bodies directly. * 2. `isTestSuiteOrganizer` — a `describe()`/`it()`/`test()` wrapper's own * FunctionSummary aggregates every call and branch from ALL of its nested test * bodies (the shared tree-sitter walk in function-facts.ts does not stop at * nested-function boundaries, since each nested callback also gets its own, * correctly-scoped, FunctionSummary). That aggregation is not real fan-out or * complexity — it's the sum of independent nested tests. A function is an * "organizer" if it directly invokes `it`/`test`/`describe` (or their * `.only`/`.skip`/`.each` variants) — i.e. it exists to group other tests, not * to implement logic itself. This does NOT exempt genuinely complex/tangled * test HELPER functions, since those don't call `it`/`describe`/`test` * themselves. */ const EXPECT_CHAIN_PREFIX = "expect("; const TEST_LIFECYCLE_NAMES = new Set([ "it", "test", "describe", "beforeeach", "aftereach", "beforeall", "afterall", ]); const TEST_LIFECYCLE_PREFIXES = ["it.", "test.", "describe."]; const MOCK_LIBRARY_PREFIXES = ["vi.", "jest."]; /** * True if `call` (a raw callee string from `FunctionSummary.outgoingCalls`) is * test-framework noise: an `expect(...)` assertion chain, a test lifecycle call * (`it`/`describe`/`test`/`beforeEach`/etc., including `.only`/`.skip`/`.each` * variants), or a mock-library call (`vi.*`/`jest.*`). */ export function isTestFrameworkNoiseCall(call) { const lower = call.toLowerCase(); if (lower === "expect" || lower.startsWith(EXPECT_CHAIN_PREFIX)) return true; if (TEST_LIFECYCLE_NAMES.has(lower)) return true; if (TEST_LIFECYCLE_PREFIXES.some((p) => lower.startsWith(p))) return true; if (MOCK_LIBRARY_PREFIXES.some((p) => lower.startsWith(p))) return true; return false; } /** * True if this function's (unfiltered) outgoing calls include a direct call to * `it`/`test`/`describe` — i.e. it groups nested test bodies rather than * implementing logic itself. Its aggregated fan-out/complexity reflects the sum * of independent nested tests, not one function's real signal. */ export function isTestSuiteOrganizer(calls) { return calls.some((call) => { const lower = call.toLowerCase(); const base = lower.split("(")[0].split(".")[0]; return base === "it" || base === "test" || base === "describe"; }); }