atdd 0.2.1__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/__init__.py +6 -0
- atdd/__main__.py +4 -0
- atdd/cli.py +404 -0
- atdd/coach/__init__.py +0 -0
- atdd/coach/commands/__init__.py +0 -0
- atdd/coach/commands/add_persistence_metadata.py +215 -0
- atdd/coach/commands/analyze_migrations.py +188 -0
- atdd/coach/commands/consumers.py +720 -0
- atdd/coach/commands/infer_governance_status.py +149 -0
- atdd/coach/commands/initializer.py +177 -0
- atdd/coach/commands/interface.py +1078 -0
- atdd/coach/commands/inventory.py +565 -0
- atdd/coach/commands/migration.py +240 -0
- atdd/coach/commands/registry.py +1560 -0
- atdd/coach/commands/session.py +430 -0
- atdd/coach/commands/sync.py +405 -0
- atdd/coach/commands/test_interface.py +399 -0
- atdd/coach/commands/test_runner.py +141 -0
- atdd/coach/commands/tests/__init__.py +1 -0
- atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
- atdd/coach/commands/traceability.py +4264 -0
- atdd/coach/conventions/session.convention.yaml +754 -0
- atdd/coach/overlays/__init__.py +2 -0
- atdd/coach/overlays/claude.md +2 -0
- atdd/coach/schemas/config.schema.json +34 -0
- atdd/coach/schemas/manifest.schema.json +101 -0
- atdd/coach/templates/ATDD.md +282 -0
- atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
- atdd/coach/utils/__init__.py +0 -0
- atdd/coach/utils/graph/__init__.py +0 -0
- atdd/coach/utils/graph/urn.py +875 -0
- atdd/coach/validators/__init__.py +0 -0
- atdd/coach/validators/shared_fixtures.py +365 -0
- atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
- atdd/coach/validators/test_registry.py +575 -0
- atdd/coach/validators/test_session_validation.py +1183 -0
- atdd/coach/validators/test_traceability.py +448 -0
- atdd/coach/validators/test_update_feature_paths.py +108 -0
- atdd/coach/validators/test_validate_contract_consumers.py +297 -0
- atdd/coder/__init__.py +1 -0
- atdd/coder/conventions/adapter.recipe.yaml +88 -0
- atdd/coder/conventions/backend.convention.yaml +460 -0
- atdd/coder/conventions/boundaries.convention.yaml +666 -0
- atdd/coder/conventions/commons.convention.yaml +460 -0
- atdd/coder/conventions/complexity.recipe.yaml +109 -0
- atdd/coder/conventions/component-naming.convention.yaml +178 -0
- atdd/coder/conventions/design.convention.yaml +327 -0
- atdd/coder/conventions/design.recipe.yaml +273 -0
- atdd/coder/conventions/dto.convention.yaml +660 -0
- atdd/coder/conventions/frontend.convention.yaml +542 -0
- atdd/coder/conventions/green.convention.yaml +1012 -0
- atdd/coder/conventions/presentation.convention.yaml +587 -0
- atdd/coder/conventions/refactor.convention.yaml +535 -0
- atdd/coder/conventions/technology.convention.yaml +206 -0
- atdd/coder/conventions/tests/__init__.py +0 -0
- atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
- atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
- atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
- atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
- atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
- atdd/coder/conventions/thinness.recipe.yaml +82 -0
- atdd/coder/conventions/train.convention.yaml +325 -0
- atdd/coder/conventions/verification.protocol.yaml +53 -0
- atdd/coder/schemas/design_system.schema.json +361 -0
- atdd/coder/validators/__init__.py +0 -0
- atdd/coder/validators/test_commons_structure.py +485 -0
- atdd/coder/validators/test_complexity.py +416 -0
- atdd/coder/validators/test_cross_language_consistency.py +431 -0
- atdd/coder/validators/test_design_system_compliance.py +413 -0
- atdd/coder/validators/test_dto_testing_patterns.py +268 -0
- atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
- atdd/coder/validators/test_green_layer_dependencies.py +148 -0
- atdd/coder/validators/test_green_python_layer_structure.py +103 -0
- atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
- atdd/coder/validators/test_import_boundaries.py +396 -0
- atdd/coder/validators/test_init_file_urns.py +593 -0
- atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
- atdd/coder/validators/test_presentation_convention.py +260 -0
- atdd/coder/validators/test_python_architecture.py +674 -0
- atdd/coder/validators/test_quality_metrics.py +420 -0
- atdd/coder/validators/test_station_master_pattern.py +244 -0
- atdd/coder/validators/test_train_infrastructure.py +454 -0
- atdd/coder/validators/test_train_urns.py +293 -0
- atdd/coder/validators/test_typescript_architecture.py +616 -0
- atdd/coder/validators/test_usecase_structure.py +421 -0
- atdd/coder/validators/test_wagon_boundaries.py +586 -0
- atdd/conftest.py +126 -0
- atdd/planner/__init__.py +1 -0
- atdd/planner/conventions/acceptance.convention.yaml +538 -0
- atdd/planner/conventions/appendix.convention.yaml +187 -0
- atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
- atdd/planner/conventions/component.convention.yaml +670 -0
- atdd/planner/conventions/criteria.convention.yaml +141 -0
- atdd/planner/conventions/feature.convention.yaml +371 -0
- atdd/planner/conventions/interface.convention.yaml +382 -0
- atdd/planner/conventions/steps.convention.yaml +141 -0
- atdd/planner/conventions/train.convention.yaml +552 -0
- atdd/planner/conventions/wagon.convention.yaml +275 -0
- atdd/planner/conventions/wmbt.convention.yaml +258 -0
- atdd/planner/schemas/acceptance.schema.json +336 -0
- atdd/planner/schemas/appendix.schema.json +78 -0
- atdd/planner/schemas/component.schema.json +114 -0
- atdd/planner/schemas/feature.schema.json +197 -0
- atdd/planner/schemas/train.schema.json +192 -0
- atdd/planner/schemas/wagon.schema.json +281 -0
- atdd/planner/schemas/wmbt.schema.json +59 -0
- atdd/planner/validators/__init__.py +0 -0
- atdd/planner/validators/conftest.py +5 -0
- atdd/planner/validators/test_draft_wagon_registry.py +374 -0
- atdd/planner/validators/test_plan_cross_refs.py +240 -0
- atdd/planner/validators/test_plan_uniqueness.py +224 -0
- atdd/planner/validators/test_plan_urn_resolution.py +268 -0
- atdd/planner/validators/test_plan_wagons.py +174 -0
- atdd/planner/validators/test_train_validation.py +514 -0
- atdd/planner/validators/test_wagon_urn_chain.py +648 -0
- atdd/planner/validators/test_wmbt_consistency.py +327 -0
- atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
- atdd/tester/__init__.py +1 -0
- atdd/tester/conventions/artifact.convention.yaml +257 -0
- atdd/tester/conventions/contract.convention.yaml +1009 -0
- atdd/tester/conventions/filename.convention.yaml +555 -0
- atdd/tester/conventions/migration.convention.yaml +509 -0
- atdd/tester/conventions/red.convention.yaml +797 -0
- atdd/tester/conventions/routing.convention.yaml +51 -0
- atdd/tester/conventions/telemetry.convention.yaml +458 -0
- atdd/tester/schemas/a11y.tmpl.json +17 -0
- atdd/tester/schemas/artifact.schema.json +189 -0
- atdd/tester/schemas/contract.schema.json +591 -0
- atdd/tester/schemas/contract.tmpl.json +95 -0
- atdd/tester/schemas/db.tmpl.json +20 -0
- atdd/tester/schemas/e2e.tmpl.json +17 -0
- atdd/tester/schemas/edge_function.tmpl.json +17 -0
- atdd/tester/schemas/event.tmpl.json +17 -0
- atdd/tester/schemas/http.tmpl.json +19 -0
- atdd/tester/schemas/job.tmpl.json +18 -0
- atdd/tester/schemas/load.tmpl.json +21 -0
- atdd/tester/schemas/metric.tmpl.json +19 -0
- atdd/tester/schemas/pack.schema.json +139 -0
- atdd/tester/schemas/realtime.tmpl.json +20 -0
- atdd/tester/schemas/rls.tmpl.json +18 -0
- atdd/tester/schemas/script.tmpl.json +16 -0
- atdd/tester/schemas/sec.tmpl.json +18 -0
- atdd/tester/schemas/storage.tmpl.json +18 -0
- atdd/tester/schemas/telemetry.schema.json +128 -0
- atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
- atdd/tester/schemas/test_filename.schema.json +194 -0
- atdd/tester/schemas/test_intent.schema.json +179 -0
- atdd/tester/schemas/unit.tmpl.json +18 -0
- atdd/tester/schemas/visual.tmpl.json +18 -0
- atdd/tester/schemas/ws.tmpl.json +17 -0
- atdd/tester/utils/__init__.py +0 -0
- atdd/tester/utils/filename.py +300 -0
- atdd/tester/validators/__init__.py +0 -0
- atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
- atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
- atdd/tester/validators/conftest.py +5 -0
- atdd/tester/validators/coverage_gap_report.py +321 -0
- atdd/tester/validators/fix_dual_ac_references.py +179 -0
- atdd/tester/validators/remove_duplicate_lines.py +93 -0
- atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
- atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
- atdd/tester/validators/test_artifact_naming_category.py +307 -0
- atdd/tester/validators/test_contract_schema_compliance.py +706 -0
- atdd/tester/validators/test_contracts_structure.py +200 -0
- atdd/tester/validators/test_coverage_adequacy.py +797 -0
- atdd/tester/validators/test_dual_ac_reference.py +225 -0
- atdd/tester/validators/test_fixture_validity.py +372 -0
- atdd/tester/validators/test_isolation.py +487 -0
- atdd/tester/validators/test_migration_coverage.py +204 -0
- atdd/tester/validators/test_migration_criteria.py +276 -0
- atdd/tester/validators/test_migration_generation.py +116 -0
- atdd/tester/validators/test_python_test_naming.py +410 -0
- atdd/tester/validators/test_red_layer_validation.py +95 -0
- atdd/tester/validators/test_red_python_layer_structure.py +87 -0
- atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
- atdd/tester/validators/test_telemetry_structure.py +634 -0
- atdd/tester/validators/test_typescript_test_naming.py +301 -0
- atdd/tester/validators/test_typescript_test_structure.py +84 -0
- atdd-0.2.1.dist-info/METADATA +221 -0
- atdd-0.2.1.dist-info/RECORD +184 -0
- atdd-0.2.1.dist-info/WHEEL +5 -0
- atdd-0.2.1.dist-info/entry_points.txt +2 -0
- atdd-0.2.1.dist-info/licenses/LICENSE +674 -0
- atdd-0.2.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Platform tests: Contract directory structure validation.
|
|
3
|
+
|
|
4
|
+
Validates that contracts/ follows the domain/resource pattern.
|
|
5
|
+
Tests ensure contract directories align with URN conventions.
|
|
6
|
+
"""
|
|
7
|
+
import pytest
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Path constants
|
|
12
|
+
REPO_ROOT = Path(__file__).resolve().parents[4]
|
|
13
|
+
CONTRACTS_DIR = REPO_ROOT / "contracts"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.mark.platform
|
|
17
|
+
def test_contracts_directory_exists():
|
|
18
|
+
"""
|
|
19
|
+
SPEC-PLATFORM-CONTRACTS-0001: contracts/ directory exists
|
|
20
|
+
|
|
21
|
+
Given: Repository root
|
|
22
|
+
When: Checking for contracts/ directory
|
|
23
|
+
Then: contracts/ directory exists
|
|
24
|
+
"""
|
|
25
|
+
assert CONTRACTS_DIR.exists(), \
|
|
26
|
+
f"contracts/ directory does not exist at {CONTRACTS_DIR}"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.mark.platform
|
|
30
|
+
def test_contracts_follow_domain_resource_pattern():
|
|
31
|
+
"""
|
|
32
|
+
SPEC-PLATFORM-CONTRACTS-0002: contracts/ follows domain/resource pattern
|
|
33
|
+
|
|
34
|
+
Given: contracts/ directory structure
|
|
35
|
+
When: Checking directory hierarchy
|
|
36
|
+
Then: Structure follows contracts/{domain}/{resource}/ pattern
|
|
37
|
+
OR contracts/{domain}/ for domain-level contracts
|
|
38
|
+
Domain and resource names are lowercase with hyphens
|
|
39
|
+
"""
|
|
40
|
+
if not CONTRACTS_DIR.exists():
|
|
41
|
+
pytest.skip(f"contracts/ directory does not exist")
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
import re
|
|
45
|
+
name_pattern = re.compile(r"^[a-z][a-z0-9\-]*$")
|
|
46
|
+
|
|
47
|
+
for domain_dir in CONTRACTS_DIR.iterdir():
|
|
48
|
+
if not domain_dir.is_dir():
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
# Skip hidden directories and special directories
|
|
52
|
+
if domain_dir.name.startswith(".") or domain_dir.name == "__pycache__":
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
# Verify domain name follows pattern
|
|
56
|
+
assert name_pattern.match(domain_dir.name), \
|
|
57
|
+
f"Contract domain '{domain_dir.name}' doesn't match pattern (lowercase, hyphens only)"
|
|
58
|
+
|
|
59
|
+
# Check resource directories
|
|
60
|
+
for resource_dir in domain_dir.iterdir():
|
|
61
|
+
if not resource_dir.is_dir():
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
if resource_dir.name.startswith(".") or resource_dir.name == "__pycache__":
|
|
65
|
+
continue
|
|
66
|
+
|
|
67
|
+
# Verify resource name follows pattern
|
|
68
|
+
assert name_pattern.match(resource_dir.name), \
|
|
69
|
+
f"Contract resource '{resource_dir.name}' in domain '{domain_dir.name}' " \
|
|
70
|
+
f"doesn't match pattern (lowercase, hyphens only)"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@pytest.mark.platform
|
|
74
|
+
def test_contract_directories_contain_files():
|
|
75
|
+
"""
|
|
76
|
+
SPEC-PLATFORM-CONTRACTS-0003: Contract directories contain definition files
|
|
77
|
+
|
|
78
|
+
Given: contracts/{domain}/{resource}/ directories
|
|
79
|
+
When: Checking directory contents
|
|
80
|
+
Then: Each resource directory contains files (JSON, YAML, or other formats)
|
|
81
|
+
Directories are not empty
|
|
82
|
+
"""
|
|
83
|
+
if not CONTRACTS_DIR.exists():
|
|
84
|
+
pytest.skip(f"contracts/ directory does not exist")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
empty_dirs = []
|
|
88
|
+
|
|
89
|
+
for domain_dir in CONTRACTS_DIR.iterdir():
|
|
90
|
+
if not domain_dir.is_dir() or domain_dir.name.startswith("."):
|
|
91
|
+
continue
|
|
92
|
+
|
|
93
|
+
for resource_dir in domain_dir.iterdir():
|
|
94
|
+
if not resource_dir.is_dir() or resource_dir.name.startswith("."):
|
|
95
|
+
continue
|
|
96
|
+
|
|
97
|
+
# Check if directory has any files (recursively)
|
|
98
|
+
has_files = any(resource_dir.rglob("*"))
|
|
99
|
+
|
|
100
|
+
if not has_files:
|
|
101
|
+
empty_dirs.append(str(resource_dir.relative_to(REPO_ROOT)))
|
|
102
|
+
|
|
103
|
+
if empty_dirs:
|
|
104
|
+
pytest.fail(
|
|
105
|
+
f"Found {len(empty_dirs)} empty contract directories:\n" +
|
|
106
|
+
"\n".join(f" {d}" for d in empty_dirs[:10]) +
|
|
107
|
+
(f"\n ... and {len(empty_dirs) - 10} more" if len(empty_dirs) > 10 else "")
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@pytest.mark.platform
|
|
112
|
+
def test_no_orphaned_contract_directories(contract_urns):
|
|
113
|
+
"""
|
|
114
|
+
SPEC-PLATFORM-CONTRACTS-0004: No orphaned contract directories
|
|
115
|
+
|
|
116
|
+
Given: Contract directories in contracts/
|
|
117
|
+
When: Comparing to contract URNs from wagons
|
|
118
|
+
Then: Each contracts/{domain}/{resource}/ has a corresponding URN
|
|
119
|
+
OR is a domain-level contract directory
|
|
120
|
+
No orphaned directories that aren't referenced
|
|
121
|
+
"""
|
|
122
|
+
if not CONTRACTS_DIR.exists():
|
|
123
|
+
pytest.skip(f"contracts/ directory does not exist")
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
# Build set of expected paths from URNs
|
|
127
|
+
expected_paths = set()
|
|
128
|
+
expected_domains = set()
|
|
129
|
+
|
|
130
|
+
for urn in contract_urns:
|
|
131
|
+
parts = urn.split(":")
|
|
132
|
+
if len(parts) == 3:
|
|
133
|
+
_, domain, resource = parts
|
|
134
|
+
expected_paths.add(f"{domain}/{resource}")
|
|
135
|
+
expected_domains.add(domain)
|
|
136
|
+
|
|
137
|
+
# Check actual directory structure
|
|
138
|
+
orphaned = []
|
|
139
|
+
|
|
140
|
+
for domain_dir in CONTRACTS_DIR.iterdir():
|
|
141
|
+
if not domain_dir.is_dir() or domain_dir.name.startswith("."):
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
domain_name = domain_dir.name
|
|
145
|
+
|
|
146
|
+
# Check resource directories
|
|
147
|
+
for resource_dir in domain_dir.iterdir():
|
|
148
|
+
if not resource_dir.is_dir() or resource_dir.name.startswith("."):
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
resource_name = resource_dir.name
|
|
152
|
+
path = f"{domain_name}/{resource_name}"
|
|
153
|
+
|
|
154
|
+
# Check if this path is referenced by a URN
|
|
155
|
+
if path not in expected_paths:
|
|
156
|
+
orphaned.append(path)
|
|
157
|
+
|
|
158
|
+
if orphaned:
|
|
159
|
+
pytest.skip(
|
|
160
|
+
f"Found {len(orphaned)} contract directories without corresponding URNs:\n" +
|
|
161
|
+
"\n".join(f" contracts/{d}" for d in orphaned[:10]) +
|
|
162
|
+
(f"\n ... and {len(orphaned) - 10} more" if len(orphaned) > 10 else "") +
|
|
163
|
+
"\n (This may be expected for legacy or future contracts)"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@pytest.mark.platform
|
|
168
|
+
def test_contract_files_are_valid_formats():
|
|
169
|
+
"""
|
|
170
|
+
SPEC-PLATFORM-CONTRACTS-0005: Contract files use valid formats
|
|
171
|
+
|
|
172
|
+
Given: Files in contracts/{domain}/{resource}/ directories
|
|
173
|
+
When: Checking file extensions
|
|
174
|
+
Then: Files use standard formats: .json, .yaml, .yml, .md, .ts, .dart
|
|
175
|
+
No unexpected file types
|
|
176
|
+
"""
|
|
177
|
+
if not CONTRACTS_DIR.exists():
|
|
178
|
+
pytest.skip(f"contracts/ directory does not exist")
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
allowed_extensions = {".json", ".yaml", ".yml", ".md", ".ts", ".dart", ".txt"}
|
|
182
|
+
invalid_files = []
|
|
183
|
+
|
|
184
|
+
for domain_dir in CONTRACTS_DIR.iterdir():
|
|
185
|
+
if not domain_dir.is_dir() or domain_dir.name.startswith("."):
|
|
186
|
+
continue
|
|
187
|
+
|
|
188
|
+
for file_path in domain_dir.rglob("*"):
|
|
189
|
+
if file_path.is_file() and not file_path.name.startswith("."):
|
|
190
|
+
# Check standard extensions
|
|
191
|
+
if file_path.suffix not in allowed_extensions:
|
|
192
|
+
invalid_files.append(str(file_path.relative_to(REPO_ROOT)))
|
|
193
|
+
|
|
194
|
+
if invalid_files:
|
|
195
|
+
pytest.skip(
|
|
196
|
+
f"Found {len(invalid_files)} contract files with unexpected extensions:\n" +
|
|
197
|
+
"\n".join(f" {f}" for f in invalid_files[:10]) +
|
|
198
|
+
(f"\n ... and {len(invalid_files) - 10} more" if len(invalid_files) > 10 else "") +
|
|
199
|
+
f"\n Allowed: {', '.join(sorted(allowed_extensions))}"
|
|
200
|
+
)
|