Skip to content

Commit d165e53

Browse files
committed
feat(tests/static): Mark tagged / untagged tests
- Add marker for tagged + untagged tests to make them easier to identify
1 parent 956e38b commit d165e53

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ addopts =
1414
-p pytest_plugins.filler.filler
1515
-p pytest_plugins.filler.ported_tests
1616
-p pytest_plugins.filler.static_filler
17+
-p pytest_plugins.filler.static_filler_tag_marker
1718
-p pytest_plugins.shared.execute_fill
1819
-p pytest_plugins.forks.forks
1920
-p pytest_plugins.eels_resolver
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"""
2+
Pytest plugin that dynamically marks static tests based on their tag compatibility.
3+
4+
This plugin examines static test files and marks them as either:
5+
- `tagged`: Tests that use the tag system (compatible)
6+
- `untagged`: Tests that have hardcoded addresses (incompatible)
7+
"""
8+
9+
import json
10+
import re
11+
from typing import Any, Dict
12+
13+
import pytest
14+
import yaml
15+
16+
from pytest_plugins.filler.static_filler import NoIntResolver
17+
18+
19+
def has_tags_in_content(content: Dict[str, Any]) -> bool:
20+
"""Check if test content uses tags for addresses."""
21+
tag_pattern = re.compile(r"<(?:eoa|contract|coinbase)(?::[^:]+)?:[^>]+>")
22+
23+
def check_dict(d: Dict[str, Any]) -> bool:
24+
"""Recursively check dictionary for tags."""
25+
for _key, value in d.items():
26+
if isinstance(value, str) and tag_pattern.search(value):
27+
return True
28+
elif isinstance(value, dict):
29+
if check_dict(value):
30+
return True
31+
elif isinstance(value, list):
32+
for item in value:
33+
if isinstance(item, dict) and check_dict(item):
34+
return True
35+
elif isinstance(item, str) and tag_pattern.search(item):
36+
return True
37+
return False
38+
39+
return check_dict(content)
40+
41+
42+
def pytest_collection_modifyitems(config, items):
43+
"""Mark tests based on their tag usage."""
44+
# Only process if static tests are being filled
45+
if not config.getoption("fill_static_tests_enabled"):
46+
return
47+
48+
# Track statistics
49+
tagged_count = 0
50+
untagged_count = 0
51+
52+
# Group items by their source file
53+
items_by_file = {}
54+
for item in items:
55+
if hasattr(item, "parent") and hasattr(item.parent, "path"):
56+
file_path = item.parent.path
57+
if file_path not in items_by_file:
58+
items_by_file[file_path] = []
59+
items_by_file[file_path].append(item)
60+
61+
# Process each file once
62+
for file_path, file_items in items_by_file.items():
63+
if file_path.suffix not in (".json", ".yml"):
64+
continue
65+
66+
if not file_path.stem.endswith("Filler"):
67+
continue
68+
69+
with open(file_path, "r") as f:
70+
file_content = (
71+
json.load(f) if file_path.suffix == ".json" else yaml.load(f, Loader=NoIntResolver)
72+
)
73+
74+
# For each test in the file
75+
for test_name, test_content in file_content.items():
76+
# Check if the test uses tags
77+
uses_tags = has_tags_in_content(test_content)
78+
79+
# Find items that belong to this test
80+
test_items = [item for item in file_items if test_name in item.name]
81+
82+
# Mark items for this test
83+
for item in test_items:
84+
if uses_tags:
85+
item.add_marker(pytest.mark.tagged)
86+
tagged_count += 1
87+
else:
88+
item.add_marker(pytest.mark.untagged)
89+
untagged_count += 1
90+
91+
# Report statistics if verbose
92+
if config.getoption("verbose") >= 1:
93+
print("\nStatic test tag statistics:")
94+
print(f" Tagged (compatible): {tagged_count}")
95+
print(f" Untagged (incompatible): {untagged_count}")
96+
97+
98+
def pytest_configure(config):
99+
"""Register markers."""
100+
config.addinivalue_line("markers", "tagged: marks tests that use the tag system")
101+
config.addinivalue_line("markers", "untagged: marks tests that have hardcoded addresses")

0 commit comments

Comments
 (0)