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.
Files changed (184) hide show
  1. atdd/__init__.py +6 -0
  2. atdd/__main__.py +4 -0
  3. atdd/cli.py +404 -0
  4. atdd/coach/__init__.py +0 -0
  5. atdd/coach/commands/__init__.py +0 -0
  6. atdd/coach/commands/add_persistence_metadata.py +215 -0
  7. atdd/coach/commands/analyze_migrations.py +188 -0
  8. atdd/coach/commands/consumers.py +720 -0
  9. atdd/coach/commands/infer_governance_status.py +149 -0
  10. atdd/coach/commands/initializer.py +177 -0
  11. atdd/coach/commands/interface.py +1078 -0
  12. atdd/coach/commands/inventory.py +565 -0
  13. atdd/coach/commands/migration.py +240 -0
  14. atdd/coach/commands/registry.py +1560 -0
  15. atdd/coach/commands/session.py +430 -0
  16. atdd/coach/commands/sync.py +405 -0
  17. atdd/coach/commands/test_interface.py +399 -0
  18. atdd/coach/commands/test_runner.py +141 -0
  19. atdd/coach/commands/tests/__init__.py +1 -0
  20. atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
  21. atdd/coach/commands/traceability.py +4264 -0
  22. atdd/coach/conventions/session.convention.yaml +754 -0
  23. atdd/coach/overlays/__init__.py +2 -0
  24. atdd/coach/overlays/claude.md +2 -0
  25. atdd/coach/schemas/config.schema.json +34 -0
  26. atdd/coach/schemas/manifest.schema.json +101 -0
  27. atdd/coach/templates/ATDD.md +282 -0
  28. atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
  29. atdd/coach/utils/__init__.py +0 -0
  30. atdd/coach/utils/graph/__init__.py +0 -0
  31. atdd/coach/utils/graph/urn.py +875 -0
  32. atdd/coach/validators/__init__.py +0 -0
  33. atdd/coach/validators/shared_fixtures.py +365 -0
  34. atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
  35. atdd/coach/validators/test_registry.py +575 -0
  36. atdd/coach/validators/test_session_validation.py +1183 -0
  37. atdd/coach/validators/test_traceability.py +448 -0
  38. atdd/coach/validators/test_update_feature_paths.py +108 -0
  39. atdd/coach/validators/test_validate_contract_consumers.py +297 -0
  40. atdd/coder/__init__.py +1 -0
  41. atdd/coder/conventions/adapter.recipe.yaml +88 -0
  42. atdd/coder/conventions/backend.convention.yaml +460 -0
  43. atdd/coder/conventions/boundaries.convention.yaml +666 -0
  44. atdd/coder/conventions/commons.convention.yaml +460 -0
  45. atdd/coder/conventions/complexity.recipe.yaml +109 -0
  46. atdd/coder/conventions/component-naming.convention.yaml +178 -0
  47. atdd/coder/conventions/design.convention.yaml +327 -0
  48. atdd/coder/conventions/design.recipe.yaml +273 -0
  49. atdd/coder/conventions/dto.convention.yaml +660 -0
  50. atdd/coder/conventions/frontend.convention.yaml +542 -0
  51. atdd/coder/conventions/green.convention.yaml +1012 -0
  52. atdd/coder/conventions/presentation.convention.yaml +587 -0
  53. atdd/coder/conventions/refactor.convention.yaml +535 -0
  54. atdd/coder/conventions/technology.convention.yaml +206 -0
  55. atdd/coder/conventions/tests/__init__.py +0 -0
  56. atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
  57. atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
  58. atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
  59. atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
  60. atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
  61. atdd/coder/conventions/thinness.recipe.yaml +82 -0
  62. atdd/coder/conventions/train.convention.yaml +325 -0
  63. atdd/coder/conventions/verification.protocol.yaml +53 -0
  64. atdd/coder/schemas/design_system.schema.json +361 -0
  65. atdd/coder/validators/__init__.py +0 -0
  66. atdd/coder/validators/test_commons_structure.py +485 -0
  67. atdd/coder/validators/test_complexity.py +416 -0
  68. atdd/coder/validators/test_cross_language_consistency.py +431 -0
  69. atdd/coder/validators/test_design_system_compliance.py +413 -0
  70. atdd/coder/validators/test_dto_testing_patterns.py +268 -0
  71. atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
  72. atdd/coder/validators/test_green_layer_dependencies.py +148 -0
  73. atdd/coder/validators/test_green_python_layer_structure.py +103 -0
  74. atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
  75. atdd/coder/validators/test_import_boundaries.py +396 -0
  76. atdd/coder/validators/test_init_file_urns.py +593 -0
  77. atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
  78. atdd/coder/validators/test_presentation_convention.py +260 -0
  79. atdd/coder/validators/test_python_architecture.py +674 -0
  80. atdd/coder/validators/test_quality_metrics.py +420 -0
  81. atdd/coder/validators/test_station_master_pattern.py +244 -0
  82. atdd/coder/validators/test_train_infrastructure.py +454 -0
  83. atdd/coder/validators/test_train_urns.py +293 -0
  84. atdd/coder/validators/test_typescript_architecture.py +616 -0
  85. atdd/coder/validators/test_usecase_structure.py +421 -0
  86. atdd/coder/validators/test_wagon_boundaries.py +586 -0
  87. atdd/conftest.py +126 -0
  88. atdd/planner/__init__.py +1 -0
  89. atdd/planner/conventions/acceptance.convention.yaml +538 -0
  90. atdd/planner/conventions/appendix.convention.yaml +187 -0
  91. atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
  92. atdd/planner/conventions/component.convention.yaml +670 -0
  93. atdd/planner/conventions/criteria.convention.yaml +141 -0
  94. atdd/planner/conventions/feature.convention.yaml +371 -0
  95. atdd/planner/conventions/interface.convention.yaml +382 -0
  96. atdd/planner/conventions/steps.convention.yaml +141 -0
  97. atdd/planner/conventions/train.convention.yaml +552 -0
  98. atdd/planner/conventions/wagon.convention.yaml +275 -0
  99. atdd/planner/conventions/wmbt.convention.yaml +258 -0
  100. atdd/planner/schemas/acceptance.schema.json +336 -0
  101. atdd/planner/schemas/appendix.schema.json +78 -0
  102. atdd/planner/schemas/component.schema.json +114 -0
  103. atdd/planner/schemas/feature.schema.json +197 -0
  104. atdd/planner/schemas/train.schema.json +192 -0
  105. atdd/planner/schemas/wagon.schema.json +281 -0
  106. atdd/planner/schemas/wmbt.schema.json +59 -0
  107. atdd/planner/validators/__init__.py +0 -0
  108. atdd/planner/validators/conftest.py +5 -0
  109. atdd/planner/validators/test_draft_wagon_registry.py +374 -0
  110. atdd/planner/validators/test_plan_cross_refs.py +240 -0
  111. atdd/planner/validators/test_plan_uniqueness.py +224 -0
  112. atdd/planner/validators/test_plan_urn_resolution.py +268 -0
  113. atdd/planner/validators/test_plan_wagons.py +174 -0
  114. atdd/planner/validators/test_train_validation.py +514 -0
  115. atdd/planner/validators/test_wagon_urn_chain.py +648 -0
  116. atdd/planner/validators/test_wmbt_consistency.py +327 -0
  117. atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
  118. atdd/tester/__init__.py +1 -0
  119. atdd/tester/conventions/artifact.convention.yaml +257 -0
  120. atdd/tester/conventions/contract.convention.yaml +1009 -0
  121. atdd/tester/conventions/filename.convention.yaml +555 -0
  122. atdd/tester/conventions/migration.convention.yaml +509 -0
  123. atdd/tester/conventions/red.convention.yaml +797 -0
  124. atdd/tester/conventions/routing.convention.yaml +51 -0
  125. atdd/tester/conventions/telemetry.convention.yaml +458 -0
  126. atdd/tester/schemas/a11y.tmpl.json +17 -0
  127. atdd/tester/schemas/artifact.schema.json +189 -0
  128. atdd/tester/schemas/contract.schema.json +591 -0
  129. atdd/tester/schemas/contract.tmpl.json +95 -0
  130. atdd/tester/schemas/db.tmpl.json +20 -0
  131. atdd/tester/schemas/e2e.tmpl.json +17 -0
  132. atdd/tester/schemas/edge_function.tmpl.json +17 -0
  133. atdd/tester/schemas/event.tmpl.json +17 -0
  134. atdd/tester/schemas/http.tmpl.json +19 -0
  135. atdd/tester/schemas/job.tmpl.json +18 -0
  136. atdd/tester/schemas/load.tmpl.json +21 -0
  137. atdd/tester/schemas/metric.tmpl.json +19 -0
  138. atdd/tester/schemas/pack.schema.json +139 -0
  139. atdd/tester/schemas/realtime.tmpl.json +20 -0
  140. atdd/tester/schemas/rls.tmpl.json +18 -0
  141. atdd/tester/schemas/script.tmpl.json +16 -0
  142. atdd/tester/schemas/sec.tmpl.json +18 -0
  143. atdd/tester/schemas/storage.tmpl.json +18 -0
  144. atdd/tester/schemas/telemetry.schema.json +128 -0
  145. atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
  146. atdd/tester/schemas/test_filename.schema.json +194 -0
  147. atdd/tester/schemas/test_intent.schema.json +179 -0
  148. atdd/tester/schemas/unit.tmpl.json +18 -0
  149. atdd/tester/schemas/visual.tmpl.json +18 -0
  150. atdd/tester/schemas/ws.tmpl.json +17 -0
  151. atdd/tester/utils/__init__.py +0 -0
  152. atdd/tester/utils/filename.py +300 -0
  153. atdd/tester/validators/__init__.py +0 -0
  154. atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
  155. atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
  156. atdd/tester/validators/conftest.py +5 -0
  157. atdd/tester/validators/coverage_gap_report.py +321 -0
  158. atdd/tester/validators/fix_dual_ac_references.py +179 -0
  159. atdd/tester/validators/remove_duplicate_lines.py +93 -0
  160. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
  161. atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
  162. atdd/tester/validators/test_artifact_naming_category.py +307 -0
  163. atdd/tester/validators/test_contract_schema_compliance.py +706 -0
  164. atdd/tester/validators/test_contracts_structure.py +200 -0
  165. atdd/tester/validators/test_coverage_adequacy.py +797 -0
  166. atdd/tester/validators/test_dual_ac_reference.py +225 -0
  167. atdd/tester/validators/test_fixture_validity.py +372 -0
  168. atdd/tester/validators/test_isolation.py +487 -0
  169. atdd/tester/validators/test_migration_coverage.py +204 -0
  170. atdd/tester/validators/test_migration_criteria.py +276 -0
  171. atdd/tester/validators/test_migration_generation.py +116 -0
  172. atdd/tester/validators/test_python_test_naming.py +410 -0
  173. atdd/tester/validators/test_red_layer_validation.py +95 -0
  174. atdd/tester/validators/test_red_python_layer_structure.py +87 -0
  175. atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
  176. atdd/tester/validators/test_telemetry_structure.py +634 -0
  177. atdd/tester/validators/test_typescript_test_naming.py +301 -0
  178. atdd/tester/validators/test_typescript_test_structure.py +84 -0
  179. atdd-0.2.1.dist-info/METADATA +221 -0
  180. atdd-0.2.1.dist-info/RECORD +184 -0
  181. atdd-0.2.1.dist-info/WHEEL +5 -0
  182. atdd-0.2.1.dist-info/entry_points.txt +2 -0
  183. atdd-0.2.1.dist-info/licenses/LICENSE +674 -0
  184. atdd-0.2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,301 @@
