-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtest_discovery.py
More file actions
278 lines (246 loc) · 10.9 KB
/
Copy pathtest_discovery.py
File metadata and controls
278 lines (246 loc) · 10.9 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
"""Tests for job folder discovery (deepwork.jobs.discovery)."""
from pathlib import Path
import pytest
from deepwork.jobs.discovery import (
ENV_ADDITIONAL_JOBS_FOLDERS,
ENV_DEV,
find_job_dir,
get_job_folders,
load_all_jobs,
)
def _create_minimal_job(parent: Path, job_name: str) -> Path:
"""Create a minimal valid job directory for testing."""
job_dir = parent / job_name
job_dir.mkdir(parents=True, exist_ok=True)
steps_dir = job_dir / "steps"
steps_dir.mkdir(exist_ok=True)
(steps_dir / "step1.md").write_text("# Step 1\n\nDo step 1.")
(job_dir / "job.yml").write_text(
f"""
name: {job_name}
version: "1.0.0"
summary: Test job {job_name}
common_job_info_provided_to_all_steps_at_runtime: A test job
steps:
- id: step1
name: Step 1
description: First step
instructions_file: steps/step1.md
outputs: {{}}
reviews: []
workflows:
- name: main
summary: Main workflow
steps:
- step1
"""
)
return job_dir
class TestGetJobFolders:
"""Tests for get_job_folders."""
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.1.2).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_default_folders_include_project_jobs(self, tmp_path: Path) -> None:
folders = get_job_folders(tmp_path)
assert tmp_path / ".deepwork" / "jobs" in folders
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.1.3, JOBS-REQ-008.1.4).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_default_folders_include_standard_jobs(self, tmp_path: Path) -> None:
from deepwork.jobs.discovery import _STANDARD_JOBS_DIR
folders = get_job_folders(tmp_path)
assert _STANDARD_JOBS_DIR in folders
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.1.5, JOBS-REQ-008.1.6).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_env_var_appends_folders(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv(ENV_ADDITIONAL_JOBS_FOLDERS, "/extra/a:/extra/b")
folders = get_job_folders(tmp_path)
assert Path("/extra/a") in folders
assert Path("/extra/b") in folders
# Defaults should still be present
assert tmp_path / ".deepwork" / "jobs" in folders
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.1.7).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_env_var_empty_is_ignored(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv(ENV_ADDITIONAL_JOBS_FOLDERS, "")
folders = get_job_folders(tmp_path)
# Should only have the two defaults
assert len(folders) == 2
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.1.8).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_env_var_strips_whitespace(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv(ENV_ADDITIONAL_JOBS_FOLDERS, " /extra/a : /extra/b ")
folders = get_job_folders(tmp_path)
assert Path("/extra/a") in folders
assert Path("/extra/b") in folders
def test_dev_mode_places_additional_folders_first(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv(ENV_DEV, "1")
monkeypatch.setenv(ENV_ADDITIONAL_JOBS_FOLDERS, "/extra/a:/extra/b")
folders = get_job_folders(tmp_path)
# Additional folders must come before local and standard
idx_extra_a = folders.index(Path("/extra/a"))
idx_extra_b = folders.index(Path("/extra/b"))
idx_local = folders.index(tmp_path / ".deepwork" / "jobs")
assert idx_extra_a < idx_local
assert idx_extra_b < idx_local
def test_dev_mode_without_additional_folders_preserves_defaults(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
from deepwork.jobs.discovery import _STANDARD_JOBS_DIR
monkeypatch.setenv(ENV_DEV, "1")
monkeypatch.delenv(ENV_ADDITIONAL_JOBS_FOLDERS, raising=False)
folders = get_job_folders(tmp_path)
assert tmp_path / ".deepwork" / "jobs" in folders
assert _STANDARD_JOBS_DIR in folders
class TestLoadAllJobs:
"""Tests for load_all_jobs."""
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.2.1, JOBS-REQ-008.2.4, JOBS-REQ-008.2.7, JOBS-REQ-008.2.8, JOBS-REQ-008.2.11).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_loads_from_project_jobs(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
jobs_dir = tmp_path / ".deepwork" / "jobs"
_create_minimal_job(jobs_dir, "my_job")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [pr / ".deepwork" / "jobs"],
)
jobs, errors = load_all_jobs(tmp_path)
assert len(jobs) == 1
assert jobs[0].name == "my_job"
assert len(errors) == 0
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.2.1).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_loads_from_multiple_folders(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
folder_a = tmp_path / "folder_a"
folder_b = tmp_path / "folder_b"
_create_minimal_job(folder_a, "job_a")
_create_minimal_job(folder_b, "job_b")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder_a, folder_b],
)
jobs, errors = load_all_jobs(tmp_path)
names = {j.name for j in jobs}
assert names == {"job_a", "job_b"}
assert len(errors) == 0
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.2.5, JOBS-REQ-008.2.6, JOBS-REQ-008.4.5).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_first_folder_wins_for_duplicate_name(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
folder_a = tmp_path / "folder_a"
folder_b = tmp_path / "folder_b"
_create_minimal_job(folder_a, "same_name")
_create_minimal_job(folder_b, "same_name")
# Patch folder_b's job to have a different summary so we can distinguish
(folder_b / "same_name" / "job.yml").write_text(
(folder_b / "same_name" / "job.yml")
.read_text()
.replace("Test job same_name", "SHOULD NOT APPEAR")
)
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder_a, folder_b],
)
jobs, errors = load_all_jobs(tmp_path)
assert len(jobs) == 1
assert jobs[0].summary == "Test job same_name"
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.2.2).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_skips_nonexistent_folders(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [tmp_path / "does_not_exist"],
)
jobs, errors = load_all_jobs(tmp_path)
assert len(jobs) == 0
assert len(errors) == 0
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.2.9, JOBS-REQ-008.2.11, JOBS-REQ-008.5.1, JOBS-REQ-008.5.3).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_skips_invalid_jobs(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
folder = tmp_path / "jobs"
bad_job = folder / "bad_job"
bad_job.mkdir(parents=True)
(bad_job / "job.yml").write_text("invalid: [yaml")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder],
)
jobs, errors = load_all_jobs(tmp_path)
assert len(jobs) == 0
assert len(errors) == 1
assert errors[0].job_name == "bad_job"
assert errors[0].job_dir == str(bad_job)
assert errors[0].error # non-empty error message
class TestFindJobDir:
"""Tests for find_job_dir."""
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.3.1, JOBS-REQ-008.3.2).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_finds_in_first_folder(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
folder = tmp_path / "jobs"
_create_minimal_job(folder, "target")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder],
)
result = find_job_dir(tmp_path, "target")
assert result == folder / "target"
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.3.1, JOBS-REQ-008.3.2, JOBS-REQ-008.3.4).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_finds_in_second_folder(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
folder_a = tmp_path / "a"
folder_b = tmp_path / "b"
folder_a.mkdir()
_create_minimal_job(folder_b, "target")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder_a, folder_b],
)
result = find_job_dir(tmp_path, "target")
assert result == folder_b / "target"
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.3.3).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_returns_none_when_not_found(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [tmp_path],
)
result = find_job_dir(tmp_path, "nonexistent")
assert result is None
# THIS TEST VALIDATES A HARD REQUIREMENT (JOBS-REQ-008.3.1, JOBS-REQ-008.3.2).
# YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES
def test_prefers_first_folder_on_duplicate(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
folder_a = tmp_path / "a"
folder_b = tmp_path / "b"
_create_minimal_job(folder_a, "dup")
_create_minimal_job(folder_b, "dup")
monkeypatch.setattr(
"deepwork.jobs.discovery.get_job_folders",
lambda pr: [folder_a, folder_b],
)
result = find_job_dir(tmp_path, "dup")
assert result == folder_a / "dup"
def test_dev_mode_prefers_additional_folder_over_local(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
local_jobs = tmp_path / ".deepwork" / "jobs"
extra_jobs = tmp_path / "library_jobs"
_create_minimal_job(local_jobs, "my_job")
_create_minimal_job(extra_jobs, "my_job")
monkeypatch.setenv(ENV_DEV, "1")
monkeypatch.setenv(ENV_ADDITIONAL_JOBS_FOLDERS, str(extra_jobs))
# In dev mode the extra folder should win over the local copy
result = find_job_dir(tmp_path, "my_job")
assert result == extra_jobs / "my_job"