From 999a5dbf31487b30f42262ea9a141ade92bdabb2 Mon Sep 17 00:00:00 2001 From: ultrahighsuper Date: Fri, 3 Jul 2026 11:15:47 +0900 Subject: [PATCH] fix(signals): detect pytest test_*.py prefix as test evidence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isTestPath recognized the *_test.py suffix but not pytest`s default and more common test_*.py prefix, so a Python PR adding test files next to source (mypackage/test_utils.py) was scored as having no test evidence — tripping the missing-test slop finding and undercounting test coverage. Add a path-segment-anchored test_*.py matcher; latest_config.py and testing.py stay non-tests. --- src/signals/test-evidence.ts | 1 + test/unit/test-evidence.test.ts | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/signals/test-evidence.ts b/src/signals/test-evidence.ts index 928dff87a9..227e64fd30 100644 --- a/src/signals/test-evidence.ts +++ b/src/signals/test-evidence.ts @@ -3,6 +3,7 @@ export function isTestPath(file: string): boolean { /(^|\/)(test|tests|spec|__tests__)\//i.test(file) || /(^|\/)src\/test\//i.test(file) || /(^|\/)[^/]+_test\.(go|py|rb)$/i.test(file) || + /(^|\/)test_[^/]*\.py$/i.test(file) || // pytest's default `test_*.py` prefix convention (the suffix rule above only catches `*_test.py`) /(^|\/)[^/]+_spec\.rb$/i.test(file) || /\.(test|spec)\.(ts|tsx|js|jsx|py|rb|rs)$/i.test(file) || /(^|\/)[^/]+\.(cy|e2e)\.(ts|tsx|js|jsx)$/i.test(file) || diff --git a/test/unit/test-evidence.test.ts b/test/unit/test-evidence.test.ts index f0997c4b5b..aaa82aaaf5 100644 --- a/test/unit/test-evidence.test.ts +++ b/test/unit/test-evidence.test.ts @@ -17,6 +17,15 @@ describe("test evidence helpers", () => { expect(isTestPath("src/widget.rs")).toBe(false); }); + it("detects pytest's default test_*.py prefix convention, not just the *_test.py suffix", () => { + expect(isTestPath("mypackage/test_utils.py")).toBe(true); // pytest default, sitting next to source + expect(isTestPath("src/app/test_auth.py")).toBe(true); + expect(isTestPath("test_top_level.py")).toBe(true); // repo-root test file + expect(isTestPath("internal/cache_test.py")).toBe(true); // the pre-existing suffix form still matches + expect(isTestPath("src/app/latest_config.py")).toBe(false); // `test_` mid-segment ⇒ not a test + expect(isTestPath("src/app/testing.py")).toBe(false); // no `test_` boundary ⇒ not a test + }); + it("does not treat framework or integration directory names alone as test evidence", () => { expect(isTestPath("src/integration/auth.ts")).toBe(false); expect(isTestPath("src/playwright/client.ts")).toBe(false);