julee 0.1.5__py3-none-any.whl → 0.1.6__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 (105) hide show
  1. julee/docs/sphinx_hcd/__init__.py +146 -13
  2. julee/docs/sphinx_hcd/domain/__init__.py +5 -0
  3. julee/docs/sphinx_hcd/domain/models/__init__.py +32 -0
  4. julee/docs/sphinx_hcd/domain/models/accelerator.py +152 -0
  5. julee/docs/sphinx_hcd/domain/models/app.py +151 -0
  6. julee/docs/sphinx_hcd/domain/models/code_info.py +121 -0
  7. julee/docs/sphinx_hcd/domain/models/epic.py +79 -0
  8. julee/docs/sphinx_hcd/domain/models/integration.py +230 -0
  9. julee/docs/sphinx_hcd/domain/models/journey.py +222 -0
  10. julee/docs/sphinx_hcd/domain/models/persona.py +106 -0
  11. julee/docs/sphinx_hcd/domain/models/story.py +128 -0
  12. julee/docs/sphinx_hcd/domain/repositories/__init__.py +25 -0
  13. julee/docs/sphinx_hcd/domain/repositories/accelerator.py +98 -0
  14. julee/docs/sphinx_hcd/domain/repositories/app.py +57 -0
  15. julee/docs/sphinx_hcd/domain/repositories/base.py +89 -0
  16. julee/docs/sphinx_hcd/domain/repositories/code_info.py +69 -0
  17. julee/docs/sphinx_hcd/domain/repositories/epic.py +62 -0
  18. julee/docs/sphinx_hcd/domain/repositories/integration.py +79 -0
  19. julee/docs/sphinx_hcd/domain/repositories/journey.py +106 -0
  20. julee/docs/sphinx_hcd/domain/repositories/story.py +68 -0
  21. julee/docs/sphinx_hcd/domain/use_cases/__init__.py +64 -0
  22. julee/docs/sphinx_hcd/domain/use_cases/derive_personas.py +166 -0
  23. julee/docs/sphinx_hcd/domain/use_cases/resolve_accelerator_references.py +236 -0
  24. julee/docs/sphinx_hcd/domain/use_cases/resolve_app_references.py +144 -0
  25. julee/docs/sphinx_hcd/domain/use_cases/resolve_story_references.py +121 -0
  26. julee/docs/sphinx_hcd/parsers/__init__.py +48 -0
  27. julee/docs/sphinx_hcd/parsers/ast.py +150 -0
  28. julee/docs/sphinx_hcd/parsers/gherkin.py +155 -0
  29. julee/docs/sphinx_hcd/parsers/yaml.py +184 -0
  30. julee/docs/sphinx_hcd/repositories/__init__.py +4 -0
  31. julee/docs/sphinx_hcd/repositories/memory/__init__.py +25 -0
  32. julee/docs/sphinx_hcd/repositories/memory/accelerator.py +86 -0
  33. julee/docs/sphinx_hcd/repositories/memory/app.py +45 -0
  34. julee/docs/sphinx_hcd/repositories/memory/base.py +106 -0
  35. julee/docs/sphinx_hcd/repositories/memory/code_info.py +59 -0
  36. julee/docs/sphinx_hcd/repositories/memory/epic.py +54 -0
  37. julee/docs/sphinx_hcd/repositories/memory/integration.py +70 -0
  38. julee/docs/sphinx_hcd/repositories/memory/journey.py +96 -0
  39. julee/docs/sphinx_hcd/repositories/memory/story.py +63 -0
  40. julee/docs/sphinx_hcd/sphinx/__init__.py +28 -0
  41. julee/docs/sphinx_hcd/sphinx/adapters.py +116 -0
  42. julee/docs/sphinx_hcd/sphinx/context.py +163 -0
  43. julee/docs/sphinx_hcd/sphinx/directives/__init__.py +160 -0
  44. julee/docs/sphinx_hcd/sphinx/directives/accelerator.py +576 -0
  45. julee/docs/sphinx_hcd/sphinx/directives/app.py +349 -0
  46. julee/docs/sphinx_hcd/sphinx/directives/base.py +211 -0
  47. julee/docs/sphinx_hcd/sphinx/directives/epic.py +434 -0
  48. julee/docs/sphinx_hcd/sphinx/directives/integration.py +220 -0
  49. julee/docs/sphinx_hcd/sphinx/directives/journey.py +642 -0
  50. julee/docs/sphinx_hcd/sphinx/directives/persona.py +345 -0
  51. julee/docs/sphinx_hcd/sphinx/directives/story.py +575 -0
  52. julee/docs/sphinx_hcd/sphinx/event_handlers/__init__.py +16 -0
  53. julee/docs/sphinx_hcd/sphinx/event_handlers/builder_inited.py +31 -0
  54. julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_read.py +27 -0
  55. julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_resolved.py +43 -0
  56. julee/docs/sphinx_hcd/sphinx/event_handlers/env_purge_doc.py +42 -0
  57. julee/docs/sphinx_hcd/sphinx/initialization.py +139 -0
  58. julee/docs/sphinx_hcd/tests/__init__.py +9 -0
  59. julee/docs/sphinx_hcd/tests/conftest.py +6 -0
  60. julee/docs/sphinx_hcd/tests/domain/__init__.py +1 -0
  61. julee/docs/sphinx_hcd/tests/domain/models/__init__.py +1 -0
  62. julee/docs/sphinx_hcd/tests/domain/models/test_accelerator.py +266 -0
  63. julee/docs/sphinx_hcd/tests/domain/models/test_app.py +258 -0
  64. julee/docs/sphinx_hcd/tests/domain/models/test_code_info.py +231 -0
  65. julee/docs/sphinx_hcd/tests/domain/models/test_epic.py +163 -0
  66. julee/docs/sphinx_hcd/tests/domain/models/test_integration.py +327 -0
  67. julee/docs/sphinx_hcd/tests/domain/models/test_journey.py +249 -0
  68. julee/docs/sphinx_hcd/tests/domain/models/test_persona.py +172 -0
  69. julee/docs/sphinx_hcd/tests/domain/models/test_story.py +216 -0
  70. julee/docs/sphinx_hcd/tests/domain/use_cases/__init__.py +1 -0
  71. julee/docs/sphinx_hcd/tests/domain/use_cases/test_derive_personas.py +314 -0
  72. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_accelerator_references.py +476 -0
  73. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_app_references.py +265 -0
  74. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_story_references.py +229 -0
  75. julee/docs/sphinx_hcd/tests/integration/__init__.py +1 -0
  76. julee/docs/sphinx_hcd/tests/parsers/__init__.py +1 -0
  77. julee/docs/sphinx_hcd/tests/parsers/test_ast.py +298 -0
  78. julee/docs/sphinx_hcd/tests/parsers/test_gherkin.py +282 -0
  79. julee/docs/sphinx_hcd/tests/parsers/test_yaml.py +496 -0
  80. julee/docs/sphinx_hcd/tests/repositories/__init__.py +1 -0
  81. julee/docs/sphinx_hcd/tests/repositories/test_accelerator.py +298 -0
  82. julee/docs/sphinx_hcd/tests/repositories/test_app.py +218 -0
  83. julee/docs/sphinx_hcd/tests/repositories/test_base.py +151 -0
  84. julee/docs/sphinx_hcd/tests/repositories/test_code_info.py +253 -0
  85. julee/docs/sphinx_hcd/tests/repositories/test_epic.py +237 -0
  86. julee/docs/sphinx_hcd/tests/repositories/test_integration.py +268 -0
  87. julee/docs/sphinx_hcd/tests/repositories/test_journey.py +294 -0
  88. julee/docs/sphinx_hcd/tests/repositories/test_story.py +236 -0
  89. julee/docs/sphinx_hcd/tests/sphinx/__init__.py +1 -0
  90. julee/docs/sphinx_hcd/tests/sphinx/directives/__init__.py +1 -0
  91. julee/docs/sphinx_hcd/tests/sphinx/directives/test_base.py +160 -0
  92. julee/docs/sphinx_hcd/tests/sphinx/test_adapters.py +176 -0
  93. julee/docs/sphinx_hcd/tests/sphinx/test_context.py +257 -0
  94. {julee-0.1.5.dist-info → julee-0.1.6.dist-info}/METADATA +2 -1
  95. {julee-0.1.5.dist-info → julee-0.1.6.dist-info}/RECORD +98 -13
  96. julee/docs/sphinx_hcd/accelerators.py +0 -1175
  97. julee/docs/sphinx_hcd/apps.py +0 -518
  98. julee/docs/sphinx_hcd/epics.py +0 -453
  99. julee/docs/sphinx_hcd/integrations.py +0 -310
  100. julee/docs/sphinx_hcd/journeys.py +0 -797
  101. julee/docs/sphinx_hcd/personas.py +0 -457
  102. julee/docs/sphinx_hcd/stories.py +0 -960
  103. {julee-0.1.5.dist-info → julee-0.1.6.dist-info}/WHEEL +0 -0
  104. {julee-0.1.5.dist-info → julee-0.1.6.dist-info}/licenses/LICENSE +0 -0
  105. {julee-0.1.5.dist-info → julee-0.1.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,476 @@
1
+ """Tests for resolve_accelerator_references use case."""
2
+
3
+ from julee.docs.sphinx_hcd.domain.models.accelerator import (
4
+ Accelerator,
5
+ IntegrationReference,
6
+ )
7
+ from julee.docs.sphinx_hcd.domain.models.app import App, AppType
8
+ from julee.docs.sphinx_hcd.domain.models.code_info import BoundedContextInfo, ClassInfo
9
+ from julee.docs.sphinx_hcd.domain.models.integration import Direction, Integration
10
+ from julee.docs.sphinx_hcd.domain.models.journey import Journey, JourneyStep
11
+ from julee.docs.sphinx_hcd.domain.models.story import Story
12
+ from julee.docs.sphinx_hcd.domain.use_cases.resolve_accelerator_references import (
13
+ get_accelerator_cross_references,
14
+ get_apps_for_accelerator,
15
+ get_code_info_for_accelerator,
16
+ get_dependent_accelerators,
17
+ get_fed_by_accelerators,
18
+ get_journeys_for_accelerator,
19
+ get_publish_integrations,
20
+ get_source_integrations,
21
+ get_stories_for_accelerator,
22
+ )
23
+
24
+
25
+ def create_accelerator(
26
+ slug: str,
27
+ sources_from: list[str] | None = None,
28
+ publishes_to: list[str] | None = None,
29
+ depends_on: list[str] | None = None,
30
+ feeds_into: list[str] | None = None,
31
+ ) -> Accelerator:
32
+ """Helper to create test accelerators."""
33
+ return Accelerator(
34
+ slug=slug,
35
+ status="active",
36
+ sources_from=[IntegrationReference(slug=s) for s in (sources_from or [])],
37
+ publishes_to=[IntegrationReference(slug=p) for p in (publishes_to or [])],
38
+ depends_on=depends_on or [],
39
+ feeds_into=feeds_into or [],
40
+ )
41
+
42
+
43
+ def create_app(slug: str, accelerators: list[str] | None = None) -> App:
44
+ """Helper to create test apps."""
45
+ kwargs: dict = {
46
+ "slug": slug,
47
+ "name": slug.replace("-", " ").title(),
48
+ "app_type": AppType.STAFF,
49
+ "manifest_path": f"apps/{slug}/app.yaml",
50
+ }
51
+ if accelerators is not None:
52
+ kwargs["accelerators"] = accelerators
53
+ return App(**kwargs)
54
+
55
+
56
+ def create_story(feature_title: str, app_slug: str) -> Story:
57
+ """Helper to create test stories."""
58
+ return Story(
59
+ slug=feature_title.lower().replace(" ", "-"),
60
+ feature_title=feature_title,
61
+ persona="Test User",
62
+ i_want="test",
63
+ so_that="verify",
64
+ app_slug=app_slug,
65
+ file_path="test.feature",
66
+ )
67
+
68
+
69
+ def create_journey(slug: str, story_refs: list[str]) -> Journey:
70
+ """Helper to create test journeys."""
71
+ steps = [JourneyStep.story(ref) for ref in story_refs]
72
+ return Journey(slug=slug, persona="User", steps=steps)
73
+
74
+
75
+ def create_integration(slug: str) -> Integration:
76
+ """Helper to create test integrations."""
77
+ return Integration(
78
+ slug=slug,
79
+ module="test",
80
+ name=slug.replace("-", " ").title(),
81
+ description="Test integration",
82
+ direction=Direction.INBOUND,
83
+ manifest_path=f"integrations/{slug}.yaml",
84
+ )
85
+
86
+
87
+ def create_code_info(slug: str, code_dir: str | None = None) -> BoundedContextInfo:
88
+ """Helper to create test code info."""
89
+ return BoundedContextInfo(
90
+ slug=slug,
91
+ code_dir=code_dir or slug,
92
+ entities=[ClassInfo(name="TestEntity", docstring="Test")],
93
+ )
94
+
95
+
96
+ class TestGetAppsForAccelerator:
97
+ """Test get_apps_for_accelerator function."""
98
+
99
+ def test_find_apps(self) -> None:
100
+ """Test finding apps that expose an accelerator."""
101
+ accelerator = create_accelerator("vocabulary-builder")
102
+ apps = [
103
+ create_app("vocab-app", accelerators=["vocabulary-builder"]),
104
+ create_app("other-app", accelerators=["other-accel"]),
105
+ create_app("multi-app", accelerators=["vocabulary-builder", "other"]),
106
+ ]
107
+
108
+ result = get_apps_for_accelerator(accelerator, apps)
109
+
110
+ assert len(result) == 2
111
+ slugs = {a.slug for a in result}
112
+ assert slugs == {"vocab-app", "multi-app"}
113
+
114
+ def test_no_apps(self) -> None:
115
+ """Test when no apps expose the accelerator."""
116
+ accelerator = create_accelerator("orphan-accel")
117
+ apps = [create_app("app1", accelerators=["other"])]
118
+
119
+ result = get_apps_for_accelerator(accelerator, apps)
120
+
121
+ assert result == []
122
+
123
+ def test_app_no_accelerators(self) -> None:
124
+ """Test apps without accelerators field."""
125
+ accelerator = create_accelerator("test-accel")
126
+ apps = [create_app("plain-app")]
127
+
128
+ result = get_apps_for_accelerator(accelerator, apps)
129
+
130
+ assert result == []
131
+
132
+ def test_sorted_by_slug(self) -> None:
133
+ """Test results are sorted by slug."""
134
+ accelerator = create_accelerator("shared")
135
+ apps = [
136
+ create_app("zebra-app", accelerators=["shared"]),
137
+ create_app("alpha-app", accelerators=["shared"]),
138
+ ]
139
+
140
+ result = get_apps_for_accelerator(accelerator, apps)
141
+
142
+ slugs = [a.slug for a in result]
143
+ assert slugs == ["alpha-app", "zebra-app"]
144
+
145
+
146
+ class TestGetStoriesForAccelerator:
147
+ """Test get_stories_for_accelerator function."""
148
+
149
+ def test_find_stories(self) -> None:
150
+ """Test finding stories from apps that expose accelerator."""
151
+ accelerator = create_accelerator("vocabulary-builder")
152
+ apps = [
153
+ create_app("vocab-app", accelerators=["vocabulary-builder"]),
154
+ create_app("other-app", accelerators=["other"]),
155
+ ]
156
+ stories = [
157
+ create_story("Upload Document", "vocab-app"),
158
+ create_story("Review Vocab", "vocab-app"),
159
+ create_story("Other Feature", "other-app"),
160
+ ]
161
+
162
+ result = get_stories_for_accelerator(accelerator, apps, stories)
163
+
164
+ assert len(result) == 2
165
+ titles = {s.feature_title for s in result}
166
+ assert titles == {"Upload Document", "Review Vocab"}
167
+
168
+ def test_no_apps_no_stories(self) -> None:
169
+ """Test when no apps expose the accelerator."""
170
+ accelerator = create_accelerator("orphan")
171
+ apps = [create_app("app", accelerators=["other"])]
172
+ stories = [create_story("Feature", "app")]
173
+
174
+ result = get_stories_for_accelerator(accelerator, apps, stories)
175
+
176
+ assert result == []
177
+
178
+ def test_sorted_by_feature_title(self) -> None:
179
+ """Test results are sorted by feature title."""
180
+ accelerator = create_accelerator("test")
181
+ apps = [create_app("app", accelerators=["test"])]
182
+ stories = [
183
+ create_story("Zebra Feature", "app"),
184
+ create_story("Alpha Feature", "app"),
185
+ ]
186
+
187
+ result = get_stories_for_accelerator(accelerator, apps, stories)
188
+
189
+ titles = [s.feature_title for s in result]
190
+ assert titles == ["Alpha Feature", "Zebra Feature"]
191
+
192
+
193
+ class TestGetJourneysForAccelerator:
194
+ """Test get_journeys_for_accelerator function."""
195
+
196
+ def test_find_journeys(self) -> None:
197
+ """Test finding journeys containing accelerator's stories."""
198
+ accelerator = create_accelerator("vocab-builder")
199
+ apps = [create_app("vocab-app", accelerators=["vocab-builder"])]
200
+ stories = [create_story("Upload Document", "vocab-app")]
201
+ journeys = [
202
+ create_journey("build-vocab", ["Upload Document"]),
203
+ create_journey("other-journey", ["Other Feature"]),
204
+ ]
205
+
206
+ result = get_journeys_for_accelerator(accelerator, apps, stories, journeys)
207
+
208
+ assert len(result) == 1
209
+ assert result[0].slug == "build-vocab"
210
+
211
+ def test_no_journeys(self) -> None:
212
+ """Test when accelerator's stories are not in any journey."""
213
+ accelerator = create_accelerator("test")
214
+ apps = [create_app("app", accelerators=["test"])]
215
+ stories = [create_story("Lonely Feature", "app")]
216
+ journeys = [create_journey("journey", ["Other Story"])]
217
+
218
+ result = get_journeys_for_accelerator(accelerator, apps, stories, journeys)
219
+
220
+ assert result == []
221
+
222
+ def test_accelerator_with_no_stories(self) -> None:
223
+ """Test when accelerator has no stories at all (no apps use it)."""
224
+ accelerator = create_accelerator("orphan-accelerator")
225
+ apps = [create_app("app", accelerators=["other-accelerator"])]
226
+ stories = [create_story("Some Feature", "app")]
227
+ journeys = [create_journey("journey", ["Some Feature"])]
228
+
229
+ result = get_journeys_for_accelerator(accelerator, apps, stories, journeys)
230
+
231
+ assert result == []
232
+
233
+ def test_sorted_by_slug(self) -> None:
234
+ """Test results are sorted by slug."""
235
+ accelerator = create_accelerator("test")
236
+ apps = [create_app("app", accelerators=["test"])]
237
+ stories = [create_story("Shared Story", "app")]
238
+ journeys = [
239
+ create_journey("zebra-journey", ["Shared Story"]),
240
+ create_journey("alpha-journey", ["Shared Story"]),
241
+ ]
242
+
243
+ result = get_journeys_for_accelerator(accelerator, apps, stories, journeys)
244
+
245
+ slugs = [j.slug for j in result]
246
+ assert slugs == ["alpha-journey", "zebra-journey"]
247
+
248
+
249
+ class TestGetSourceIntegrations:
250
+ """Test get_source_integrations function."""
251
+
252
+ def test_find_sources(self) -> None:
253
+ """Test finding source integrations."""
254
+ accelerator = create_accelerator(
255
+ "vocab-builder",
256
+ sources_from=["kafka", "postgres"],
257
+ )
258
+ integrations = [
259
+ create_integration("kafka"),
260
+ create_integration("postgres"),
261
+ create_integration("redis"),
262
+ ]
263
+
264
+ result = get_source_integrations(accelerator, integrations)
265
+
266
+ assert len(result) == 2
267
+ slugs = {i.slug for i in result}
268
+ assert slugs == {"kafka", "postgres"}
269
+
270
+ def test_no_sources(self) -> None:
271
+ """Test accelerator with no sources."""
272
+ accelerator = create_accelerator("no-sources")
273
+ integrations = [create_integration("kafka")]
274
+
275
+ result = get_source_integrations(accelerator, integrations)
276
+
277
+ assert result == []
278
+
279
+ def test_missing_integration(self) -> None:
280
+ """Test when referenced integration doesn't exist."""
281
+ accelerator = create_accelerator("test", sources_from=["missing"])
282
+ integrations = [create_integration("other")]
283
+
284
+ result = get_source_integrations(accelerator, integrations)
285
+
286
+ assert result == []
287
+
288
+
289
+ class TestGetPublishIntegrations:
290
+ """Test get_publish_integrations function."""
291
+
292
+ def test_find_publish_targets(self) -> None:
293
+ """Test finding publish target integrations."""
294
+ accelerator = create_accelerator(
295
+ "vocab-builder",
296
+ publishes_to=["elasticsearch", "api"],
297
+ )
298
+ integrations = [
299
+ create_integration("elasticsearch"),
300
+ create_integration("api"),
301
+ create_integration("unused"),
302
+ ]
303
+
304
+ result = get_publish_integrations(accelerator, integrations)
305
+
306
+ assert len(result) == 2
307
+ slugs = {i.slug for i in result}
308
+ assert slugs == {"elasticsearch", "api"}
309
+
310
+ def test_no_publish_targets(self) -> None:
311
+ """Test accelerator with no publish targets."""
312
+ accelerator = create_accelerator("no-publish")
313
+ integrations = [create_integration("kafka")]
314
+
315
+ result = get_publish_integrations(accelerator, integrations)
316
+
317
+ assert result == []
318
+
319
+
320
+ class TestGetDependentAccelerators:
321
+ """Test get_dependent_accelerators function."""
322
+
323
+ def test_find_dependents(self) -> None:
324
+ """Test finding accelerators that depend on this one."""
325
+ accelerator = create_accelerator("core-accel")
326
+ accelerators = [
327
+ create_accelerator("dependent-1", depends_on=["core-accel"]),
328
+ create_accelerator("dependent-2", depends_on=["core-accel", "other"]),
329
+ create_accelerator("independent", depends_on=["other"]),
330
+ ]
331
+
332
+ result = get_dependent_accelerators(accelerator, accelerators)
333
+
334
+ assert len(result) == 2
335
+ slugs = {a.slug for a in result}
336
+ assert slugs == {"dependent-1", "dependent-2"}
337
+
338
+ def test_no_dependents(self) -> None:
339
+ """Test when no accelerators depend on this one."""
340
+ accelerator = create_accelerator("leaf-accel")
341
+ accelerators = [create_accelerator("other", depends_on=["different"])]
342
+
343
+ result = get_dependent_accelerators(accelerator, accelerators)
344
+
345
+ assert result == []
346
+
347
+ def test_sorted_by_slug(self) -> None:
348
+ """Test results are sorted by slug."""
349
+ accelerator = create_accelerator("core")
350
+ accelerators = [
351
+ create_accelerator("zebra", depends_on=["core"]),
352
+ create_accelerator("alpha", depends_on=["core"]),
353
+ ]
354
+
355
+ result = get_dependent_accelerators(accelerator, accelerators)
356
+
357
+ slugs = [a.slug for a in result]
358
+ assert slugs == ["alpha", "zebra"]
359
+
360
+
361
+ class TestGetFedByAccelerators:
362
+ """Test get_fed_by_accelerators function."""
363
+
364
+ def test_find_feeders(self) -> None:
365
+ """Test finding accelerators that feed into this one."""
366
+ accelerator = create_accelerator("downstream")
367
+ accelerators = [
368
+ create_accelerator("feeder-1", feeds_into=["downstream"]),
369
+ create_accelerator("feeder-2", feeds_into=["downstream", "other"]),
370
+ create_accelerator("non-feeder", feeds_into=["other"]),
371
+ ]
372
+
373
+ result = get_fed_by_accelerators(accelerator, accelerators)
374
+
375
+ assert len(result) == 2
376
+ slugs = {a.slug for a in result}
377
+ assert slugs == {"feeder-1", "feeder-2"}
378
+
379
+ def test_no_feeders(self) -> None:
380
+ """Test when no accelerators feed into this one."""
381
+ accelerator = create_accelerator("source-accel")
382
+ accelerators = [create_accelerator("other", feeds_into=["different"])]
383
+
384
+ result = get_fed_by_accelerators(accelerator, accelerators)
385
+
386
+ assert result == []
387
+
388
+
389
+ class TestGetCodeInfoForAccelerator:
390
+ """Test get_code_info_for_accelerator function."""
391
+
392
+ def test_exact_match(self) -> None:
393
+ """Test finding code info by exact slug match."""
394
+ accelerator = create_accelerator("vocab-builder")
395
+ code_infos = [
396
+ create_code_info("vocab-builder"),
397
+ create_code_info("other"),
398
+ ]
399
+
400
+ result = get_code_info_for_accelerator(accelerator, code_infos)
401
+
402
+ assert result is not None
403
+ assert result.slug == "vocab-builder"
404
+
405
+ def test_snake_case_match(self) -> None:
406
+ """Test finding code info by snake_case slug match."""
407
+ accelerator = create_accelerator("vocab-builder")
408
+ code_infos = [create_code_info("vocab_builder")]
409
+
410
+ result = get_code_info_for_accelerator(accelerator, code_infos)
411
+
412
+ assert result is not None
413
+ assert result.slug == "vocab_builder"
414
+
415
+ def test_code_dir_match(self) -> None:
416
+ """Test finding code info by code_dir match."""
417
+ accelerator = create_accelerator("vocab-builder")
418
+ code_infos = [create_code_info("different-slug", code_dir="vocab_builder")]
419
+
420
+ result = get_code_info_for_accelerator(accelerator, code_infos)
421
+
422
+ assert result is not None
423
+ assert result.code_dir == "vocab_builder"
424
+
425
+ def test_no_match(self) -> None:
426
+ """Test when no code info matches."""
427
+ accelerator = create_accelerator("unknown")
428
+ code_infos = [create_code_info("other")]
429
+
430
+ result = get_code_info_for_accelerator(accelerator, code_infos)
431
+
432
+ assert result is None
433
+
434
+
435
+ class TestGetAcceleratorCrossReferences:
436
+ """Test get_accelerator_cross_references function."""
437
+
438
+ def test_cross_references(self) -> None:
439
+ """Test getting all cross-references for an accelerator."""
440
+ accelerator = create_accelerator(
441
+ "vocab-builder",
442
+ sources_from=["kafka"],
443
+ publishes_to=["elasticsearch"],
444
+ )
445
+ accelerators = [
446
+ accelerator,
447
+ create_accelerator("dependent", depends_on=["vocab-builder"]),
448
+ create_accelerator("feeder", feeds_into=["vocab-builder"]),
449
+ ]
450
+ apps = [create_app("vocab-app", accelerators=["vocab-builder"])]
451
+ stories = [create_story("Upload Document", "vocab-app")]
452
+ journeys = [create_journey("build-vocab", ["Upload Document"])]
453
+ integrations = [
454
+ create_integration("kafka"),
455
+ create_integration("elasticsearch"),
456
+ ]
457
+ code_infos = [create_code_info("vocab-builder")]
458
+
459
+ result = get_accelerator_cross_references(
460
+ accelerator,
461
+ accelerators,
462
+ apps,
463
+ stories,
464
+ journeys,
465
+ integrations,
466
+ code_infos,
467
+ )
468
+
469
+ assert len(result["apps"]) == 1
470
+ assert len(result["stories"]) == 1
471
+ assert len(result["journeys"]) == 1
472
+ assert len(result["source_integrations"]) == 1
473
+ assert len(result["publish_integrations"]) == 1
474
+ assert len(result["dependents"]) == 1
475
+ assert len(result["fed_by"]) == 1
476
+ assert result["code_info"] is not None