Skip to content

Commit 100ede0

Browse files
Add list parsing helper usage centralization guard
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 6a38bf4 commit 100ede0

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ This runs lint, format checks, compile checks, tests, and package build.
167167
- `tests/test_job_start_payload_helper_usage.py` (shared scrape/crawl start-payload helper usage enforcement),
168168
- `tests/test_job_wait_helper_boundary.py` (centralization boundary enforcement for wait-for-job helper primitives),
169169
- `tests/test_job_wait_helper_usage.py` (shared wait-for-job defaults helper usage enforcement),
170+
- `tests/test_list_parsing_helper_usage.py` (list parsing shared helper usage centralization),
170171
- `tests/test_list_parsing_key_display_helper_usage.py` (list parsing safe key-display helper usage enforcement),
171172
- `tests/test_makefile_quality_targets.py` (Makefile quality-gate target enforcement),
172173
- `tests/test_manager_helper_import_boundary.py` (manager helper-import boundary enforcement for low-level parse modules),

tests/test_architecture_marker_usage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"tests/test_job_start_payload_helper_usage.py",
129129
"tests/test_job_query_params_helper_usage.py",
130130
"tests/test_list_parsing_key_display_helper_usage.py",
131+
"tests/test_list_parsing_helper_usage.py",
131132
"tests/test_job_wait_helper_boundary.py",
132133
"tests/test_job_wait_helper_usage.py",
133134
"tests/test_example_sync_async_parity.py",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
5+
from tests.guardrail_ast_utils import collect_name_call_lines, read_module_ast
6+
7+
pytestmark = pytest.mark.architecture
8+
9+
HYPERBROWSER_ROOT = Path(__file__).resolve().parents[1] / "hyperbrowser"
10+
ALLOWED_PARSE_MAPPING_LIST_CALL_FILES = {
11+
Path("client/managers/extension_utils.py"),
12+
Path("client/managers/list_parsing_utils.py"),
13+
Path("client/managers/session_utils.py"),
14+
}
15+
ALLOWED_READ_PLAIN_LIST_CALL_FILES = {
16+
Path("client/managers/extension_utils.py"),
17+
Path("client/managers/list_parsing_utils.py"),
18+
Path("client/managers/session_utils.py"),
19+
}
20+
21+
22+
def _python_files() -> list[Path]:
23+
return sorted(HYPERBROWSER_ROOT.rglob("*.py"))
24+
25+
26+
def test_parse_mapping_list_items_usage_is_centralized():
27+
violations: list[str] = []
28+
29+
for path in _python_files():
30+
relative_path = path.relative_to(HYPERBROWSER_ROOT)
31+
module = read_module_ast(path)
32+
helper_calls = collect_name_call_lines(module, "parse_mapping_list_items")
33+
if not helper_calls:
34+
continue
35+
if relative_path in ALLOWED_PARSE_MAPPING_LIST_CALL_FILES:
36+
continue
37+
for line in helper_calls:
38+
violations.append(f"{relative_path}:{line}")
39+
40+
assert violations == []
41+
42+
43+
def test_read_plain_list_items_usage_is_centralized():
44+
violations: list[str] = []
45+
46+
for path in _python_files():
47+
relative_path = path.relative_to(HYPERBROWSER_ROOT)
48+
module = read_module_ast(path)
49+
helper_calls = collect_name_call_lines(module, "read_plain_list_items")
50+
if not helper_calls:
51+
continue
52+
if relative_path in ALLOWED_READ_PLAIN_LIST_CALL_FILES:
53+
continue
54+
for line in helper_calls:
55+
violations.append(f"{relative_path}:{line}")
56+
57+
assert violations == []

0 commit comments

Comments
 (0)