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,555 @@
|
|
|
1
|
+
# Test Filename Convention
|
|
2
|
+
# Defines deterministic filename generation from acceptance URNs
|
|
3
|
+
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
|
|
6
|
+
description: |
|
|
7
|
+
Test filename generation follows language-specific conventions derived from
|
|
8
|
+
acceptance URN format. This ensures consistent, traceable naming across all
|
|
9
|
+
test files, enabling bidirectional mapping between acceptance criteria and
|
|
10
|
+
their test implementations.
|
|
11
|
+
|
|
12
|
+
rationale: |
|
|
13
|
+
Standardized test filenames derived from acceptance URNs provide:
|
|
14
|
+
1. Traceability: Direct mapping from acceptance criteria to test files
|
|
15
|
+
2. Consistency: Language-specific conventions followed systematically
|
|
16
|
+
3. Discoverability: Predictable filenames enable tooling and automation
|
|
17
|
+
4. Maintainability: Clear relationship between requirements and tests
|
|
18
|
+
|
|
19
|
+
The URN-based approach ensures that test files can be generated deterministically
|
|
20
|
+
from acceptance criteria, and conversely, acceptance URNs can be extracted from
|
|
21
|
+
test filenames, supporting bidirectional navigation in the ATDD workflow.
|
|
22
|
+
|
|
23
|
+
urn_format:
|
|
24
|
+
pattern: "acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]"
|
|
25
|
+
description: "Acceptance URN format with optional slug"
|
|
26
|
+
|
|
27
|
+
components:
|
|
28
|
+
wagon:
|
|
29
|
+
description: "Wagon identifier in kebab-case"
|
|
30
|
+
pattern: "[a-z][a-z0-9-]*"
|
|
31
|
+
example: "maintain-ux"
|
|
32
|
+
|
|
33
|
+
WMBT:
|
|
34
|
+
description: "Step code + zero-padded 3-digit WMBT sequence"
|
|
35
|
+
pattern: "[DLPCEMYRK][0-9]{3}"
|
|
36
|
+
examples:
|
|
37
|
+
- "C004" # Code step 4
|
|
38
|
+
- "E019" # Evaluate step 19
|
|
39
|
+
- "P003" # Pace step 3
|
|
40
|
+
|
|
41
|
+
HARNESS:
|
|
42
|
+
description: "Test harness code (uppercase)"
|
|
43
|
+
pattern: "[A-Z0-9]+"
|
|
44
|
+
examples:
|
|
45
|
+
- "UNIT"
|
|
46
|
+
- "HTTP"
|
|
47
|
+
- "E2E"
|
|
48
|
+
- "EVENT"
|
|
49
|
+
- "WIDGET"
|
|
50
|
+
|
|
51
|
+
NNN:
|
|
52
|
+
description: "Zero-padded 3-digit per-harness acceptance sequence"
|
|
53
|
+
pattern: "[0-9]{3}"
|
|
54
|
+
examples:
|
|
55
|
+
- "001"
|
|
56
|
+
- "019"
|
|
57
|
+
- "042"
|
|
58
|
+
|
|
59
|
+
slug:
|
|
60
|
+
description: "Optional kebab-case descriptor"
|
|
61
|
+
pattern: "[a-z0-9-]+"
|
|
62
|
+
optional: true
|
|
63
|
+
examples:
|
|
64
|
+
- "user-connection"
|
|
65
|
+
- "primitive-endpoint"
|
|
66
|
+
- "avatar-display"
|
|
67
|
+
|
|
68
|
+
regex: "^acc:([a-z][a-z0-9-]*):([DLPCEMYRK][0-9]{3})-([A-Z0-9]+)-([0-9]{3})(?:-([a-z0-9-]+))?$"
|
|
69
|
+
|
|
70
|
+
examples:
|
|
71
|
+
- urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
72
|
+
wagon: "maintain-ux"
|
|
73
|
+
WMBT: "C004"
|
|
74
|
+
HARNESS: "E2E"
|
|
75
|
+
NNN: "019"
|
|
76
|
+
slug: "user-connection"
|
|
77
|
+
|
|
78
|
+
- urn: "acc:pace-dilemmas:P003-UNIT-042"
|
|
79
|
+
wagon: "pace-dilemmas"
|
|
80
|
+
WMBT: "P003"
|
|
81
|
+
HARNESS: "UNIT"
|
|
82
|
+
NNN: "042"
|
|
83
|
+
slug: null
|
|
84
|
+
|
|
85
|
+
slug_transformations:
|
|
86
|
+
kebab_to_snake:
|
|
87
|
+
description: "Convert kebab-case to snake_case (for Dart, Python, Go)"
|
|
88
|
+
example_input: "user-connection"
|
|
89
|
+
example_output: "user_connection"
|
|
90
|
+
algorithm: "Replace hyphens with underscores"
|
|
91
|
+
|
|
92
|
+
kebab_to_pascal:
|
|
93
|
+
description: "Convert kebab-case to PascalCase (for Java, Kotlin)"
|
|
94
|
+
example_input: "user-connection"
|
|
95
|
+
example_output: "UserConnection"
|
|
96
|
+
algorithm: "Split on hyphens, capitalize each part, join without separator"
|
|
97
|
+
|
|
98
|
+
kebab_to_kebab:
|
|
99
|
+
description: "Preserve kebab-case (legacy TypeScript or no-op cases)"
|
|
100
|
+
example_input: "user-connection"
|
|
101
|
+
example_output: "user-connection"
|
|
102
|
+
algorithm: "No transformation"
|
|
103
|
+
|
|
104
|
+
languages:
|
|
105
|
+
dart:
|
|
106
|
+
pattern: "{WMBT}_{HARNESS}_{NNN}[_{slug_snake}]_test.dart"
|
|
107
|
+
separator: "underscore"
|
|
108
|
+
casing: "WMBT and HARNESS uppercase, slug snake_case"
|
|
109
|
+
suffix: "_test.dart"
|
|
110
|
+
slug_transform: "kebab_to_snake"
|
|
111
|
+
|
|
112
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
113
|
+
example_filename: "C004_E2E_019_user_connection_test.dart"
|
|
114
|
+
|
|
115
|
+
rationale: |
|
|
116
|
+
Dart/Flutter conventions use snake_case with underscores. Test files
|
|
117
|
+
are suffixed with _test.dart. Uppercase WMBT and HARNESS codes maintain
|
|
118
|
+
visual distinction from the slug portion.
|
|
119
|
+
|
|
120
|
+
file_locations:
|
|
121
|
+
- "test/{wagon}/{feature}/"
|
|
122
|
+
- "integration_test/{wagon}/"
|
|
123
|
+
|
|
124
|
+
typescript:
|
|
125
|
+
pattern: "{wmbt_lower}-{harness_lower}-{nnn}[-{slug-kebab}].test.ts"
|
|
126
|
+
separator: "hyphen"
|
|
127
|
+
casing: "all lowercase, slug kebab-case"
|
|
128
|
+
suffix: ".test.ts"
|
|
129
|
+
slug_transform: "kebab_to_kebab"
|
|
130
|
+
|
|
131
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
132
|
+
example_filename: "c004-e2e-019-user-connection.test.ts"
|
|
133
|
+
|
|
134
|
+
rationale: |
|
|
135
|
+
TypeScript conventions favor kebab-case for filenames. Use .test.ts
|
|
136
|
+
suffixes for consistency across TypeScript runtimes. All lowercase ensures
|
|
137
|
+
modern JavaScript/TypeScript module naming.
|
|
138
|
+
|
|
139
|
+
file_locations:
|
|
140
|
+
- "supabase/functions/{wagon}/{feature}/test/"
|
|
141
|
+
- "e2e/{train}/"
|
|
142
|
+
- "supabase/functions/{feature}/test/" # DEPRECATED: Legacy flat structure
|
|
143
|
+
|
|
144
|
+
typescript_preact:
|
|
145
|
+
pattern: "{WMBT}_{HARNESS}_{NNN}[_{slug_snake}].test.ts[x]"
|
|
146
|
+
separator: "underscore"
|
|
147
|
+
casing: "WMBT and HARNESS uppercase, slug snake_case"
|
|
148
|
+
suffix: ".test.ts"
|
|
149
|
+
alternative_suffix: ".test.tsx"
|
|
150
|
+
slug_transform: "kebab_to_snake"
|
|
151
|
+
|
|
152
|
+
example_urn: "acc:maintain-ux:C001-WIDGET-001-button"
|
|
153
|
+
example_filename: "C001_WIDGET_001_button.test.tsx"
|
|
154
|
+
|
|
155
|
+
extension_rules:
|
|
156
|
+
".test.ts": "Logic tests (domain, application, integration)"
|
|
157
|
+
".test.tsx": "Component tests (presentation, widget harness)"
|
|
158
|
+
|
|
159
|
+
rationale: |
|
|
160
|
+
Preact/TypeScript tests align with URN-based filenames and use
|
|
161
|
+
underscore separators for readability. Use .test.tsx for component
|
|
162
|
+
tests that include JSX, and .test.ts for pure logic tests.
|
|
163
|
+
|
|
164
|
+
file_locations:
|
|
165
|
+
- "web/tests/{wagon}/{feature}/{layer}/"
|
|
166
|
+
|
|
167
|
+
python:
|
|
168
|
+
pattern: "test_{wmbt_lower}_{harness_lower}_{nnn}_{slug_snake}.py"
|
|
169
|
+
separator: "underscore"
|
|
170
|
+
casing: "all lowercase, slug snake_case"
|
|
171
|
+
prefix: "test_"
|
|
172
|
+
slug_transform: "kebab_to_snake"
|
|
173
|
+
slug_required: true
|
|
174
|
+
slug_source: "acceptance.identity.purpose"
|
|
175
|
+
|
|
176
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
177
|
+
example_filename: "test_c004_e2e_019_user_connection.py"
|
|
178
|
+
|
|
179
|
+
rationale: |
|
|
180
|
+
pytest requires test files to start with test_ prefix. Python conventions
|
|
181
|
+
use snake_case throughout. Lowercase codes maintain consistency with
|
|
182
|
+
Python's typical module naming.
|
|
183
|
+
|
|
184
|
+
Slugs are MANDATORY and derived from acceptance criteria purposes to:
|
|
185
|
+
1. Enable human-readable test filenames
|
|
186
|
+
2. Support ATDD test discovery and traceability
|
|
187
|
+
3. Provide clear intent without opening files
|
|
188
|
+
4. Facilitate code review and navigation
|
|
189
|
+
|
|
190
|
+
Slug extraction: Take the acceptance purpose field, remove "Verify" prefix,
|
|
191
|
+
convert to lowercase, replace spaces with hyphens, and limit to first 5 words.
|
|
192
|
+
|
|
193
|
+
file_locations:
|
|
194
|
+
- "python/{wagon_snake}/{feature_snake}/test/" # Feature-based structure (preferred)
|
|
195
|
+
- "tests/{wagon}/" # Legacy wagon-level tests
|
|
196
|
+
- ".claude/utils/{agent}/tests/" # Platform utility tests
|
|
197
|
+
|
|
198
|
+
go:
|
|
199
|
+
pattern: "{wmbt_lower}_{harness_lower}_{nnn}[_{slug_snake}]_test.go"
|
|
200
|
+
separator: "underscore"
|
|
201
|
+
casing: "all lowercase, slug snake_case"
|
|
202
|
+
suffix: "_test.go"
|
|
203
|
+
slug_transform: "kebab_to_snake"
|
|
204
|
+
|
|
205
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
206
|
+
example_filename: "c004_e2e_019_user_connection_test.go"
|
|
207
|
+
|
|
208
|
+
rationale: |
|
|
209
|
+
Go testing convention requires _test.go suffix. Go uses snake_case for
|
|
210
|
+
test files. Lowercase maintains consistency with Go's filename conventions.
|
|
211
|
+
|
|
212
|
+
file_locations:
|
|
213
|
+
- "{wagon}/"
|
|
214
|
+
- "cmd/{wagon}/"
|
|
215
|
+
- "pkg/{wagon}/"
|
|
216
|
+
|
|
217
|
+
java:
|
|
218
|
+
pattern: "{WMBT}{HARNESS}{NNN}{SlugPascal}Test"
|
|
219
|
+
separator: "none"
|
|
220
|
+
casing: "WMBT and HARNESS uppercase, slug PascalCase"
|
|
221
|
+
suffix: "Test"
|
|
222
|
+
slug_transform: "kebab_to_pascal"
|
|
223
|
+
|
|
224
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
225
|
+
example_filename: "C004E2E019UserConnectionTest.java"
|
|
226
|
+
example_classname: "C004E2E019UserConnectionTest"
|
|
227
|
+
|
|
228
|
+
rationale: |
|
|
229
|
+
Java requires filename to match class name. JUnit convention uses Test
|
|
230
|
+
suffix. PascalCase without separators follows Java class naming standards.
|
|
231
|
+
|
|
232
|
+
file_locations:
|
|
233
|
+
- "src/test/java/{package}/{wagon}/"
|
|
234
|
+
|
|
235
|
+
kotlin:
|
|
236
|
+
pattern: "{WMBT}{HARNESS}{NNN}{SlugPascal}Test.kt"
|
|
237
|
+
separator: "none"
|
|
238
|
+
casing: "WMBT and HARNESS uppercase, slug PascalCase"
|
|
239
|
+
suffix: "Test"
|
|
240
|
+
slug_transform: "kebab_to_pascal"
|
|
241
|
+
|
|
242
|
+
example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
|
|
243
|
+
example_filename: "C004E2E019UserConnectionTest.kt"
|
|
244
|
+
example_classname: "C004E2E019UserConnectionTest"
|
|
245
|
+
|
|
246
|
+
rationale: |
|
|
247
|
+
Kotlin follows same conventions as Java for test naming. JUnit/KotlinTest
|
|
248
|
+
frameworks expect Test suffix and PascalCase class names.
|
|
249
|
+
|
|
250
|
+
file_locations:
|
|
251
|
+
- "src/test/kotlin/{package}/{wagon}/"
|
|
252
|
+
|
|
253
|
+
harness_codes:
|
|
254
|
+
- code: "UNIT"
|
|
255
|
+
description: "Unit tests for isolated component logic"
|
|
256
|
+
- code: "HTTP"
|
|
257
|
+
description: "HTTP API endpoint tests"
|
|
258
|
+
- code: "EVENT"
|
|
259
|
+
description: "Event handler and pub/sub tests"
|
|
260
|
+
- code: "WS"
|
|
261
|
+
description: "WebSocket connection tests"
|
|
262
|
+
- code: "E2E"
|
|
263
|
+
description: "End-to-end integration tests"
|
|
264
|
+
- code: "A11Y"
|
|
265
|
+
description: "Accessibility compliance tests"
|
|
266
|
+
- code: "VIS"
|
|
267
|
+
description: "Visual regression tests"
|
|
268
|
+
- code: "METRIC"
|
|
269
|
+
description: "Performance metric tests"
|
|
270
|
+
- code: "JOB"
|
|
271
|
+
description: "Background job tests"
|
|
272
|
+
- code: "DB"
|
|
273
|
+
description: "Database operation tests"
|
|
274
|
+
- code: "SEC"
|
|
275
|
+
description: "Security validation tests"
|
|
276
|
+
- code: "LOAD"
|
|
277
|
+
description: "Load and stress tests"
|
|
278
|
+
- code: "SCRIPT"
|
|
279
|
+
description: "Script execution tests"
|
|
280
|
+
- code: "WIDGET"
|
|
281
|
+
description: "Widget component tests"
|
|
282
|
+
- code: "GOLDEN"
|
|
283
|
+
description: "Golden file comparison tests"
|
|
284
|
+
- code: "BLOC"
|
|
285
|
+
description: "BLoC pattern tests"
|
|
286
|
+
- code: "INTEGRATION"
|
|
287
|
+
description: "Integration tests"
|
|
288
|
+
- code: "RLS"
|
|
289
|
+
description: "Row-level security tests"
|
|
290
|
+
- code: "EDGE"
|
|
291
|
+
description: "Edge function tests"
|
|
292
|
+
- code: "REALTIME"
|
|
293
|
+
description: "Realtime subscription tests"
|
|
294
|
+
- code: "STORAGE"
|
|
295
|
+
description: "Storage operation tests"
|
|
296
|
+
|
|
297
|
+
utility_functions:
|
|
298
|
+
module: ".claude/utils/tester/filename.py"
|
|
299
|
+
|
|
300
|
+
functions:
|
|
301
|
+
- name: "parse_acceptance_urn"
|
|
302
|
+
description: "Parse URN into components (wagon, WMBT, HARNESS, NNN, slug)"
|
|
303
|
+
signature: "parse_acceptance_urn(urn: str) -> Dict[str, Optional[str]]"
|
|
304
|
+
|
|
305
|
+
- name: "dart_filename"
|
|
306
|
+
description: "Generate Dart test filename from URN"
|
|
307
|
+
signature: "dart_filename(urn: str) -> str"
|
|
308
|
+
|
|
309
|
+
- name: "typescript_filename"
|
|
310
|
+
description: "Generate TypeScript test filename from URN"
|
|
311
|
+
signature: "typescript_filename(urn: str) -> str"
|
|
312
|
+
|
|
313
|
+
- name: "typescript_preact_filename"
|
|
314
|
+
description: "Generate Preact TypeScript test filename from URN"
|
|
315
|
+
signature: "typescript_preact_filename(urn: str, tsx: Optional[bool] = None) -> str"
|
|
316
|
+
|
|
317
|
+
- name: "python_filename"
|
|
318
|
+
description: "Generate Python test filename from URN"
|
|
319
|
+
signature: "python_filename(urn: str) -> str"
|
|
320
|
+
|
|
321
|
+
- name: "go_filename"
|
|
322
|
+
description: "Generate Go test filename from URN"
|
|
323
|
+
signature: "go_filename(urn: str) -> str"
|
|
324
|
+
|
|
325
|
+
- name: "java_classname"
|
|
326
|
+
description: "Generate Java/Kotlin test classname from URN"
|
|
327
|
+
signature: "java_classname(urn: str) -> str"
|
|
328
|
+
|
|
329
|
+
- name: "generate_test_filename"
|
|
330
|
+
description: "Unified interface accepting language parameter"
|
|
331
|
+
signature: "generate_test_filename(urn: str, language: str) -> str"
|
|
332
|
+
|
|
333
|
+
- name: "kebab_to_snake"
|
|
334
|
+
description: "Convert kebab-case to snake_case"
|
|
335
|
+
signature: "kebab_to_snake(slug: Optional[str]) -> str"
|
|
336
|
+
|
|
337
|
+
- name: "kebab_to_pascal"
|
|
338
|
+
description: "Convert kebab-case to PascalCase"
|
|
339
|
+
signature: "kebab_to_pascal(slug: Optional[str]) -> str"
|
|
340
|
+
|
|
341
|
+
validation:
|
|
342
|
+
urn_format:
|
|
343
|
+
- "URN must match regex pattern"
|
|
344
|
+
- "Wagon must be lowercase with hyphens"
|
|
345
|
+
- "WMBT must be uppercase letter + 3 digits"
|
|
346
|
+
- "HARNESS must be uppercase code from approved list"
|
|
347
|
+
- "NNN must be 3-digit zero-padded sequence"
|
|
348
|
+
- "Slug (if present) must be lowercase with hyphens"
|
|
349
|
+
|
|
350
|
+
filename_format:
|
|
351
|
+
- "Generated filename must follow language-specific pattern"
|
|
352
|
+
- "Casing transformations must be applied correctly"
|
|
353
|
+
- "Separators must match language conventions"
|
|
354
|
+
- "File extension must match language requirements"
|
|
355
|
+
|
|
356
|
+
test_file_header:
|
|
357
|
+
description: "All test files should include URN comment for traceability"
|
|
358
|
+
|
|
359
|
+
formats:
|
|
360
|
+
dart: |
|
|
361
|
+
// urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
|
|
362
|
+
|
|
363
|
+
typescript: |
|
|
364
|
+
// urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
|
|
365
|
+
|
|
366
|
+
python: |
|
|
367
|
+
# urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
|
|
368
|
+
|
|
369
|
+
go: |
|
|
370
|
+
// urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
|
|
371
|
+
|
|
372
|
+
java: |
|
|
373
|
+
// urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
|
|
374
|
+
|
|
375
|
+
directory_structure:
|
|
376
|
+
description: |
|
|
377
|
+
Tests are organized by feature within wagon directories. Each feature contains
|
|
378
|
+
separate src/ and test/ folders following clean architecture principles.
|
|
379
|
+
|
|
380
|
+
pattern: "{language}/{wagon_snake}/{feature_snake}/{src|test}/"
|
|
381
|
+
|
|
382
|
+
rationale: |
|
|
383
|
+
Feature-based organization provides:
|
|
384
|
+
1. Feature Isolation: Each feature's code and tests are colocated
|
|
385
|
+
2. Traceability: Direct mapping from wagon manifest features to code structure
|
|
386
|
+
3. Scalability: Wagons can contain multiple features without test conflicts
|
|
387
|
+
4. Clarity: Clear separation between implementation (src/) and verification (test/)
|
|
388
|
+
|
|
389
|
+
examples:
|
|
390
|
+
python:
|
|
391
|
+
structure: |
|
|
392
|
+
python/
|
|
393
|
+
{wagon_snake}/ # Wagon directory (kebab→snake)
|
|
394
|
+
{feature_snake}/ # Feature directory (kebab→snake)
|
|
395
|
+
src/ # Implementation code
|
|
396
|
+
__init__.py
|
|
397
|
+
domain/ # Domain layer
|
|
398
|
+
application/ # Application layer
|
|
399
|
+
integration/ # Integration layer
|
|
400
|
+
test/ # Test code
|
|
401
|
+
__init__.py
|
|
402
|
+
test_{wmbt}_{harness}_{nnn}.py # Acceptance tests
|
|
403
|
+
conftest.py # Pytest fixtures
|
|
404
|
+
|
|
405
|
+
example_wagon: "generate-identifiers"
|
|
406
|
+
example_features:
|
|
407
|
+
- "generate-uuid"
|
|
408
|
+
- "generate-username"
|
|
409
|
+
|
|
410
|
+
concrete_structure: |
|
|
411
|
+
python/
|
|
412
|
+
generate_identifiers/
|
|
413
|
+
generate_uuid/
|
|
414
|
+
src/
|
|
415
|
+
__init__.py
|
|
416
|
+
uuid_generator.py
|
|
417
|
+
test/
|
|
418
|
+
__init__.py
|
|
419
|
+
test_l001_unit_001.py # Performance test
|
|
420
|
+
test_l001_load_001.py # Throughput test
|
|
421
|
+
test_c005.py # RFC compliance
|
|
422
|
+
test_c006.py # Deterministic generation
|
|
423
|
+
generate_username/
|
|
424
|
+
src/
|
|
425
|
+
__init__.py
|
|
426
|
+
username_sanitizer.py
|
|
427
|
+
username_validator.py
|
|
428
|
+
test/
|
|
429
|
+
__init__.py
|
|
430
|
+
test_p001_unit_001.py # Sanitization
|
|
431
|
+
test_p001_unit_002.py # Unicode handling
|
|
432
|
+
test_c001_unit_001.py # Uniqueness (taken)
|
|
433
|
+
test_c001_unit_002.py # Uniqueness (available)
|
|
434
|
+
test_c004.py # Reserved words
|
|
435
|
+
test_c007.py # Format enforcement
|
|
436
|
+
|
|
437
|
+
dart:
|
|
438
|
+
structure: |
|
|
439
|
+
lib/
|
|
440
|
+
{wagon_snake}/ # Wagon directory
|
|
441
|
+
{feature_snake}/ # Feature directory
|
|
442
|
+
src/ # Implementation
|
|
443
|
+
domain/
|
|
444
|
+
application/
|
|
445
|
+
presentation/
|
|
446
|
+
test/
|
|
447
|
+
{wagon_snake}/ # Test mirror structure
|
|
448
|
+
{feature_snake}/
|
|
449
|
+
{WMBT}_{HARNESS}_{NNN}_test.dart
|
|
450
|
+
|
|
451
|
+
example: |
|
|
452
|
+
lib/maintain_ux/provide_foundations/src/
|
|
453
|
+
test/maintain_ux/provide_foundations/L001_UNIT_001_test.dart
|
|
454
|
+
|
|
455
|
+
naming_transformations:
|
|
456
|
+
wagon_name:
|
|
457
|
+
input: "Wagon name from manifest (kebab-case)"
|
|
458
|
+
python_output: "snake_case"
|
|
459
|
+
dart_output: "snake_case"
|
|
460
|
+
typescript_output: "kebab-case"
|
|
461
|
+
example_input: "generate-identifiers"
|
|
462
|
+
example_python: "generate_identifiers"
|
|
463
|
+
example_dart: "generate_identifiers"
|
|
464
|
+
|
|
465
|
+
feature_name:
|
|
466
|
+
input: "Feature name from wagon manifest (kebab-case)"
|
|
467
|
+
python_output: "snake_case"
|
|
468
|
+
dart_output: "snake_case"
|
|
469
|
+
typescript_output: "kebab-case"
|
|
470
|
+
example_input: "generate-uuid"
|
|
471
|
+
example_python: "generate_uuid"
|
|
472
|
+
example_dart: "generate_uuid"
|
|
473
|
+
|
|
474
|
+
feature_discovery:
|
|
475
|
+
description: "Features are defined in wagon manifest YAML"
|
|
476
|
+
manifest_location: "plan/{wagon}/_{wagon}.yaml"
|
|
477
|
+
manifest_field: "features[]"
|
|
478
|
+
|
|
479
|
+
example_manifest: |
|
|
480
|
+
wagon: generate-identifiers
|
|
481
|
+
features:
|
|
482
|
+
- urn: feature:generate-identifiers:generate-uuid
|
|
483
|
+
- urn: feature:generate-identifiers:generate-username
|
|
484
|
+
|
|
485
|
+
feature_extraction:
|
|
486
|
+
pattern: "feature:{wagon}:{feature_name}"
|
|
487
|
+
regex: "^feature:([a-z][a-z0-9-]*):([a-z][a-z0-9-]*)$"
|
|
488
|
+
wagon_group: 1
|
|
489
|
+
feature_group: 2
|
|
490
|
+
|
|
491
|
+
acceptance_to_feature_mapping:
|
|
492
|
+
description: |
|
|
493
|
+
Each acceptance criteria belongs to a feature. The feature name determines
|
|
494
|
+
which test directory the test file should be placed in.
|
|
495
|
+
|
|
496
|
+
lookup_process:
|
|
497
|
+
1: "Parse acceptance URN to extract wagon and WMBT code"
|
|
498
|
+
2: "Load wagon manifest from plan/{wagon}/_{wagon}.yaml"
|
|
499
|
+
3: "Load WMBT file from plan/{wagon}/{WMBT}.yaml"
|
|
500
|
+
4: "Extract feature URNs from wagon manifest features[]"
|
|
501
|
+
5: "Match acceptance to feature via acceptance.identity.purpose or metadata.feature"
|
|
502
|
+
6: "Extract feature name from feature URN"
|
|
503
|
+
7: "Generate test path: {lang}/{wagon_snake}/{feature_snake}/test/"
|
|
504
|
+
|
|
505
|
+
example:
|
|
506
|
+
acceptance_urn: "acc:generate-identifiers:L001-UNIT-001"
|
|
507
|
+
wagon: "generate-identifiers"
|
|
508
|
+
wmbt_file: "plan/generate_identifiers/L001.yaml"
|
|
509
|
+
feature_urn: "feature:generate-identifiers:generate-uuid"
|
|
510
|
+
feature_name: "generate-uuid"
|
|
511
|
+
test_path: "python/generate_identifiers/generate_uuid/test/"
|
|
512
|
+
test_filename: "test_l001_unit_001.py"
|
|
513
|
+
full_path: "python/generate_identifiers/generate_uuid/test/test_l001_unit_001.py"
|
|
514
|
+
|
|
515
|
+
references:
|
|
516
|
+
spec_ids:
|
|
517
|
+
- "SPEC-TESTER-CONV-0068" # Parse acceptance URN components
|
|
518
|
+
- "SPEC-TESTER-CONV-0069" # Generate Dart filename
|
|
519
|
+
- "SPEC-TESTER-CONV-0070" # Generate TypeScript filename
|
|
520
|
+
- "SPEC-TESTER-CONV-0071" # Generate Python filename
|
|
521
|
+
- "SPEC-TESTER-CONV-0072" # Generate Go filename
|
|
522
|
+
- "SPEC-TESTER-CONV-0073" # Generate Java/Kotlin classname
|
|
523
|
+
- "SPEC-TESTER-CONV-0074" # Handle URN without slug
|
|
524
|
+
- "SPEC-TESTER-CONV-0075" # Slug transformations
|
|
525
|
+
- "SPEC-TESTER-CONV-0076" # URN regex validation
|
|
526
|
+
- "SPEC-TESTER-CONV-0077" # Convention documentation
|
|
527
|
+
- "SPEC-TESTER-CONV-0078" # Platform validation enforcement
|
|
528
|
+
- "SPEC-TESTER-CONV-0079" # Feature-based directory structure
|
|
529
|
+
- "SPEC-TESTER-CONV-0080" # Acceptance-to-feature mapping
|
|
530
|
+
|
|
531
|
+
related_conventions:
|
|
532
|
+
- "red.convention.yaml" # References test generation
|
|
533
|
+
- "artifact.convention.yaml" # Pattern for URN-to-path mapping
|
|
534
|
+
- "backend.convention.yaml" # Layer structure within src/
|
|
535
|
+
|
|
536
|
+
related_schemas:
|
|
537
|
+
- ".claude/schemas/tester/test_intent.schema.json"
|
|
538
|
+
- ".claude/schemas/planner/acceptance.schema.json"
|
|
539
|
+
- ".claude/schemas/planner/wagon.schema.json"
|
|
540
|
+
- ".claude/schemas/planner/feature.schema.json"
|
|
541
|
+
|
|
542
|
+
migration:
|
|
543
|
+
from_legacy:
|
|
544
|
+
description: "Legacy test files may not follow URN-based naming"
|
|
545
|
+
strategy: |
|
|
546
|
+
1. Extract URN from test file header comment
|
|
547
|
+
2. Generate expected filename using utility
|
|
548
|
+
3. Rename file if filename doesn't match convention
|
|
549
|
+
4. Update imports and references
|
|
550
|
+
|
|
551
|
+
example_transformation:
|
|
552
|
+
legacy_dart: "ac_http_006_primitive_endpoint_test.dart"
|
|
553
|
+
legacy_urn_comment: "// urn: acc:maintain-ux.001.AC-HTTP-006"
|
|
554
|
+
new_urn: "acc:maintain-ux:C004-HTTP-006-primitive-endpoint"
|
|
555
|
+
new_filename: "C004_HTTP_006_primitive_endpoint_test.dart"
|