Skip to content

Commit ba3370f

Browse files
committed
fix(utils): use anchored regex patterns for test file detection
- Normalize Windows separators (backslash to forward slash) - Use path boundary anchors (?:^|/) and (?:/|$) to prevent false matches - Pre-compile patterns for performance - Fixes false positives like 'contest.py' matching 'test'
1 parent 72605e6 commit ba3370f

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

backend/utils/test_detection.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,49 @@
66
from typing import List
77

88

9-
# Regex patterns for test files (consolidated from CodeGraphRanker)
9+
# Anchored regex patterns for test files (boundary-aware to prevent false matches)
10+
# Uses (?:^|/) for start boundary and (?:/|$) for end boundary
1011
TEST_PATTERNS = [
11-
r'test[s]?[/_]', # test/, tests/, test_
12-
r'[/_]test[s]?\.py$', # _test.py, _tests.py
13-
r'\.test\.[jt]sx?$', # .test.js, .test.ts
14-
r'\.spec\.[jt]sx?$', # .spec.js, .spec.ts
15-
r'__tests__', # __tests__/
16-
r'conftest\.py$', # pytest config
17-
r'fixtures?[/_]', # fixtures/
18-
r'mock[s]?[/_]', # mocks/
12+
# test directories: /test/, /tests/, but NOT "contest", "latest"
13+
r'(?:^|/)tests?(?:/|$)',
14+
# test_ prefix in filename: test_foo.py, but NOT "contest_foo.py"
15+
r'(?:^|/)test_[^/]+$',
16+
# _test suffix: foo_test.py, foo_tests.py
17+
r'(?:^|/)[^/]+_tests?\.py$',
18+
# .test.js, .test.ts, .test.tsx, .test.jsx
19+
r'\.test\.[jt]sx?$',
20+
# .spec.js, .spec.ts, .spec.tsx, .spec.jsx
21+
r'\.spec\.[jt]sx?$',
22+
# __tests__ directory (Jest convention)
23+
r'(?:^|/)__tests__(?:/|$)',
24+
# conftest.py (pytest config)
25+
r'(?:^|/)conftest\.py$',
26+
# fixtures directory
27+
r'(?:^|/)fixtures?(?:/|$)',
28+
# mocks directory
29+
r'(?:^|/)mocks?(?:/|$)',
1930
]
2031

32+
# Pre-compile patterns for performance
33+
_COMPILED_PATTERNS = [re.compile(p) for p in TEST_PATTERNS]
34+
2135

2236
def is_test_file(file_path: str) -> bool:
2337
"""
24-
Check if file is a test file using regex patterns.
38+
Check if file is a test file using anchored regex patterns.
2539
2640
Args:
27-
file_path: Path to check (can be relative or absolute)
41+
file_path: Path to check (can be relative or absolute, Windows or Unix)
2842
2943
Returns:
3044
True if file matches any test pattern
3145
"""
3246
if not file_path:
3347
return False
34-
file_path_lower = file_path.lower()
35-
for pattern in TEST_PATTERNS:
36-
if re.search(pattern, file_path_lower):
48+
# normalize: lowercase + Windows separators to Unix
49+
normalized = file_path.lower().replace('\\', '/')
50+
for pattern in _COMPILED_PATTERNS:
51+
if pattern.search(normalized):
3752
return True
3853
return False
3954

0 commit comments

Comments
 (0)