1
+ """
2
+ Platform tests: TypeScript test file naming validation.
3
+
4
+ Validates that all TypeScript test files conform to Node.js/TypeScript naming conventions.
5
+ Tests parametrized to run once per test file for surgical diagnostics.
6
+
7
+ Migration Note:
8
+ Legacy format: ac-{type}-{nnn}.{purpose-slug}.test.ts (uses acceptance ID)
9
+ New format: {wmbt_lower}-{harness_lower}-{nnn}[-{slug-kebab}].test.ts (uses URN)
10
+
11
+ New URN-based naming documented in:
12
+ - .claude/conventions/tester/filename.convention.yaml
13
+ - atdd.tester.utils.filename module
14
+ - SPEC-TESTER-CONV-0070
15
+
16
+ See test_acceptance_urn_filename_mapping.py for validation of new format.
17
+ """
18
+ import pytest
19
+ import re
20
+ from pathlib import Path
21
+
22
+
23
+ @pytest.mark.platform
24
+ def test_typescript_test_files_use_kebab_case(typescript_test_files):
25
+ """
26
+ SPEC-PLATFORM-TS-0001: TypeScript test files use kebab-case naming
27
+
28
+ Given: TypeScript test files in supabase/ and e2e/ directories
29
+ When: Checking file naming conventions
30
+ Then: All test files use kebab-case (lowercase with hyphens)
31
+ No underscores allowed in filenames (except in .test.ts suffix)
32
+ Pattern: {normalized_id}.{purpose_slug}.test.ts
33
+
34
+ Convention: atdd/tester/conventions/red.convention.yaml:254-285
35
+ """
36
+ errors = []
37
+
38
+ for test_file in typescript_test_files:
39
+ filename = test_file.name
40
+
41
+ # Remove .test.ts suffix
42
+ base_name = filename.replace('.test.ts', '')
43
+
44
+ # Check for invalid characters (underscores)
45
+ if '_' in base_name:
46
+ errors.append(
47
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
48
+ f" Contains underscores. Expected kebab-case format.\n"
49
+ f" Example: ac-http-006.primitive-endpoint.test.ts"
50
+ )
51
+
52
+ # Check for uppercase letters
53
+ if base_name != base_name.lower():
54
+ errors.append(
55
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
56
+ f" Contains uppercase letters. Expected all lowercase.\n"
57
+ f" Example: ac-db-015.user-records-persist.test.ts"
58
+ )
59
+
60
+ if errors:
61
+ pytest.fail(
62
+ "\n\n🔴 TypeScript test files violate Node.js naming conventions:\n\n" +
63
+ "\n".join(errors) +
64
+ "\n\n📘 See: atdd/tester/conventions/red.convention.yaml:254-285"
65
+ )
66
+
67
+
68
+ @pytest.mark.platform
69
+ def test_typescript_test_files_match_acceptance_pattern(typescript_test_files):
70
+ """
71
+ SPEC-PLATFORM-TS-0002: TypeScript test files follow acceptance-derived naming
72
+
73
+ Given: TypeScript test files in supabase/ and e2e/ directories
74
+ When: Checking naming pattern
75
+ Then: Files match pattern: {normalized_id}.{purpose_slug}.test.ts
76
+ normalized_id: AC-HTTP-006 → ac-http-006 (kebab-case)
77
+ purpose_slug: extracted from identity.purpose field (kebab-case)
78
+
79
+ Convention: atdd/tester/conventions/red.convention.yaml:254-285
80
+ """
81
+ # Pattern: {normalized_id}.{purpose_slug}.test.ts
82
+ # normalized_id: ac-http-006, ac-db-015, etc.
83
+ # purpose_slug: primitive-endpoint, user-records-persist, etc.
84
+
85
+ valid_pattern = re.compile(r'^ac-[a-z]+-\d{3}\.[a-z][a-z0-9-]*\.test\.ts$')
86
+ errors = []
87
+
88
+ for test_file in typescript_test_files:
89
+ filename = test_file.name
90
+
91
+ if not valid_pattern.match(filename):
92
+ errors.append(
93
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
94
+ f" Pattern mismatch. Expected: ac-{{type}}-{{nnn}}.{{purpose}}.test.ts\n"
95
+ f" Example: ac-http-006.primitive-endpoint.test.ts"
96
+ )
97
+
98
+ if errors:
99
+ pytest.fail(
100
+ "\n\n🔴 TypeScript test files don't match expected pattern:\n\n" +
101
+ "\n".join(errors) +
102
+ "\n\n📘 Pattern: ac-{type}-{nnn}.{purpose}.test.ts\n" +
103
+ "📘 See: atdd/tester/conventions/red.convention.yaml:254-285"
104
+ )
105
+
106
+
107
+ @pytest.mark.platform
108
+ def test_typescript_test_files_have_urn_comment(typescript_test_files):
109
+ """
110
+ SPEC-PLATFORM-TS-0003: TypeScript test files contain URN comment
111
+
112
+ Given: TypeScript test files in supabase/ and e2e/ directories
113
+ When: Reading file contents
114
+ Then: First line contains URN comment in format:
115
+ // urn: acc:{wagon}.{wmbt}.{acceptance_id}
116
+
117
+ Example: // urn: acc:maintain-ux.P002.AC-HTTP-006
118
+ """
119
+ errors = []
120
+
121
+ for test_file in typescript_test_files:
122
+ with open(test_file, 'r') as f:
123
+ first_line = f.readline().strip()
124
+
125
+ # Check for URN comment pattern
126
+ urn_pattern = re.compile(r'^// urn: acc:[a-z][a-z0-9-]+\.[A-Z]\d{3}\.AC-[A-Z]+-\d{3}$')
127
+
128
+ if not urn_pattern.match(first_line):
129
+ errors.append(
130
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
131
+ f" Missing or invalid URN comment in first line.\n"
132
+ f" Found: {first_line[:80]}\n"
133
+ f" Expected: // urn: acc:{{wagon}}.{{wmbt}}.{{acceptance_id}}"
134
+ )
135
+
136
+ if errors:
137
+ pytest.fail(
138
+ "\n\n🔴 TypeScript test files missing URN comments:\n\n" +
139
+ "\n".join(errors) +
140
+ "\n\n📘 First line must be: // urn: acc:{wagon}.{wmbt}.{acceptance_id}"
141
+ )
142
+
143
+
144
+ @pytest.mark.platform
145
+ def test_typescript_test_files_organized_by_wagon(typescript_test_files):
146
+ """
147
+ SPEC-PLATFORM-TS-0004: TypeScript test files organized by wagon
148
+
149
+ Given: TypeScript test files in supabase/ and e2e/ directories
150
+ When: Checking directory structure
151
+ Then: Backend tests: supabase/functions/{wagon}/test/{test_file}.test.ts
152
+ E2E tests: e2e/{wagon}/{test_file}.test.ts
153
+
154
+ Example: supabase/functions/maintain-ux/test/ac-http-006.primitive-endpoint.test.ts
155
+ """
156
+ errors = []
157
+
158
+ for test_file in typescript_test_files:
159
+ parts = test_file.parts
160
+
161
+ # Check if it's a supabase backend test
162
+ if 'supabase' in parts and 'functions' in parts:
163
+ try:
164
+ supabase_idx = parts.index('supabase')
165
+ functions_idx = parts.index('functions')
166
+
167
+ # Expected: supabase/functions/{wagon}/test/{file}.test.ts
168
+ if functions_idx != supabase_idx + 1:
169
+ errors.append(
170
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
171
+ f" Invalid structure. Expected: supabase/functions/{{wagon}}/test/{{file}}.test.ts"
172
+ )
173
+ continue
174
+
175
+ remaining = parts[functions_idx + 1:]
176
+ # Should have: wagon/test/file.test.ts
177
+ if len(remaining) < 3 or remaining[1] != 'test':
178
+ errors.append(
179
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
180
+ f" Not in test/ subdirectory.\n"
181
+ f" Expected: supabase/functions/{{wagon}}/test/{{file}}.test.ts"
182
+ )
183
+ except (ValueError, IndexError):
184
+ errors.append(
185
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
186
+ f" Invalid supabase structure"
187
+ )
188
+
189
+ # Check if it's an e2e test
190
+ elif 'e2e' in parts:
191
+ try:
192
+ e2e_idx = parts.index('e2e')
193
+ remaining = parts[e2e_idx + 1:]
194
+
195
+ # Should have at least: wagon/file.test.ts
196
+ if len(remaining) < 2:
197
+ errors.append(
198
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
199
+ f" Not organized by wagon.\n"
200
+ f" Expected: e2e/{{wagon}}/{{file}}.test.ts"
201
+ )
202
+ except (ValueError, IndexError):
203
+ errors.append(
204
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
205
+ f" Invalid e2e structure"
206
+ )
207
+
208
+ if errors:
209
+ pytest.fail(
210
+ "\n\n🔴 TypeScript test files not properly organized:\n\n" +
211
+ "\n".join(errors) +
212
+ "\n\n📘 Backend: supabase/functions/{wagon}/test/{file}.test.ts\n" +
213
+ "📘 E2E: e2e/{wagon}/{file}.test.ts"
214
+ )
215
+
216
+
217
+ @pytest.mark.platform
218
+ def test_typescript_test_filename_matches_urn_acceptance_id(typescript_test_files):
219
+ """
220
+ SPEC-PLATFORM-TS-0005: Test filename normalized_id matches URN acceptance_id
221
+
222
+ Given: TypeScript test files with URN comments
223
+ When: Comparing filename normalized_id to URN acceptance_id
224
+ Then: normalized_id matches acceptance_id (converted to kebab-case)
225
+ Example: ac-http-006 matches AC-HTTP-006
226
+
227
+ Convention: atdd/tester/conventions/red.convention.yaml:255-260
228
+ """
229
+ errors = []
230
+
231
+ for test_file in typescript_test_files:
232
+ # Read URN from first line
233
+ with open(test_file, 'r') as f:
234
+ first_line = f.readline().strip()
235
+
236
+ # Extract acceptance_id from URN (e.g., AC-HTTP-006)
237
+ urn_match = re.search(r'// urn: acc:[a-z][a-z0-9-]+\.[A-Z]\d{3}\.(AC-[A-Z]+-\d{3})', first_line)
238
+
239
+ if not urn_match:
240
+ continue # Skip if URN not found (covered by other test)
241
+
242
+ acceptance_id = urn_match.group(1) # e.g., AC-HTTP-006
243
+
244
+ # Normalize acceptance_id to kebab-case
245
+ expected_normalized_id = acceptance_id.lower() # ac-http-006
246
+
247
+ # Extract normalized_id from filename (first part before purpose_slug)
248
+ filename = test_file.name
249
+ # Pattern: {normalized_id}.{purpose_slug}.test.ts
250
+ parts = filename.replace('.test.ts', '').split('.')
251
+
252
+ if len(parts) >= 1:
253
+ actual_normalized_id = parts[0] # ac-http-006
254
+
255
+ if actual_normalized_id != expected_normalized_id:
256
+ errors.append(
257
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
258
+ f" Filename normalized_id doesn't match URN acceptance_id.\n"
259
+ f" URN acceptance_id: {acceptance_id}\n"
260
+ f" Expected normalized: {expected_normalized_id}\n"
261
+ f" Actual in filename: {actual_normalized_id}"
262
+ )
263
+
264
+ if errors:
265
+ pytest.fail(
266
+ "\n\n🔴 TypeScript test filenames don't match URN acceptance IDs:\n\n" +
267
+ "\n".join(errors) +
268
+ "\n\n📘 Transformation: AC-HTTP-006 → ac-http-006\n" +
269
+ "📘 See: atdd/tester/conventions/red.convention.yaml:255-260"
270
+ )
271
+
272
+
273
+ @pytest.mark.platform
274
+ def test_typescript_test_files_use_correct_extension(typescript_test_files):
275
+ """
276
+ SPEC-PLATFORM-TS-0006: TypeScript test files use .test.ts extension
277
+
278
+ Given: TypeScript test files in supabase/ and e2e/ directories
279
+ When: Checking file extensions
280
+ Then: Files use .test.ts
281
+ No other extensions allowed
282
+
283
+ Convention: Standard Node.js/TypeScript testing convention
284
+ """
285
+ errors = []
286
+
287
+ for test_file in typescript_test_files:
288
+ filename = test_file.name
289
+
290
+ if not filename.endswith('.test.ts'):
291
+ errors.append(
292
+ f"❌ {test_file.relative_to(Path.cwd())}\n"
293
+ f" Invalid extension. Expected: .test.ts"
294
+ )
295
+
296
+ if errors:
297
+ pytest.fail(
298
+ "\n\n🔴 TypeScript test files have invalid extensions:\n\n" +
299
+ "\n".join(errors) +
300
+ "\n\n📘 Use .test.ts"
301
+ )
@@ -0,0 +1,84 @@
1
+ """
2
+ Platform tests: TypeScript test structure validation.
3
+
4
+ Focuses on URN headers and TSX usage for component tests under web/tests/.
5
+ """
6
+ import pytest
7
+ import re
8
+
9
+
10
+ URN_HEADER_PATTERN = re.compile(
11
+ r'^//\s*(?:URN|urn):\s*(acc:[a-z][a-z0-9-]*:[A-Z][0-9]{3}-[A-Z0-9]+-[0-9]{3}(?:-[a-z0-9-]+)?)$'
12
+ )
13
+
14
+
15
+ @pytest.mark.platform
16
+ def test_typescript_test_files_have_urn_header(web_typescript_test_files):
17
+ """
18
+ SPEC-TESTER-TS-001: All TypeScript test files must have URN header.
19
+ """
20
+ errors = []
21
+
22
+ for test_file in web_typescript_test_files:
23
+ lines = test_file.read_text().splitlines()
24
+ first_non_empty = next((line.strip() for line in lines if line.strip()), "")
25
+
26
+ if not URN_HEADER_PATTERN.match(first_non_empty):
27
+ errors.append(
28
+ f"❌ {test_file}\n"
29
+ f" Missing URN header in first non-empty line.\n"
30
+ f" Expected: // URN: acc:{{wagon}}:{{WMBT}}-{{HARNESS}}-{{NNN}}[-slug]"
31
+ )
32
+
33
+ if errors:
34
+ pytest.fail(
35
+ "\n\n🔴 TypeScript test files missing URN headers:\n\n" +
36
+ "\n".join(errors)
37
+ )
38
+
39
+
40
+ @pytest.mark.platform
41
+ def test_component_tests_use_tsx_extension(web_typescript_test_files):
42
+ """
43
+ SPEC-TESTER-TS-002: Component tests using JSX must use .test.tsx.
44
+ """
45
+ errors = []
46
+
47
+ for test_file in web_typescript_test_files:
48
+ content = test_file.read_text()
49
+ has_render = "from '@testing-library/preact'" in content
50
+ has_jsx = bool(re.search(r'<\\w+.*?>', content))
51
+
52
+ if (has_render or has_jsx) and not test_file.name.endswith(".test.tsx"):
53
+ errors.append(
54
+ f"❌ {test_file}\n"
55
+ f" Component test uses JSX but is not .test.tsx"
56
+ )
57
+
58
+ if errors:
59
+ pytest.fail(
60
+ "\n\n🔴 Component tests must use .test.tsx:\n\n" +
61
+ "\n".join(errors)
62
+ )
63
+
64
+
65
+ @pytest.mark.platform
66
+ def test_preact_test_files_use_urn_filename_format(web_typescript_test_files):
67
+ """
68
+ SPEC-TESTER-TS-003: Preact TypeScript tests use URN-based filename format.
69
+ """
70
+ pattern = re.compile(r'^([A-Z][0-9]{3})_([A-Z0-9]+)_([0-9]{3})(?:_([a-z0-9_]+))?\.test\.ts(x)?$')
71
+ errors = []
72
+
73
+ for test_file in web_typescript_test_files:
74
+ if not pattern.match(test_file.name):
75
+ errors.append(
76
+ f"❌ {test_file}\n"
77
+ f" Expected: C004_UNIT_001_slug.test.ts[x]"
78
+ )
79
+
80
+ if errors:
81
+ pytest.fail(
82
+ "\n\n🔴 Preact TypeScript tests use invalid filenames:\n\n" +
83
+ "\n".join(errors)
84
+ )
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: atdd
3
+ Version: 0.2.1
4
+ Summary: ATDD Platform - Acceptance Test Driven Development toolkit
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: pyyaml
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest; extra == "dev"
12
+ Requires-Dist: pytest-xdist; extra == "dev"
13
+ Dynamic: license-file
14
+
15
+ # ATDD
16
+
17
+ Acceptance Test Driven Development toolkit for structured planning and convention enforcement.
18
+
19
+ ## Installation
20
+
21
+ ### From PyPI
22
+
23
+ ```bash
24
+ pip install atdd
25
+ ```
26
+
27
+ ### For Development
28
+
29
+ ```bash
30
+ # Clone the repo
31
+ git clone https://github.com/afokapu/atdd.git
32
+ cd atdd
33
+
34
+ # Install in editable mode with dev dependencies
35
+ pip install -e ".[dev]"
36
+
37
+ # Verify installation
38
+ atdd --help
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ # Initialize ATDD in your project
45
+ atdd init
46
+
47
+ # Create a planning session
48
+ atdd session new my-feature
49
+
50
+ # List sessions
51
+ atdd session list
52
+
53
+ # Sync ATDD rules to agent config files
54
+ atdd sync
55
+
56
+ # Run validators
57
+ atdd --test all
58
+ ```
59
+
60
+ ## What It Does
61
+
62
+ ATDD provides:
63
+
64
+ 1. **Session Management** - Structured planning documents with templates and tracking
65
+ 2. **Convention Enforcement** - YAML-based conventions validated via pytest
66
+ 3. **ATDD Lifecycle** - Planner → Tester → Coder phase gates
67
+ 4. **Agent Config Sync** - Keep ATDD rules in sync across AI agent config files
68
+
69
+ ## Commands
70
+
71
+ ### Project Initialization
72
+
73
+ ```bash
74
+ atdd init # Create atdd-sessions/, .atdd/, and CLAUDE.md
75
+ atdd init --force # Reinitialize (overwrites existing)
76
+ ```
77
+
78
+ Creates:
79
+ ```
80
+ your-project/
81
+ ├── CLAUDE.md # With managed ATDD block
82
+ ├── atdd-sessions/
83
+ │ ├── SESSION-TEMPLATE.md
84
+ │ └── archive/
85
+ └── .atdd/
86
+ ├── manifest.yaml # Session tracking
87
+ └── config.yaml # Agent sync configuration
88
+ ```
89
+
90
+ ### Session Management
91
+
92
+ ```bash
93
+ atdd session new <slug> # Create new session
94
+ atdd session new <slug> --type <type> # Specify type
95
+ atdd session list # List all sessions
96
+ atdd session archive <id> # Archive session
97
+ atdd session sync # Sync manifest with files
98
+ ```
99
+
100
+ Session types: `implementation`, `migration`, `refactor`, `analysis`, `planning`, `cleanup`, `tracking`
101
+
102
+ ### Agent Config Sync
103
+
104
+ Sync ATDD rules to agent config files using managed blocks that preserve user content:
105
+
106
+ ```bash
107
+ atdd sync # Sync all enabled agents from config
108
+ atdd sync --agent claude # Sync specific agent only
109
+ atdd sync --verify # Check if files are in sync (for CI)
110
+ atdd sync --status # Show sync status for all agents
111
+ ```
112
+
113
+ Supported agents:
114
+ | Agent | File |
115
+ |-------|------|
116
+ | claude | CLAUDE.md |
117
+ | codex | AGENTS.md |
118
+ | gemini | GEMINI.md |
119
+ | qwen | QWEN.md |
120
+
121
+ Configure which agents to sync in `.atdd/config.yaml`:
122
+ ```yaml
123
+ version: "1.0"
124
+ sync:
125
+ agents:
126
+ - claude # Enabled by default
127
+ # - codex # Uncomment to sync AGENTS.md
128
+ # - gemini # Uncomment to sync GEMINI.md
129
+ # - qwen # Uncomment to sync QWEN.md
130
+ ```
131
+
132
+ ### Validation
133
+
134
+ ```bash
135
+ atdd --test all # Run all validators
136
+ atdd --test planner # Planning artifacts only
137
+ atdd --test tester # Testing artifacts only
138
+ atdd --test coder # Implementation only
139
+ atdd --quick # Fast smoke test
140
+ ```
141
+
142
+ ### Other Commands
143
+
144
+ ```bash
145
+ atdd --status # Platform status
146
+ atdd --inventory # Generate artifact inventory
147
+ atdd --help # Full help
148
+ ```
149
+
150
+ ## Project Structure
151
+
152
+ ```
153
+ src/atdd/
154
+ ├── cli.py # Entry point
155
+ ├── coach/
156
+ │ ├── commands/ # CLI command implementations
157
+ │ ├── conventions/ # Coach conventions (YAML)
158
+ │ ├── overlays/ # Agent-specific additions
159
+ │ ├── schemas/ # JSON schemas
160
+ │ ├── templates/ # Session templates, ATDD.md
161
+ │ └── validators/ # Coach validators
162
+ ├── planner/
163
+ │ ├── conventions/ # Planning conventions
164
+ │ ├── schemas/ # Planning schemas
165
+ │ └── validators/ # Planning validators
166
+ ├── tester/
167
+ │ ├── conventions/ # Testing conventions
168
+ │ ├── schemas/ # Testing schemas
169
+ │ └── validators/ # Testing validators
170
+ └── coder/
171
+ ├── conventions/ # Coding conventions
172
+ ├── schemas/ # Coder schemas
173
+ └── validators/ # Implementation validators
174
+ ```
175
+
176
+ ## Development
177
+
178
+ ### Setup
179
+
180
+ ```bash
181
+ git clone https://github.com/afokapu/atdd.git
182
+ cd atdd
183
+ pip install -e ".[dev]"
184
+ ```
185
+
186
+ ### Run Tests
187
+
188
+ ```bash
189
+ # All tests
190
+ pytest
191
+
192
+ # Specific phase
193
+ pytest src/atdd/planner/validators/
194
+
195
+ # With coverage
196
+ pytest --cov=atdd --cov-report=html
197
+ ```
198
+
199
+ ### Adding Validators
200
+
201
+ 1. Create `src/atdd/{phase}/validators/test_{name}.py`
202
+ 2. Write pytest test functions
203
+ 3. Run `atdd --test {phase}`
204
+
205
+ Validators are auto-discovered by pytest.
206
+
207
+ ### Adding Conventions
208
+
209
+ 1. Create `src/atdd/{phase}/conventions/{name}.convention.yaml`
210
+ 2. Reference in validators via `Path(__file__).parent.parent / "conventions" / "..."`
211
+
212
+ ## Requirements
213
+
214
+ - Python 3.10+
215
+ - pyyaml
216
+
217
+ Dev dependencies: pytest, pytest-xdist
218
+
219
+ ## License
220
+
221
+ MIT