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.
- atdd/__init__.py +0 -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.1.0.dist-info/METADATA +191 -0
- atdd-0.1.0.dist-info/RECORD +183 -0
- atdd-0.1.0.dist-info/WHEEL +5 -0
- atdd-0.1.0.dist-info/entry_points.txt +2 -0
- atdd-0.1.0.dist-info/licenses/LICENSE +674 -0
- atdd-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test telemetry array migration for uniqueness support.
|
|
3
|
+
|
|
4
|
+
SPEC: .claude/agents/coach/schemas.spec.yaml::telemetry_array_migration
|
|
5
|
+
ID: SPEC-COACH-SCHEMA-0019
|
|
6
|
+
|
|
7
|
+
Validates:
|
|
8
|
+
- Telemetry field accepts array of URNs
|
|
9
|
+
- Backward compatibility with single URN
|
|
10
|
+
- Validation of array entries
|
|
11
|
+
- No URN collision when multiple variants share aspect
|
|
12
|
+
- Complete artifact-level URNs for uniqueness
|
|
13
|
+
|
|
14
|
+
Architecture:
|
|
15
|
+
- Tests validate ProduceItem domain entity behavior
|
|
16
|
+
- Tests validate ManifestParser parsing logic
|
|
17
|
+
- Tests validate TelemetryReconciler validation logic
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import pytest
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from atdd.coach.commands.traceability import (
|
|
23
|
+
ProduceItem,
|
|
24
|
+
ManifestParser,
|
|
25
|
+
TelemetryFile
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ============================================================================
|
|
30
|
+
# Test Fixtures
|
|
31
|
+
# ============================================================================
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture
|
|
35
|
+
def sample_wagon_manifest_with_array_telemetry():
|
|
36
|
+
"""Sample wagon manifest with array telemetry references."""
|
|
37
|
+
return {
|
|
38
|
+
'wagon': 'pace-dilemmas',
|
|
39
|
+
'produce': [
|
|
40
|
+
{
|
|
41
|
+
'name': 'match:dilemma.paired',
|
|
42
|
+
'to': 'external',
|
|
43
|
+
'contract': 'contract:match:dilemma.paired',
|
|
44
|
+
'telemetry': [
|
|
45
|
+
'telemetry:match:dilemma.paired',
|
|
46
|
+
'telemetry:match:pacing.exhausted'
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
'name': 'match:dilemma.current',
|
|
51
|
+
'to': 'external',
|
|
52
|
+
'contract': 'contract:match:dilemma.current',
|
|
53
|
+
'telemetry': [
|
|
54
|
+
'telemetry:match:dilemma.current'
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@pytest.fixture
|
|
62
|
+
def sample_wagon_manifest_with_single_telemetry():
|
|
63
|
+
"""Sample wagon manifest with single URN (backward compatibility)."""
|
|
64
|
+
return {
|
|
65
|
+
'wagon': 'probe-character',
|
|
66
|
+
'produce': [
|
|
67
|
+
{
|
|
68
|
+
'name': 'sensory:character.dialog',
|
|
69
|
+
'to': 'external',
|
|
70
|
+
'contract': 'contract:sensory:character.dialog',
|
|
71
|
+
'telemetry': 'telemetry:sensory:character.dialog'
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.fixture
|
|
78
|
+
def sample_wagon_manifest_with_null_telemetry():
|
|
79
|
+
"""Sample wagon manifest with null telemetry."""
|
|
80
|
+
return {
|
|
81
|
+
'wagon': 'stage-characters',
|
|
82
|
+
'produce': [
|
|
83
|
+
{
|
|
84
|
+
'name': 'sensory:character.expression',
|
|
85
|
+
'to': 'external',
|
|
86
|
+
'contract': 'contract:sensory:character.expression',
|
|
87
|
+
'telemetry': None
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ============================================================================
|
|
94
|
+
# SPEC-COACH-SCHEMA-0019: Telemetry field accepts array of URNs
|
|
95
|
+
# ============================================================================
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@pytest.mark.platform
|
|
99
|
+
def test_telemetry_accepts_array(sample_wagon_manifest_with_array_telemetry):
|
|
100
|
+
"""
|
|
101
|
+
SPEC-COACH-SCHEMA-0019: Telemetry field accepts array of URNs for multiple signals.
|
|
102
|
+
|
|
103
|
+
Given: Wagon has multiple produce items sharing same aspect
|
|
104
|
+
Example: match:dilemma.paired and match:dilemma.current
|
|
105
|
+
Both need separate telemetry URNs for uniqueness
|
|
106
|
+
When: Produce item telemetry field is defined as array
|
|
107
|
+
Then: Telemetry accepts array format: [telemetry:match:dilemma.paired, telemetry:match:dilemma.current]
|
|
108
|
+
Each array entry uses complete artifact-level URN
|
|
109
|
+
No URN collision when multiple variants share aspect
|
|
110
|
+
"""
|
|
111
|
+
parser = ManifestParser()
|
|
112
|
+
produce_items = parser.parse_produce_items(sample_wagon_manifest_with_array_telemetry)
|
|
113
|
+
|
|
114
|
+
# Verify first produce item has array telemetry
|
|
115
|
+
first_item = produce_items[0]
|
|
116
|
+
assert first_item.name == 'match:dilemma.paired'
|
|
117
|
+
assert isinstance(first_item.telemetry_ref, list), "Telemetry should be parsed as list"
|
|
118
|
+
assert len(first_item.telemetry_ref) == 2
|
|
119
|
+
assert 'telemetry:match:dilemma.paired' in first_item.telemetry_ref
|
|
120
|
+
assert 'telemetry:match:pacing.exhausted' in first_item.telemetry_ref
|
|
121
|
+
|
|
122
|
+
# Verify second produce item has array telemetry
|
|
123
|
+
second_item = produce_items[1]
|
|
124
|
+
assert second_item.name == 'match:dilemma.current'
|
|
125
|
+
assert isinstance(second_item.telemetry_ref, list), "Telemetry should be parsed as list"
|
|
126
|
+
assert len(second_item.telemetry_ref) == 1
|
|
127
|
+
assert 'telemetry:match:dilemma.current' in second_item.telemetry_ref
|
|
128
|
+
|
|
129
|
+
# Verify no collision - each has unique URN
|
|
130
|
+
all_urns = first_item.telemetry_ref + second_item.telemetry_ref
|
|
131
|
+
assert 'telemetry:match:dilemma.paired' in all_urns
|
|
132
|
+
assert 'telemetry:match:dilemma.current' in all_urns
|
|
133
|
+
# Both are unique despite sharing aspect 'match:dilemma'
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@pytest.mark.platform
|
|
137
|
+
def test_telemetry_validates_array_entries(sample_wagon_manifest_with_array_telemetry):
|
|
138
|
+
"""
|
|
139
|
+
SPEC-COACH-SCHEMA-0019: Traceability validation checks all array entries exist.
|
|
140
|
+
|
|
141
|
+
Given: Produce item has telemetry array
|
|
142
|
+
When: Validating telemetry references
|
|
143
|
+
Then: Each entry in array is validated
|
|
144
|
+
Each entry must use complete artifact-level URN
|
|
145
|
+
Validation checks all URNs exist in telemetry directory
|
|
146
|
+
"""
|
|
147
|
+
parser = ManifestParser()
|
|
148
|
+
produce_items = parser.parse_produce_items(sample_wagon_manifest_with_array_telemetry)
|
|
149
|
+
|
|
150
|
+
first_item = produce_items[0]
|
|
151
|
+
|
|
152
|
+
# Verify telemetry_ref is list
|
|
153
|
+
assert isinstance(first_item.telemetry_ref, list)
|
|
154
|
+
|
|
155
|
+
# Verify each entry is a complete URN (not null, not empty)
|
|
156
|
+
for telemetry_urn in first_item.telemetry_ref:
|
|
157
|
+
assert telemetry_urn is not None
|
|
158
|
+
assert isinstance(telemetry_urn, str)
|
|
159
|
+
assert telemetry_urn.startswith('telemetry:')
|
|
160
|
+
# Complete artifact-level URN includes variant
|
|
161
|
+
assert ':' in telemetry_urn
|
|
162
|
+
assert '.' in telemetry_urn
|
|
163
|
+
|
|
164
|
+
# Verify no null telemetry when array is present
|
|
165
|
+
assert not first_item.has_null_telemetry_ref
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@pytest.mark.platform
|
|
169
|
+
def test_telemetry_backward_compatible_single_urn(sample_wagon_manifest_with_single_telemetry):
|
|
170
|
+
"""
|
|
171
|
+
SPEC-COACH-SCHEMA-0019: Telemetry accepts single URN for backward compatibility.
|
|
172
|
+
|
|
173
|
+
Given: Wagon manifest has single telemetry URN (not array)
|
|
174
|
+
When: Parsing produce items
|
|
175
|
+
Then: Single URN is treated as single-item array internally
|
|
176
|
+
has_null_telemetry_ref returns False
|
|
177
|
+
Telemetry ref accessible as list for uniform processing
|
|
178
|
+
"""
|
|
179
|
+
parser = ManifestParser()
|
|
180
|
+
produce_items = parser.parse_produce_items(sample_wagon_manifest_with_single_telemetry)
|
|
181
|
+
|
|
182
|
+
item = produce_items[0]
|
|
183
|
+
assert item.name == 'sensory:character.dialog'
|
|
184
|
+
|
|
185
|
+
# Single URN should be converted to list internally for uniform processing
|
|
186
|
+
assert isinstance(item.telemetry_ref, list), "Single URN should be normalized to list"
|
|
187
|
+
assert len(item.telemetry_ref) == 1
|
|
188
|
+
assert item.telemetry_ref[0] == 'telemetry:sensory:character.dialog'
|
|
189
|
+
|
|
190
|
+
# Should not be treated as null
|
|
191
|
+
assert not item.has_null_telemetry_ref
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@pytest.mark.platform
|
|
195
|
+
def test_telemetry_null_handling(sample_wagon_manifest_with_null_telemetry):
|
|
196
|
+
"""
|
|
197
|
+
SPEC-COACH-SCHEMA-0019: Telemetry accepts null for items without telemetry.
|
|
198
|
+
|
|
199
|
+
Given: Produce item has telemetry: null
|
|
200
|
+
When: Parsing produce items
|
|
201
|
+
Then: has_null_telemetry_ref returns True
|
|
202
|
+
telemetry_ref is None or empty list
|
|
203
|
+
"""
|
|
204
|
+
parser = ManifestParser()
|
|
205
|
+
produce_items = parser.parse_produce_items(sample_wagon_manifest_with_null_telemetry)
|
|
206
|
+
|
|
207
|
+
item = produce_items[0]
|
|
208
|
+
assert item.name == 'sensory:character.expression'
|
|
209
|
+
|
|
210
|
+
# Null telemetry should be detected
|
|
211
|
+
assert item.has_null_telemetry_ref
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@pytest.mark.platform
|
|
215
|
+
def test_produce_item_supports_telemetry_array():
|
|
216
|
+
"""
|
|
217
|
+
SPEC-COACH-SCHEMA-0019: ProduceItem entity supports telemetry as array.
|
|
218
|
+
|
|
219
|
+
Given: Need to represent produce item with multiple telemetry URNs
|
|
220
|
+
When: Creating ProduceItem with list telemetry_ref
|
|
221
|
+
Then: ProduceItem stores list correctly
|
|
222
|
+
All properties work with list format
|
|
223
|
+
"""
|
|
224
|
+
item = ProduceItem(
|
|
225
|
+
name='match:dilemma.paired',
|
|
226
|
+
to='external',
|
|
227
|
+
contract_ref='contract:match:dilemma.paired',
|
|
228
|
+
telemetry_ref=['telemetry:match:dilemma.paired', 'telemetry:match:pacing.exhausted'],
|
|
229
|
+
wagon='pace-dilemmas'
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
assert isinstance(item.telemetry_ref, list)
|
|
233
|
+
assert len(item.telemetry_ref) == 2
|
|
234
|
+
assert 'telemetry:match:dilemma.paired' in item.telemetry_ref
|
|
235
|
+
assert not item.has_null_telemetry_ref
|