From 6867b126964160816befd69055653b53f9842aa3 Mon Sep 17 00:00:00 2001 From: Prince Date: Sun, 3 May 2026 16:00:37 +0530 Subject: [PATCH 1/2] parser: detect files under __tests__/ as tests flows.py and refactor.py already recognize the Jest convention of placing tests under a __tests__/ directory, but parser.py did not. This meant a file like src/__tests__/UserService.ts was treated as a test for criticality scoring and dead-code analysis but never produced Test nodes or TESTED_BY edges. Add the same regex used in flows.py and refactor.py to _TEST_FILE_PATTERNS so the three modules agree. --- code_review_graph/parser.py | 1 + tests/fixtures/__tests__/UserService.ts | 15 +++++++++++++ tests/test_parser.py | 29 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 tests/fixtures/__tests__/UserService.ts diff --git a/code_review_graph/parser.py b/code_review_graph/parser.py index f681263a..17c4a1cb 100644 --- a/code_review_graph/parser.py +++ b/code_review_graph/parser.py @@ -319,6 +319,7 @@ class EdgeInfo: re.compile(r".*\.spec\.[jt]sx?$"), re.compile(r".*_test\.go$"), re.compile(r"tests?/"), + re.compile(r"[\\/]__tests__[\\/]"), re.compile(r".*_test\.dart$"), re.compile(r"test[_-].*\.[rR]$"), re.compile(r"tests/testthat/"), diff --git a/tests/fixtures/__tests__/UserService.ts b/tests/fixtures/__tests__/UserService.ts new file mode 100644 index 00000000..de44ec0c --- /dev/null +++ b/tests/fixtures/__tests__/UserService.ts @@ -0,0 +1,15 @@ +import { describe, it, expect } from 'vitest'; +import { UserRepository, UserService } from '../sample_typescript'; + +describe('UserService (under __tests__/)', () => { + it('constructs a service', () => { + const service = new UserService(); + expect(service).toBeDefined(); + }); + + it('returns undefined for missing user', () => { + const service = new UserService(); + const user = service.getUser(999); + expect(user).toBeUndefined(); + }); +}); diff --git a/tests/test_parser.py b/tests/test_parser.py index b38ff11b..d3e30679 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -648,6 +648,35 @@ def test_vitest_tested_by_edges(self): f"All edges: {[(e.kind, e.source, e.target) for e in edges]}" ) + # --- __tests__/ directory recognition (Jest convention) --- + # Consistency fix: flows.py and refactor.py already recognize __tests__/ + # but parser.py did not, so files there did not produce Test nodes. + + def test_jest_tests_dir_detected_as_test_file(self): + """A file under __tests__/ should be classified as a test file even + when the filename itself has no .test./.spec. marker.""" + from code_review_graph.parser import _is_test_file + assert _is_test_file("src/__tests__/UserService.ts") + assert _is_test_file("src\\__tests__\\UserService.ts") + # Negative: __tests__ as a substring without path separators must not match + assert not _is_test_file("my__tests__notdir.ts") + + def test_jest_tests_dir_produces_test_nodes(self): + """A vitest-style file under __tests__/ should yield Test nodes + and TESTED_BY edges, the same as a *.test.ts file.""" + path = FIXTURES / "__tests__" / "UserService.ts" + nodes, edges = self.parser.parse_file(path) + tests = [n for n in nodes if n.kind == "Test"] + test_names = {t.name for t in tests} + assert any(n.startswith("describe") or n.startswith("describe:") for n in test_names), ( + f"Expected describe Test node, got: {test_names}" + ) + tested_by = [e for e in edges if e.kind == "TESTED_BY"] + assert len(tested_by) >= 1, ( + f"Expected TESTED_BY edges from __tests__/ file, got none. " + f"Edges: {[(e.kind, e.source, e.target) for e in edges]}" + ) + def test_non_test_file_describe_not_special(self): """describe() in a non-test file should NOT create Test nodes.""" import tempfile From 3686fc2d214115bd4f2e454e403b54c3ce11fc98 Mon Sep 17 00:00:00 2001 From: Prince Parmar Singh <149327706+Pr1ncePS2002@users.noreply.github.com> Date: Sun, 3 May 2026 16:06:56 +0530 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/test_parser.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index d3e30679..3f768889 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -664,8 +664,13 @@ def test_jest_tests_dir_detected_as_test_file(self): def test_jest_tests_dir_produces_test_nodes(self): """A vitest-style file under __tests__/ should yield Test nodes and TESTED_BY edges, the same as a *.test.ts file.""" - path = FIXTURES / "__tests__" / "UserService.ts" - nodes, edges = self.parser.parse_file(path) + fixture_path = FIXTURES / "__tests__" / "UserService.ts" + fixture_code = fixture_path.read_text(encoding="utf-8") + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "src" / "__tests__" / "UserService.ts" + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(fixture_code, encoding="utf-8") + nodes, edges = self.parser.parse_file(path) tests = [n for n in nodes if n.kind == "Test"] test_names = {t.name for t in tests} assert any(n.startswith("describe") or n.startswith("describe:") for n in test_names), (