atdd 0.4.6__py3-none-any.whl → 0.4.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- atdd/coach/commands/inventory.py +91 -3
- atdd/coach/commands/registry.py +114 -5
- atdd/coach/utils/config.py +131 -0
- atdd/coach/utils/train_spec_phase.py +97 -0
- atdd/coach/validators/shared_fixtures.py +68 -1
- atdd/coach/validators/test_train_registry.py +189 -0
- atdd/coder/validators/test_train_infrastructure.py +236 -2
- atdd/planner/schemas/train.schema.json +125 -2
- atdd/planner/validators/test_train_validation.py +667 -2
- atdd/tester/validators/test_train_backend_e2e.py +371 -0
- atdd/tester/validators/test_train_frontend_e2e.py +292 -0
- atdd/tester/validators/test_train_frontend_python.py +282 -0
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/METADATA +1 -1
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/RECORD +18 -12
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/WHEEL +0 -0
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/entry_points.txt +0 -0
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/licenses/LICENSE +0 -0
- {atdd-0.4.6.dist-info → atdd-0.4.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tester validators: Train frontend Python (Streamlit) convention validation.
|
|
3
|
+
|
|
4
|
+
Train First-Class Spec v0.6 Section 8: Frontend Python Conventions
|
|
5
|
+
|
|
6
|
+
Validates:
|
|
7
|
+
- SPEC-TRAIN-VAL-0029: Frontend Python code paths
|
|
8
|
+
- SPEC-TRAIN-VAL-0030: Frontend Python test paths
|
|
9
|
+
|
|
10
|
+
Frontend Python (Streamlit) should follow:
|
|
11
|
+
- Code paths: python/streamlit/ or python/apps/
|
|
12
|
+
- Test paths: python/tests/streamlit/test_<train_id>[_<slug>].py
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
import re
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Dict, List, Tuple
|
|
19
|
+
|
|
20
|
+
import atdd
|
|
21
|
+
from atdd.coach.utils.repo import find_repo_root
|
|
22
|
+
from atdd.coach.utils.train_spec_phase import (
|
|
23
|
+
TrainSpecPhase,
|
|
24
|
+
should_enforce,
|
|
25
|
+
emit_phase_warning
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Path constants
|
|
30
|
+
REPO_ROOT = find_repo_root()
|
|
31
|
+
PYTHON_DIR = REPO_ROOT / "python"
|
|
32
|
+
STREAMLIT_DIR = PYTHON_DIR / "streamlit"
|
|
33
|
+
APPS_DIR = PYTHON_DIR / "apps"
|
|
34
|
+
STREAMLIT_TESTS_DIR = PYTHON_DIR / "tests" / "streamlit"
|
|
35
|
+
|
|
36
|
+
# Package resources
|
|
37
|
+
ATDD_PKG_DIR = Path(atdd.__file__).resolve().parent
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _get_trains_with_frontend_python() -> List[str]:
|
|
41
|
+
"""
|
|
42
|
+
Get train IDs that expect frontend_python implementation.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
List of train_id strings
|
|
46
|
+
"""
|
|
47
|
+
import yaml
|
|
48
|
+
|
|
49
|
+
train_ids = []
|
|
50
|
+
trains_registry_path = REPO_ROOT / "plan" / "_trains.yaml"
|
|
51
|
+
|
|
52
|
+
if not trains_registry_path.exists():
|
|
53
|
+
return train_ids
|
|
54
|
+
|
|
55
|
+
with open(trains_registry_path) as f:
|
|
56
|
+
data = yaml.safe_load(f)
|
|
57
|
+
|
|
58
|
+
trains_dir = REPO_ROOT / "plan" / "_trains"
|
|
59
|
+
|
|
60
|
+
for theme_key, categories in data.get("trains", {}).items():
|
|
61
|
+
if isinstance(categories, dict):
|
|
62
|
+
for category_key, trains_list in categories.items():
|
|
63
|
+
if isinstance(trains_list, list):
|
|
64
|
+
for train in trains_list:
|
|
65
|
+
train_id = train.get("train_id")
|
|
66
|
+
if not train_id:
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
# Check expectations in registry
|
|
70
|
+
expectations = train.get("expectations", {})
|
|
71
|
+
if expectations.get("frontend_python"):
|
|
72
|
+
train_ids.append(train_id)
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
# Check YAML file for expectations
|
|
76
|
+
train_file = trains_dir / f"{train_id}.yaml"
|
|
77
|
+
if train_file.exists():
|
|
78
|
+
try:
|
|
79
|
+
with open(train_file) as tf:
|
|
80
|
+
train_data = yaml.safe_load(tf)
|
|
81
|
+
yaml_expectations = train_data.get("expectations", {})
|
|
82
|
+
if yaml_expectations.get("frontend_python"):
|
|
83
|
+
train_ids.append(train_id)
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
return train_ids
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _find_frontend_python_code_files() -> List[Path]:
|
|
91
|
+
"""
|
|
92
|
+
Find all frontend Python code files.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
List of paths to .py files in streamlit/ or apps/ directories
|
|
96
|
+
"""
|
|
97
|
+
files = []
|
|
98
|
+
|
|
99
|
+
for search_dir in [STREAMLIT_DIR, APPS_DIR]:
|
|
100
|
+
if search_dir.exists():
|
|
101
|
+
for py_file in search_dir.rglob("*.py"):
|
|
102
|
+
if not py_file.name.startswith("_"):
|
|
103
|
+
files.append(py_file)
|
|
104
|
+
|
|
105
|
+
return files
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _find_frontend_python_test_files() -> List[Tuple[Path, str]]:
|
|
109
|
+
"""
|
|
110
|
+
Find all frontend Python test files.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
List of (path, train_id_from_filename) tuples
|
|
114
|
+
"""
|
|
115
|
+
tests = []
|
|
116
|
+
|
|
117
|
+
if not STREAMLIT_TESTS_DIR.exists():
|
|
118
|
+
return tests
|
|
119
|
+
|
|
120
|
+
# Pattern: test_<train_id>*.py
|
|
121
|
+
for test_file in STREAMLIT_TESTS_DIR.glob("test_*.py"):
|
|
122
|
+
filename = test_file.stem
|
|
123
|
+
match = re.match(r"test_(\d{4}-[a-z0-9-]+)", filename)
|
|
124
|
+
if match:
|
|
125
|
+
train_id = match.group(1)
|
|
126
|
+
tests.append((test_file, train_id))
|
|
127
|
+
|
|
128
|
+
return tests
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _check_train_code_references(train_id: str) -> List[Path]:
|
|
132
|
+
"""
|
|
133
|
+
Find code files that reference a specific train.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
List of paths that contain train_id reference
|
|
137
|
+
"""
|
|
138
|
+
matching_files = []
|
|
139
|
+
|
|
140
|
+
for search_dir in [STREAMLIT_DIR, APPS_DIR]:
|
|
141
|
+
if not search_dir.exists():
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
for py_file in search_dir.rglob("*.py"):
|
|
145
|
+
try:
|
|
146
|
+
with open(py_file, 'r', encoding='utf-8') as f:
|
|
147
|
+
content = f.read()
|
|
148
|
+
|
|
149
|
+
# Check for train_id in file
|
|
150
|
+
if train_id in content:
|
|
151
|
+
matching_files.append(py_file)
|
|
152
|
+
|
|
153
|
+
except Exception:
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
return matching_files
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ============================================================================
|
|
160
|
+
# FRONTEND PYTHON VALIDATORS
|
|
161
|
+
# ============================================================================
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@pytest.mark.platform
|
|
165
|
+
def test_frontend_python_code_paths():
|
|
166
|
+
"""
|
|
167
|
+
SPEC-TRAIN-VAL-0029: Frontend Python code in allowed paths
|
|
168
|
+
|
|
169
|
+
Given: Trains expecting frontend_python implementation
|
|
170
|
+
When: Checking code locations
|
|
171
|
+
Then: Code is in python/streamlit/ or python/apps/
|
|
172
|
+
|
|
173
|
+
Section 8: Frontend Python Code Paths
|
|
174
|
+
"""
|
|
175
|
+
trains_with_frontend_python = _get_trains_with_frontend_python()
|
|
176
|
+
|
|
177
|
+
if not trains_with_frontend_python:
|
|
178
|
+
pytest.skip("No trains expecting frontend_python implementation")
|
|
179
|
+
|
|
180
|
+
code_files = _find_frontend_python_code_files()
|
|
181
|
+
|
|
182
|
+
if not code_files:
|
|
183
|
+
if should_enforce(TrainSpecPhase.FULL_ENFORCEMENT):
|
|
184
|
+
pytest.fail(
|
|
185
|
+
f"Trains expect frontend_python but no code found in python/streamlit/ or python/apps/:\n"
|
|
186
|
+
f" Trains: {trains_with_frontend_python}"
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
emit_phase_warning(
|
|
190
|
+
"SPEC-TRAIN-VAL-0029",
|
|
191
|
+
f"{len(trains_with_frontend_python)} trains expect frontend_python but no code found",
|
|
192
|
+
TrainSpecPhase.FULL_ENFORCEMENT
|
|
193
|
+
)
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
# Check that trains with expectations have corresponding code
|
|
197
|
+
missing_code = []
|
|
198
|
+
for train_id in trains_with_frontend_python:
|
|
199
|
+
refs = _check_train_code_references(train_id)
|
|
200
|
+
if not refs:
|
|
201
|
+
missing_code.append(f"{train_id}: no code references found")
|
|
202
|
+
|
|
203
|
+
if missing_code:
|
|
204
|
+
if should_enforce(TrainSpecPhase.FULL_ENFORCEMENT):
|
|
205
|
+
pytest.fail(
|
|
206
|
+
f"Trains missing frontend_python code:\n " + "\n ".join(missing_code) +
|
|
207
|
+
"\n\nExpected code in: python/streamlit/ or python/apps/"
|
|
208
|
+
)
|
|
209
|
+
else:
|
|
210
|
+
for missing in missing_code:
|
|
211
|
+
emit_phase_warning(
|
|
212
|
+
"SPEC-TRAIN-VAL-0029",
|
|
213
|
+
missing,
|
|
214
|
+
TrainSpecPhase.FULL_ENFORCEMENT
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@pytest.mark.platform
|
|
219
|
+
def test_frontend_python_test_paths():
|
|
220
|
+
"""
|
|
221
|
+
SPEC-TRAIN-VAL-0030: Frontend Python tests in correct location
|
|
222
|
+
|
|
223
|
+
Given: Frontend Python test files
|
|
224
|
+
When: Checking test paths
|
|
225
|
+
Then: Path follows python/tests/streamlit/test_<train_id>[_<slug>].py
|
|
226
|
+
|
|
227
|
+
Section 8: Frontend Python Test Paths
|
|
228
|
+
"""
|
|
229
|
+
trains_with_frontend_python = _get_trains_with_frontend_python()
|
|
230
|
+
|
|
231
|
+
if not trains_with_frontend_python:
|
|
232
|
+
pytest.skip("No trains expecting frontend_python implementation")
|
|
233
|
+
|
|
234
|
+
test_files = _find_frontend_python_test_files()
|
|
235
|
+
|
|
236
|
+
# Check that tests exist for trains that expect frontend_python
|
|
237
|
+
train_ids_with_tests = {train_id for _, train_id in test_files}
|
|
238
|
+
|
|
239
|
+
missing_tests = []
|
|
240
|
+
for train_id in trains_with_frontend_python:
|
|
241
|
+
if train_id not in train_ids_with_tests:
|
|
242
|
+
missing_tests.append(
|
|
243
|
+
f"{train_id}: missing test at python/tests/streamlit/test_{train_id}.py"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
if missing_tests:
|
|
247
|
+
if should_enforce(TrainSpecPhase.FULL_ENFORCEMENT):
|
|
248
|
+
pytest.fail(
|
|
249
|
+
f"Trains missing frontend_python tests:\n " + "\n ".join(missing_tests) +
|
|
250
|
+
"\n\nExpected: python/tests/streamlit/test_<train_id>[_<slug>].py"
|
|
251
|
+
)
|
|
252
|
+
else:
|
|
253
|
+
for missing in missing_tests:
|
|
254
|
+
emit_phase_warning(
|
|
255
|
+
"SPEC-TRAIN-VAL-0030",
|
|
256
|
+
missing,
|
|
257
|
+
TrainSpecPhase.FULL_ENFORCEMENT
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Validate existing test file naming
|
|
261
|
+
invalid_tests = []
|
|
262
|
+
all_train_ids = set(trains_with_frontend_python)
|
|
263
|
+
|
|
264
|
+
for test_path, train_id in test_files:
|
|
265
|
+
if train_id not in all_train_ids:
|
|
266
|
+
rel_path = test_path.relative_to(REPO_ROOT)
|
|
267
|
+
invalid_tests.append(
|
|
268
|
+
f"{rel_path}: train_id '{train_id}' not in trains expecting frontend_python"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
if invalid_tests:
|
|
272
|
+
if should_enforce(TrainSpecPhase.FULL_ENFORCEMENT):
|
|
273
|
+
pytest.fail(
|
|
274
|
+
f"Frontend Python test path issues:\n " + "\n ".join(invalid_tests)
|
|
275
|
+
)
|
|
276
|
+
else:
|
|
277
|
+
for invalid in invalid_tests:
|
|
278
|
+
emit_phase_warning(
|
|
279
|
+
"SPEC-TRAIN-VAL-0030",
|
|
280
|
+
invalid,
|
|
281
|
+
TrainSpecPhase.FULL_ENFORCEMENT
|
|
282
|
+
)
|
|
@@ -12,9 +12,9 @@ atdd/coach/commands/gate.py,sha256=_V2GypqoGixTs_kLWxFF3HgEt-Wi2r6Iv0YL75yWrWo,5
|
|
|
12
12
|
atdd/coach/commands/infer_governance_status.py,sha256=MlLnx8SrJAOQq2rfuxLZMmyNylCQ-OYx4tSi_iFdhRA,4504
|
|
13
13
|
atdd/coach/commands/initializer.py,sha256=wuvzj7QwA11ilNjRZU6Bx2bLQXITdBHJxR9_mZK7xjA,6503
|
|
14
14
|
atdd/coach/commands/interface.py,sha256=FwBrJpWkfSL9n4n0HT_EC-alseXgU0bweKD4TImyHN0,40483
|
|
15
|
-
atdd/coach/commands/inventory.py,sha256=
|
|
15
|
+
atdd/coach/commands/inventory.py,sha256=7Znpx2mFh3rQXEguUzIaBage3B5m1L_K2esYyd3pfLY,24764
|
|
16
16
|
atdd/coach/commands/migration.py,sha256=wRxU7emvvHqWt1MvXKkNTkPBjp0sU9g8F5Uy5yV2YfI,8177
|
|
17
|
-
atdd/coach/commands/registry.py,sha256=
|
|
17
|
+
atdd/coach/commands/registry.py,sha256=9iWW34CCJAr36v91863u8TDdlGQJdLpYYBGb1ojtS1Q,71546
|
|
18
18
|
atdd/coach/commands/session.py,sha256=MhuWXd5TR6bB3w0t8vANeZx3L476qwLT6EUQMwg-wQA,14268
|
|
19
19
|
atdd/coach/commands/sync.py,sha256=SLNzhcc6IuzMofMbkH9wM9rBSk5tPfcWPKXn9TaSZ-Y,13782
|
|
20
20
|
atdd/coach/commands/test_interface.py,sha256=a7ut2Hhk0PnQ5LfJZkoQwfkfkVuB5OHA4QBwOS0-jcg,16870
|
|
@@ -30,16 +30,19 @@ atdd/coach/schemas/manifest.schema.json,sha256=WO13-YF_FgH1awh96khCtk-112b6XSC24
|
|
|
30
30
|
atdd/coach/templates/ATDD.md,sha256=MLbrVbCETJre4c05d5FXGuf6W95Hz9E0jpE4RI9r4cg,13237
|
|
31
31
|
atdd/coach/templates/SESSION-TEMPLATE.md,sha256=cGT_0x5KLbPHOCiuM8evLGpWKIlR-aggqxiBtbjSJoo,9478
|
|
32
32
|
atdd/coach/utils/__init__.py,sha256=7Jbo-heJEKSAn6I0s35z_2S4R8qGZ48PL6a2IntcNYg,148
|
|
33
|
+
atdd/coach/utils/config.py,sha256=6XXaaeVfjTrJwdaR0IZ6Kf1-1ZHhaCVLO5pNx_A2el4,3320
|
|
33
34
|
atdd/coach/utils/repo.py,sha256=0kiF5WpVTen0nO14u5T0RflznZhgGco2i9CwKobOh38,3757
|
|
35
|
+
atdd/coach/utils/train_spec_phase.py,sha256=Mk8CiMoO6jb-VGttHgI20KIG26r9cjSz4gDfk01q1M0,3025
|
|
34
36
|
atdd/coach/utils/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
37
|
atdd/coach/utils/graph/urn.py,sha256=O2AHIB_CmmMUvXzyejc_oFReNW_rOcw7m4qaqSYcnNQ,33558
|
|
36
38
|
atdd/coach/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
atdd/coach/validators/shared_fixtures.py,sha256=
|
|
39
|
+
atdd/coach/validators/shared_fixtures.py,sha256=AUb-387kEc584umEzG_TnzEzcHkYignrobkgrRcQOso,14518
|
|
38
40
|
atdd/coach/validators/test_enrich_wagon_registry.py,sha256=WeTwYJqoNY6mEYc-QAvQo7YVagSOjaNKxB6Q6dpWqIM,6561
|
|
39
41
|
atdd/coach/validators/test_registry.py,sha256=ffN70yA_1xxL3R8gdpGbY2M8dQXyuajIZhBZ-ylNiNs,17845
|
|
40
42
|
atdd/coach/validators/test_release_versioning.py,sha256=B40DfbtrSGguPc537zXmjT75hhySfocWLzJWqOKZQcU,5678
|
|
41
43
|
atdd/coach/validators/test_session_validation.py,sha256=0VszXtFwRTO04b5CxDPO3klk0VfiqlpdbNpshjMn-qU,39079
|
|
42
44
|
atdd/coach/validators/test_traceability.py,sha256=qTyobt41VBiCr6xRN2C7BPtGYvk_2poVQIe814Blt8E,15977
|
|
45
|
+
atdd/coach/validators/test_train_registry.py,sha256=YDnmC1MP4TfAMZzyldh0hfHMo7LY27DZ2GXmhQx7vds,6021
|
|
43
46
|
atdd/coach/validators/test_update_feature_paths.py,sha256=zOKVDgEIpncSJwDh_shyyou5Pu-Ai7Z_XgF8zAbQVTA,4528
|
|
44
47
|
atdd/coach/validators/test_validate_contract_consumers.py,sha256=b01yam_GwAERF6YaFmUV6Bd7SNMWQkUKBfNVvplbEcU,12613
|
|
45
48
|
atdd/coder/__init__.py,sha256=Rmi5S7Pzx7qsRe5MC66GduNGmkssWWnElkVvvNHFDgU,45
|
|
@@ -84,7 +87,7 @@ atdd/coder/validators/test_presentation_convention.py,sha256=ceAtg_sTEJiPkHVfnwB
|
|
|
84
87
|
atdd/coder/validators/test_python_architecture.py,sha256=USnSujKVu7_BC2ij-pTSHyiFi4iBMBemIPR7oXYQ3B4,25243
|
|
85
88
|
atdd/coder/validators/test_quality_metrics.py,sha256=vLWPfL0x9sfCvKXO4uECW61RnJTsjbmuEUjCsBcUmuA,12551
|
|
86
89
|
atdd/coder/validators/test_station_master_pattern.py,sha256=biYwXAftpXdhIhDjn2RrVTdEdvTWPW5ddm2gQubJBXQ,9280
|
|
87
|
-
atdd/coder/validators/test_train_infrastructure.py,sha256=
|
|
90
|
+
atdd/coder/validators/test_train_infrastructure.py,sha256=CXOSn_CPk3wJhEVNYztSdiV_ecIgnJkulD-xWivregE,24424
|
|
88
91
|
atdd/coder/validators/test_train_urns.py,sha256=TvSNHbvG8SAtAPaS2K8mMgzE8GbJtrTaF4iEgkJEIIk,10099
|
|
89
92
|
atdd/coder/validators/test_typescript_architecture.py,sha256=gi76IwlqX_MpWsr8CXWH7v16KAoud-1OY92iuN-0BpU,22176
|
|
90
93
|
atdd/coder/validators/test_usecase_structure.py,sha256=nAeqmLWRCstXT8fDuxqk6iVcH4TLHjTvlaGDpanD9sM,14077
|
|
@@ -105,7 +108,7 @@ atdd/planner/schemas/acceptance.schema.json,sha256=3mQV067ipiYsTcXkDll4zWJBYdOkB
|
|
|
105
108
|
atdd/planner/schemas/appendix.schema.json,sha256=aMqKIwHAgEoO49v8O8isyP1S3oTNCCEeIX3gNmge3TY,2885
|
|
106
109
|
atdd/planner/schemas/component.schema.json,sha256=B-RgVUmG02T8j0jL1FjAPhVSIGiditJ0UsILNxYXElQ,3891
|
|
107
110
|
atdd/planner/schemas/feature.schema.json,sha256=wZAIzroUv74iAS2tzIDPhWu2EIDMSRtzsMj5mAfLVdY,7228
|
|
108
|
-
atdd/planner/schemas/train.schema.json,sha256=
|
|
111
|
+
atdd/planner/schemas/train.schema.json,sha256=YU58Pc_EuhwUR0tuwyXWOQBeKei0TsB4wkRLNcyE0Ig,9877
|
|
109
112
|
atdd/planner/schemas/wagon.schema.json,sha256=Vy9QCd7aN9yUS5hTPv0XiZ_vw4MEWeDfvCW7jr9Dn6o,11699
|
|
110
113
|
atdd/planner/schemas/wmbt.schema.json,sha256=KU_D6r0kQTJod-XHQT5QiiHcUUPJrLgg3aPeZdrRBUU,2298
|
|
111
114
|
atdd/planner/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -115,7 +118,7 @@ atdd/planner/validators/test_plan_cross_refs.py,sha256=kxlq1uZ2u4mn3r8wHJjXVJsB8
|
|
|
115
118
|
atdd/planner/validators/test_plan_uniqueness.py,sha256=rlC5khAoBkgpTZJdyHi1JbDUj14v1JiGBFv2iV_AP_Y,7735
|
|
116
119
|
atdd/planner/validators/test_plan_urn_resolution.py,sha256=GoxFiRjOfp69FUmIyKGnsGgpYalOz3qfp6qjyCkga44,9440
|
|
117
120
|
atdd/planner/validators/test_plan_wagons.py,sha256=l4jbHf9Kg-Fy8Gz5O8BO7PDQKbbeLN0uctoErPK_YKI,7357
|
|
118
|
-
atdd/planner/validators/test_train_validation.py,sha256=
|
|
121
|
+
atdd/planner/validators/test_train_validation.py,sha256=7vlu3P8PenWgZhZCf9kO0UTM-k1n37Ds_jUvrJa-Np0,39264
|
|
119
122
|
atdd/planner/validators/test_wagon_urn_chain.py,sha256=KY_0vrj6CoiQJ80WbqfCGCYbup13cVssaxbNO0eVf74,26697
|
|
120
123
|
atdd/planner/validators/test_wmbt_consistency.py,sha256=jdfu4xWEozzBGwplKDXxuDQNLBDxB_AC96NHLkyHqQ8,10875
|
|
121
124
|
atdd/planner/validators/test_wmbt_vocabulary.py,sha256=PCivTzV7ntlZBa-PVzpBwEiKqLumsEZXfj1r2xl9usM,18803
|
|
@@ -180,11 +183,14 @@ atdd/tester/validators/test_red_layer_validation.py,sha256=otqohLMayIK4nPPF2fl-O
|
|
|
180
183
|
atdd/tester/validators/test_red_python_layer_structure.py,sha256=5p6mTieijO7MpZGuVODYm9acKkMJ1XeMYDZ3gxPGW0k,3467
|
|
181
184
|
atdd/tester/validators/test_red_supabase_layer_structure.py,sha256=zbUjsMWSJE1MPnLQx6Hk2lvMgNmMVUKq8a0rwKnp7Lo,3836
|
|
182
185
|
atdd/tester/validators/test_telemetry_structure.py,sha256=uU5frZnxSlOn60iHyqhe7Pg9b0wrOV7N14D4S6Aw6TE,22626
|
|
186
|
+
atdd/tester/validators/test_train_backend_e2e.py,sha256=Yx75JMjUgf86XTqeuc0k8yT41XuIquo05h2ce3lNb2w,10950
|
|
187
|
+
atdd/tester/validators/test_train_frontend_e2e.py,sha256=fpfUwTbAWzuqxbVKoaFw-ab4e3puK-uLC-ahf1jYgk8,8469
|
|
188
|
+
atdd/tester/validators/test_train_frontend_python.py,sha256=KK2U3oNFWLyBK7YHC0fU7shR05k93gVcO762AI8Q3pw,9018
|
|
183
189
|
atdd/tester/validators/test_typescript_test_naming.py,sha256=E-TyGv_GVlTfsbyuxrtv9sOWSZS_QcpH6rrJFbWoeeU,11280
|
|
184
190
|
atdd/tester/validators/test_typescript_test_structure.py,sha256=eV89SD1RaKtchBZupqhnJmaruoROosf3LwB4Fwe4UJI,2612
|
|
185
|
-
atdd-0.4.
|
|
186
|
-
atdd-0.4.
|
|
187
|
-
atdd-0.4.
|
|
188
|
-
atdd-0.4.
|
|
189
|
-
atdd-0.4.
|
|
190
|
-
atdd-0.4.
|
|
191
|
+
atdd-0.4.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
192
|
+
atdd-0.4.7.dist-info/METADATA,sha256=9kcgwnLFKtRapPjpY7J9n1UBjq8kOmS27bqdvr0_iek,8716
|
|
193
|
+
atdd-0.4.7.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
194
|
+
atdd-0.4.7.dist-info/entry_points.txt,sha256=-C3yrA1WQQfN3iuGmSzPapA5cKVBEYU5Q1HUffSJTbY,38
|
|
195
|
+
atdd-0.4.7.dist-info/top_level.txt,sha256=VKkf6Uiyrm4RS6ULCGM-v8AzYN8K2yg8SMqwJLoO-xs,5
|
|
196
|
+
atdd-0.4.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|