atdd 0.1.0__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 (183) hide show
  1. atdd/__init__.py +0 -0
  2. atdd/cli.py +404 -0
  3. atdd/coach/__init__.py +0 -0
  4. atdd/coach/commands/__init__.py +0 -0
  5. atdd/coach/commands/add_persistence_metadata.py +215 -0
  6. atdd/coach/commands/analyze_migrations.py +188 -0
  7. atdd/coach/commands/consumers.py +720 -0
  8. atdd/coach/commands/infer_governance_status.py +149 -0
  9. atdd/coach/commands/initializer.py +177 -0
  10. atdd/coach/commands/interface.py +1078 -0
  11. atdd/coach/commands/inventory.py +565 -0
  12. atdd/coach/commands/migration.py +240 -0
  13. atdd/coach/commands/registry.py +1560 -0
  14. atdd/coach/commands/session.py +430 -0
  15. atdd/coach/commands/sync.py +405 -0
  16. atdd/coach/commands/test_interface.py +399 -0
  17. atdd/coach/commands/test_runner.py +141 -0
  18. atdd/coach/commands/tests/__init__.py +1 -0
  19. atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
  20. atdd/coach/commands/traceability.py +4264 -0
  21. atdd/coach/conventions/session.convention.yaml +754 -0
  22. atdd/coach/overlays/__init__.py +2 -0
  23. atdd/coach/overlays/claude.md +2 -0
  24. atdd/coach/schemas/config.schema.json +34 -0
  25. atdd/coach/schemas/manifest.schema.json +101 -0
  26. atdd/coach/templates/ATDD.md +282 -0
  27. atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
  28. atdd/coach/utils/__init__.py +0 -0
  29. atdd/coach/utils/graph/__init__.py +0 -0
  30. atdd/coach/utils/graph/urn.py +875 -0
  31. atdd/coach/validators/__init__.py +0 -0
  32. atdd/coach/validators/shared_fixtures.py +365 -0
  33. atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
  34. atdd/coach/validators/test_registry.py +575 -0
  35. atdd/coach/validators/test_session_validation.py +1183 -0
  36. atdd/coach/validators/test_traceability.py +448 -0
  37. atdd/coach/validators/test_update_feature_paths.py +108 -0
  38. atdd/coach/validators/test_validate_contract_consumers.py +297 -0
  39. atdd/coder/__init__.py +1 -0
  40. atdd/coder/conventions/adapter.recipe.yaml +88 -0
  41. atdd/coder/conventions/backend.convention.yaml +460 -0
  42. atdd/coder/conventions/boundaries.convention.yaml +666 -0
  43. atdd/coder/conventions/commons.convention.yaml +460 -0
  44. atdd/coder/conventions/complexity.recipe.yaml +109 -0
  45. atdd/coder/conventions/component-naming.convention.yaml +178 -0
  46. atdd/coder/conventions/design.convention.yaml +327 -0
  47. atdd/coder/conventions/design.recipe.yaml +273 -0
  48. atdd/coder/conventions/dto.convention.yaml +660 -0
  49. atdd/coder/conventions/frontend.convention.yaml +542 -0
  50. atdd/coder/conventions/green.convention.yaml +1012 -0
  51. atdd/coder/conventions/presentation.convention.yaml +587 -0
  52. atdd/coder/conventions/refactor.convention.yaml +535 -0
  53. atdd/coder/conventions/technology.convention.yaml +206 -0
  54. atdd/coder/conventions/tests/__init__.py +0 -0
  55. atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
  56. atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
  57. atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
  58. atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
  59. atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
  60. atdd/coder/conventions/thinness.recipe.yaml +82 -0
  61. atdd/coder/conventions/train.convention.yaml +325 -0
  62. atdd/coder/conventions/verification.protocol.yaml +53 -0
  63. atdd/coder/schemas/design_system.schema.json +361 -0
  64. atdd/coder/validators/__init__.py +0 -0
  65. atdd/coder/validators/test_commons_structure.py +485 -0
  66. atdd/coder/validators/test_complexity.py +416 -0
  67. atdd/coder/validators/test_cross_language_consistency.py +431 -0
  68. atdd/coder/validators/test_design_system_compliance.py +413 -0
  69. atdd/coder/validators/test_dto_testing_patterns.py +268 -0
  70. atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
  71. atdd/coder/validators/test_green_layer_dependencies.py +148 -0
  72. atdd/coder/validators/test_green_python_layer_structure.py +103 -0
  73. atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
  74. atdd/coder/validators/test_import_boundaries.py +396 -0
  75. atdd/coder/validators/test_init_file_urns.py +593 -0
  76. atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
  77. atdd/coder/validators/test_presentation_convention.py +260 -0
  78. atdd/coder/validators/test_python_architecture.py +674 -0
  79. atdd/coder/validators/test_quality_metrics.py +420 -0
  80. atdd/coder/validators/test_station_master_pattern.py +244 -0
  81. atdd/coder/validators/test_train_infrastructure.py +454 -0
  82. atdd/coder/validators/test_train_urns.py +293 -0
  83. atdd/coder/validators/test_typescript_architecture.py +616 -0
  84. atdd/coder/validators/test_usecase_structure.py +421 -0
  85. atdd/coder/validators/test_wagon_boundaries.py +586 -0
  86. atdd/conftest.py +126 -0
  87. atdd/planner/__init__.py +1 -0
  88. atdd/planner/conventions/acceptance.convention.yaml +538 -0
  89. atdd/planner/conventions/appendix.convention.yaml +187 -0
  90. atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
  91. atdd/planner/conventions/component.convention.yaml +670 -0
  92. atdd/planner/conventions/criteria.convention.yaml +141 -0
  93. atdd/planner/conventions/feature.convention.yaml +371 -0
  94. atdd/planner/conventions/interface.convention.yaml +382 -0
  95. atdd/planner/conventions/steps.convention.yaml +141 -0
  96. atdd/planner/conventions/train.convention.yaml +552 -0
  97. atdd/planner/conventions/wagon.convention.yaml +275 -0
  98. atdd/planner/conventions/wmbt.convention.yaml +258 -0
  99. atdd/planner/schemas/acceptance.schema.json +336 -0
  100. atdd/planner/schemas/appendix.schema.json +78 -0
  101. atdd/planner/schemas/component.schema.json +114 -0
  102. atdd/planner/schemas/feature.schema.json +197 -0
  103. atdd/planner/schemas/train.schema.json +192 -0
  104. atdd/planner/schemas/wagon.schema.json +281 -0
  105. atdd/planner/schemas/wmbt.schema.json +59 -0
  106. atdd/planner/validators/__init__.py +0 -0
  107. atdd/planner/validators/conftest.py +5 -0
  108. atdd/planner/validators/test_draft_wagon_registry.py +374 -0
  109. atdd/planner/validators/test_plan_cross_refs.py +240 -0
  110. atdd/planner/validators/test_plan_uniqueness.py +224 -0
  111. atdd/planner/validators/test_plan_urn_resolution.py +268 -0
  112. atdd/planner/validators/test_plan_wagons.py +174 -0
  113. atdd/planner/validators/test_train_validation.py +514 -0
  114. atdd/planner/validators/test_wagon_urn_chain.py +648 -0
  115. atdd/planner/validators/test_wmbt_consistency.py +327 -0
  116. atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
  117. atdd/tester/__init__.py +1 -0
  118. atdd/tester/conventions/artifact.convention.yaml +257 -0
  119. atdd/tester/conventions/contract.convention.yaml +1009 -0
  120. atdd/tester/conventions/filename.convention.yaml +555 -0
  121. atdd/tester/conventions/migration.convention.yaml +509 -0
  122. atdd/tester/conventions/red.convention.yaml +797 -0
  123. atdd/tester/conventions/routing.convention.yaml +51 -0
  124. atdd/tester/conventions/telemetry.convention.yaml +458 -0
  125. atdd/tester/schemas/a11y.tmpl.json +17 -0
  126. atdd/tester/schemas/artifact.schema.json +189 -0
  127. atdd/tester/schemas/contract.schema.json +591 -0
  128. atdd/tester/schemas/contract.tmpl.json +95 -0
  129. atdd/tester/schemas/db.tmpl.json +20 -0
  130. atdd/tester/schemas/e2e.tmpl.json +17 -0
  131. atdd/tester/schemas/edge_function.tmpl.json +17 -0
  132. atdd/tester/schemas/event.tmpl.json +17 -0
  133. atdd/tester/schemas/http.tmpl.json +19 -0
  134. atdd/tester/schemas/job.tmpl.json +18 -0
  135. atdd/tester/schemas/load.tmpl.json +21 -0
  136. atdd/tester/schemas/metric.tmpl.json +19 -0
  137. atdd/tester/schemas/pack.schema.json +139 -0
  138. atdd/tester/schemas/realtime.tmpl.json +20 -0
  139. atdd/tester/schemas/rls.tmpl.json +18 -0
  140. atdd/tester/schemas/script.tmpl.json +16 -0
  141. atdd/tester/schemas/sec.tmpl.json +18 -0
  142. atdd/tester/schemas/storage.tmpl.json +18 -0
  143. atdd/tester/schemas/telemetry.schema.json +128 -0
  144. atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
  145. atdd/tester/schemas/test_filename.schema.json +194 -0
  146. atdd/tester/schemas/test_intent.schema.json +179 -0
  147. atdd/tester/schemas/unit.tmpl.json +18 -0
  148. atdd/tester/schemas/visual.tmpl.json +18 -0
  149. atdd/tester/schemas/ws.tmpl.json +17 -0
  150. atdd/tester/utils/__init__.py +0 -0
  151. atdd/tester/utils/filename.py +300 -0
  152. atdd/tester/validators/__init__.py +0 -0
  153. atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
  154. atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
  155. atdd/tester/validators/conftest.py +5 -0
  156. atdd/tester/validators/coverage_gap_report.py +321 -0
  157. atdd/tester/validators/fix_dual_ac_references.py +179 -0
  158. atdd/tester/validators/remove_duplicate_lines.py +93 -0
  159. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
  160. atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
  161. atdd/tester/validators/test_artifact_naming_category.py +307 -0
  162. atdd/tester/validators/test_contract_schema_compliance.py +706 -0
  163. atdd/tester/validators/test_contracts_structure.py +200 -0
  164. atdd/tester/validators/test_coverage_adequacy.py +797 -0
  165. atdd/tester/validators/test_dual_ac_reference.py +225 -0
  166. atdd/tester/validators/test_fixture_validity.py +372 -0
  167. atdd/tester/validators/test_isolation.py +487 -0
  168. atdd/tester/validators/test_migration_coverage.py +204 -0
  169. atdd/tester/validators/test_migration_criteria.py +276 -0
  170. atdd/tester/validators/test_migration_generation.py +116 -0
  171. atdd/tester/validators/test_python_test_naming.py +410 -0
  172. atdd/tester/validators/test_red_layer_validation.py +95 -0
  173. atdd/tester/validators/test_red_python_layer_structure.py +87 -0
  174. atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
  175. atdd/tester/validators/test_telemetry_structure.py +634 -0
  176. atdd/tester/validators/test_typescript_test_naming.py +301 -0
  177. atdd/tester/validators/test_typescript_test_structure.py +84 -0
  178. atdd-0.1.0.dist-info/METADATA +191 -0
  179. atdd-0.1.0.dist-info/RECORD +183 -0
  180. atdd-0.1.0.dist-info/WHEEL +5 -0
  181. atdd-0.1.0.dist-info/entry_points.txt +2 -0
  182. atdd-0.1.0.dist-info/licenses/LICENSE +674 -0
  183. atdd-0.1.0.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,191 @@
