-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtest_matcher.py
More file actions
158 lines (132 loc) · 6.46 KB
/
Copy pathtest_matcher.py
File metadata and controls
158 lines (132 loc) · 6.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
"""Tests for DeepSchema file matching."""
from pathlib import Path
from deepwork.deepschema.config import DeepSchema
from deepwork.deepschema.matcher import get_applicable_schemas, get_schemas_for_file_fast
def _named_schema(
name: str,
matchers: list[str],
source_path: Path | None = None,
) -> DeepSchema:
return DeepSchema(
name=name,
schema_type="named",
source_path=source_path or Path(f"/fake/.deepwork/schemas/{name}/deepschema.yml"),
matchers=matchers,
requirements={"test": "MUST pass"},
)
def _anonymous_schema(
target_filename: str,
directory: Path,
) -> DeepSchema:
return DeepSchema(
name=target_filename,
schema_type="anonymous",
source_path=directory / f".deepschema.{target_filename}.yml",
requirements={"test": "MUST pass"},
)
class TestGetApplicableSchemas:
def test_matches_named_schema_by_glob(self, tmp_path: Path) -> None:
schema = _named_schema("py_files", ["**/*.py"])
result = get_applicable_schemas("src/app.py", [schema], tmp_path)
assert len(result) == 1
assert result[0].name == "py_files"
def test_no_match_for_wrong_extension(self, tmp_path: Path) -> None:
schema = _named_schema("py_files", ["**/*.py"])
result = get_applicable_schemas("src/app.js", [schema], tmp_path)
assert len(result) == 0
def test_matches_anonymous_schema(self, tmp_path: Path) -> None:
schema = _anonymous_schema("config.json", tmp_path / "src")
result = get_applicable_schemas("src/config.json", [schema], tmp_path)
assert len(result) == 1
def test_anonymous_no_match_different_dir(self, tmp_path: Path) -> None:
schema = _anonymous_schema("config.json", tmp_path / "src")
result = get_applicable_schemas("other/config.json", [schema], tmp_path)
assert len(result) == 0
def test_multiple_schemas_match(self, tmp_path: Path) -> None:
named = _named_schema("all_yml", ["**/*.yml"])
anon = _anonymous_schema("config.yml", tmp_path / "src")
result = get_applicable_schemas("src/config.yml", [named, anon], tmp_path)
assert len(result) == 2
def test_named_schema_specific_dir_pattern(self, tmp_path: Path) -> None:
schema = _named_schema("src_only", ["src/**/*.py"])
assert get_applicable_schemas("src/main.py", [schema], tmp_path)
assert not get_applicable_schemas("tests/main.py", [schema], tmp_path)
class TestAnonymousSchemaOutsideProject:
"""Tests for _anonymous_schema_matches when target is outside project_root."""
def test_returns_false_when_target_outside_project(self, tmp_path: Path) -> None:
"""Anonymous schema whose target resolves outside project_root returns False."""
from deepwork.deepschema.matcher import _anonymous_schema_matches
# Schema in /outside/ directory, target would be /outside/config.json
schema = DeepSchema(
name="config.json",
schema_type="anonymous",
source_path=Path("/outside/.deepschema.config.json.yml"),
requirements={"test": "MUST pass"},
)
# filepath is relative to tmp_path, but target resolves to /outside/config.json
result = _anonymous_schema_matches("config.json", schema, tmp_path)
assert result is False
class TestGetSchemasForFileFast:
def test_finds_named_schema(self, tmp_path: Path) -> None:
schema_dir = tmp_path / ".deepwork" / "schemas" / "py_files"
schema_dir.mkdir(parents=True)
(schema_dir / "deepschema.yml").write_text(
"matchers:\n - '**/*.py'\nrequirements:\n r1: 'MUST exist'\n",
encoding="utf-8",
)
result = get_schemas_for_file_fast("src/app.py", tmp_path)
assert len(result) == 1
assert result[0].name == "py_files"
def test_finds_anonymous_schema(self, tmp_path: Path) -> None:
src = tmp_path / "src"
src.mkdir()
(src / ".deepschema.app.py.yml").write_text(
"requirements:\n r1: 'MUST exist'\n",
encoding="utf-8",
)
result = get_schemas_for_file_fast("src/app.py", tmp_path)
assert len(result) == 1
assert result[0].name == "app.py"
def test_returns_empty_when_no_schemas(self, tmp_path: Path) -> None:
result = get_schemas_for_file_fast("src/app.py", tmp_path)
assert result == []
def test_skips_named_schema_with_parse_error(self, tmp_path: Path) -> None:
"""Named schema with parse error is skipped, not crash."""
schema_dir = tmp_path / ".deepwork" / "schemas" / "broken"
schema_dir.mkdir(parents=True)
(schema_dir / "deepschema.yml").write_text("[invalid yaml]", encoding="utf-8")
# Should not raise — the broken schema is silently skipped
result = get_schemas_for_file_fast("src/app.py", tmp_path)
# No broken schemas in result
assert all(s.name != "broken" for s in result)
def test_skips_anonymous_schema_with_parse_error(self, tmp_path: Path) -> None:
"""Anonymous schema with parse error is skipped, not crash."""
src = tmp_path / "src"
src.mkdir()
(src / ".deepschema.app.py.yml").write_text("[invalid yaml]", encoding="utf-8")
# Should not raise — the broken anonymous schema is silently skipped
result = get_schemas_for_file_fast("src/app.py", tmp_path)
assert result == []
# THIS TEST VALIDATES A HARD REQUIREMENT (DW-REQ-011.6).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_returns_both_named_and_anonymous(self, tmp_path: Path) -> None:
"""When both a named and anonymous schema apply, both are returned."""
# Named schema matching *.yml files
schema_dir = tmp_path / ".deepwork" / "schemas" / "yml_files"
schema_dir.mkdir(parents=True)
(schema_dir / "deepschema.yml").write_text(
"matchers:\n - '**/*.yml'\nrequirements:\n generic: 'MUST be valid'\n",
encoding="utf-8",
)
# Anonymous schema for a specific yml file
src = tmp_path / "src"
src.mkdir()
(src / ".deepschema.config.yml.yml").write_text(
"requirements:\n specific: 'MUST have timeout field'\n",
encoding="utf-8",
)
result = get_schemas_for_file_fast("src/config.yml", tmp_path)
assert len(result) == 2
names = {s.name for s in result}
assert "yml_files" in names
assert "config.yml" in names