1
+ Metadata-Version: 2.4
2
+ Name: atdd
3
+ Version: 0.1.0
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 GitHub (recommended for now)
22
+
23
+ ```bash
24
+ pip install git+https://github.com/afokapu/atdd.git
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
+ ### Future: PyPI
42
+
43
+ Once published to PyPI:
44
+ ```bash
45
+ pip install atdd
46
+ ```
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ # Initialize ATDD in your project
52
+ atdd init
53
+
54
+ # Create a planning session
55
+ atdd session new my-feature
56
+
57
+ # List sessions
58
+ atdd session list
59
+
60
+ # Run validators
61
+ atdd --test all
62
+ ```
63
+
64
+ ## What It Does
65
+
66
+ ATDD provides:
67
+
68
+ 1. **Session Management** - Structured planning documents with templates and tracking
69
+ 2. **Convention Enforcement** - YAML-based conventions validated via pytest
70
+ 3. **ATDD Lifecycle** - Planner → Tester → Coder phase gates
71
+
72
+ ## Commands
73
+
74
+ ### Project Initialization
75
+
76
+ ```bash
77
+ atdd init # Create atdd-sessions/ and .atdd/ directories
78
+ atdd init --force # Reinitialize (overwrites existing)
79
+ ```
80
+
81
+ Creates:
82
+ ```
83
+ your-project/
84
+ ├── atdd-sessions/
85
+ │ ├── SESSION-TEMPLATE.md
86
+ │ └── archive/
87
+ └── .atdd/
88
+ └── manifest.yaml
89
+ ```
90
+
91
+ ### Session Management
92
+
93
+ ```bash
94
+ atdd session new <slug> # Create new session
95
+ atdd session new <slug> --type <type> # Specify type
96
+ atdd session list # List all sessions
97
+ atdd session archive <id> # Archive session
98
+ atdd session sync # Sync manifest with files
99
+ ```
100
+
101
+ Session types: `implementation`, `migration`, `refactor`, `analysis`, `planning`, `cleanup`, `tracking`
102
+
103
+ ### Validation
104
+
105
+ ```bash
106
+ atdd --test all # Run all validators
107
+ atdd --test planner # Planning artifacts only
108
+ atdd --test tester # Testing artifacts only
109
+ atdd --test coder # Implementation only
110
+ atdd --quick # Fast smoke test
111
+ ```
112
+
113
+ ### Other Commands
114
+
115
+ ```bash
116
+ atdd --status # Platform status
117
+ atdd --inventory # Generate artifact inventory
118
+ atdd --help # Full help
119
+ ```
120
+
121
+ ## Project Structure
122
+
123
+ ```
124
+ src/atdd/
125
+ ├── cli.py # Entry point
126
+ ├── coach/
127
+ │ ├── commands/ # CLI command implementations
128
+ │ ├── conventions/ # Coach conventions (YAML)
129
+ │ ├── schemas/ # JSON schemas
130
+ │ ├── templates/ # Session templates
131
+ │ └── validators/ # Coach validators
132
+ ├── planner/
133
+ │ ├── conventions/ # Planning conventions
134
+ │ ├── schemas/ # Planning schemas
135
+ │ └── validators/ # Planning validators
136
+ ├── tester/
137
+ │ ├── conventions/ # Testing conventions
138
+ │ ├── schemas/ # Testing schemas
139
+ │ └── validators/ # Testing validators
140
+ └── coder/
141
+ ├── conventions/ # Coding conventions
142
+ ├── schemas/ # Coder schemas
143
+ └── validators/ # Implementation validators
144
+ ```
145
+
146
+ ## Development
147
+
148
+ ### Setup
149
+
150
+ ```bash
151
+ git clone https://github.com/afokapu/atdd.git
152
+ cd atdd
153
+ pip install -e ".[dev]"
154
+ ```
155
+
156
+ ### Run Tests
157
+
158
+ ```bash
159
+ # All tests
160
+ pytest
161
+
162
+ # Specific phase
163
+ pytest src/atdd/planner/validators/
164
+
165
+ # With coverage
166
+ pytest --cov=atdd --cov-report=html
167
+ ```
168
+
169
+ ### Adding Validators
170
+
171
+ 1. Create `src/atdd/{phase}/validators/test_{name}.py`
172
+ 2. Write pytest test functions
173
+ 3. Run `atdd --test {phase}`
174
+
175
+ Validators are auto-discovered by pytest.
176
+
177
+ ### Adding Conventions
178
+
179
+ 1. Create `src/atdd/{phase}/conventions/{name}.convention.yaml`
180
+ 2. Reference in validators via `Path(__file__).parent.parent / "conventions" / "..."`
181
+
182
+ ## Requirements
183
+
184
+ - Python 3.10+
185
+ - pyyaml
186
+
187
+ Dev dependencies: pytest, pytest-xdist
188
+
189
+ ## License
190
+
191
+ MIT