com.wallstop-studios.dxmessaging 2.1.5 → 2.1.6

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 (161) hide show
  1. package/.artifacts/SourceGenerators.Tests/obj/Debug/net9.0/WallstopStudios.DxMessaging.SourceGenerators.Tests.AssemblyInfo.cs +1 -1
  2. package/.cspell.json +4 -1
  3. package/.github/workflows/actionlint.yml +11 -1
  4. package/.github/workflows/csharpier-autofix.yml +34 -3
  5. package/.github/workflows/dotnet-tests.yml +13 -0
  6. package/.github/workflows/format-on-demand.yml +38 -44
  7. package/.github/workflows/json-format-check.yml +24 -0
  8. package/.github/workflows/lint-doc-links.yml +13 -0
  9. package/.github/workflows/markdown-json.yml +21 -4
  10. package/.github/workflows/markdown-link-text-check.yml +10 -0
  11. package/.github/workflows/markdown-link-validity.yml +10 -0
  12. package/.github/workflows/markdownlint.yml +7 -5
  13. package/.github/workflows/prettier-autofix.yml +67 -11
  14. package/.github/workflows/release-drafter.yml +2 -2
  15. package/.github/workflows/sync-wiki.yml +3 -3
  16. package/.github/workflows/yaml-format-lint.yml +26 -0
  17. package/.llm/context.md +113 -3
  18. package/.llm/skills/documentation/changelog-management.md +38 -0
  19. package/.llm/skills/documentation/documentation-style-guide.md +18 -0
  20. package/.llm/skills/documentation/documentation-update-workflow.md +2 -0
  21. package/.llm/skills/documentation/documentation-updates.md +2 -0
  22. package/.llm/skills/documentation/markdown-compatibility.md +476 -0
  23. package/.llm/skills/documentation/mermaid-theming.md +326 -0
  24. package/.llm/skills/documentation/mkdocs-navigation.md +290 -0
  25. package/.llm/skills/github-actions/git-renormalize-patterns.md +231 -0
  26. package/.llm/skills/github-actions/workflow-consistency.md +346 -0
  27. package/.llm/skills/index.md +53 -27
  28. package/.llm/skills/scripting/javascript-code-quality.md +417 -0
  29. package/.llm/skills/scripting/regex-documentation.md +461 -0
  30. package/.llm/skills/scripting/shell-best-practices.md +55 -4
  31. package/.llm/skills/scripting/validation-patterns.md +418 -0
  32. package/.llm/skills/specification.md +4 -1
  33. package/.llm/skills/testing/test-code-quality.md +243 -0
  34. package/.llm/skills/testing/test-production-code.md +348 -0
  35. package/CHANGELOG.md +11 -0
  36. package/README.md +0 -11
  37. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +1 -6
  38. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +1 -1
  39. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +1 -1
  40. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +1 -1
  41. package/coverage/clover.xml +216 -3
  42. package/coverage/clover.xml.meta +7 -7
  43. package/coverage/coverage-final.json +2 -1
  44. package/coverage/coverage-final.json.meta +7 -7
  45. package/coverage/lcov-report/base.css.meta +1 -1
  46. package/coverage/lcov-report/block-navigation.js.meta +1 -1
  47. package/coverage/lcov-report/favicon.png.meta +1 -1
  48. package/coverage/lcov-report/index.html +25 -10
  49. package/coverage/lcov-report/index.html.meta +7 -7
  50. package/coverage/lcov-report/prettify.css.meta +1 -1
  51. package/coverage/lcov-report/prettify.js.meta +1 -1
  52. package/coverage/lcov-report/sort-arrow-sprite.png.meta +1 -1
  53. package/coverage/lcov-report/sorter.js.meta +1 -1
  54. package/coverage/lcov-report/transform-docs-to-wiki.js.html +1 -1
  55. package/coverage/lcov-report/transform-docs-to-wiki.js.html.meta +7 -7
  56. package/coverage/lcov-report/vendor.meta +1 -1
  57. package/coverage/lcov-report.meta +8 -8
  58. package/coverage/lcov.info +365 -0
  59. package/coverage/lcov.info.meta +7 -7
  60. package/docs/architecture/design-and-architecture.md +0 -1
  61. package/docs/concepts/index.md +37 -0
  62. package/docs/concepts/index.md.meta +7 -0
  63. package/docs/concepts/interceptors-and-ordering.md +0 -2
  64. package/docs/concepts/mental-model.md +390 -0
  65. package/docs/concepts/mental-model.md.meta +7 -0
  66. package/docs/concepts/message-types.md +0 -1
  67. package/docs/getting-started/getting-started.md +1 -0
  68. package/docs/getting-started/index.md +6 -5
  69. package/docs/getting-started/overview.md +1 -0
  70. package/docs/getting-started/quick-start.md +2 -1
  71. package/docs/getting-started/visual-guide.md +4 -10
  72. package/docs/hooks.py +10 -1
  73. package/docs/images/DxMessaging-banner.svg +1 -1
  74. package/docs/index.md +7 -7
  75. package/docs/javascripts/mermaid-config.js +44 -4
  76. package/docs/reference/helpers.md +130 -154
  77. package/docs/reference/quick-reference.md +5 -1
  78. package/docs/reference/reference.md +124 -130
  79. package/mkdocs.yml +2 -0
  80. package/package.json +1 -1
  81. package/scripts/__tests__/generate-skills-index.test.js +397 -0
  82. package/scripts/__tests__/generate-skills-index.test.js.meta +7 -0
  83. package/scripts/__tests__/mermaid-config.test.js +467 -0
  84. package/scripts/__tests__/mermaid-config.test.js.meta +7 -0
  85. package/scripts/__tests__/validate-skills-optional-fields.test.js +1474 -0
  86. package/scripts/__tests__/validate-skills-optional-fields.test.js.meta +7 -0
  87. package/scripts/__tests__/validate-skills-required-fields.test.js +188 -0
  88. package/scripts/__tests__/validate-skills-required-fields.test.js.meta +7 -0
  89. package/scripts/__tests__/validate-skills-tags.test.js +353 -0
  90. package/scripts/__tests__/validate-skills-tags.test.js.meta +7 -0
  91. package/scripts/__tests__/validate-workflows.test.js +188 -0
  92. package/scripts/__tests__/validate-workflows.test.js.meta +7 -0
  93. package/scripts/generate-skills-index.js +88 -3
  94. package/scripts/validate-skills.js +230 -30
  95. package/scripts/validate-workflows.js +272 -0
  96. package/scripts/validate-workflows.js.meta +7 -0
  97. package/site/404.html +1 -1
  98. package/site/advanced/emit-shorthands/index.html +2 -2
  99. package/site/advanced/message-bus-providers/index.html +2 -2
  100. package/site/advanced/registration-builders/index.html +2 -2
  101. package/site/advanced/runtime-configuration/index.html +2 -2
  102. package/site/advanced/string-messages/index.html +2 -2
  103. package/site/advanced.meta +1 -1
  104. package/site/architecture/comparisons/index.html +2 -2
  105. package/site/architecture/design-and-architecture/index.html +2 -2
  106. package/site/architecture/performance/index.html +1 -1
  107. package/site/architecture.meta +1 -1
  108. package/site/concepts/index.html +1 -0
  109. package/site/concepts/index.html.meta +7 -0
  110. package/site/concepts/interceptors-and-ordering/index.html +4 -4
  111. package/site/concepts/listening-patterns/index.html +2 -2
  112. package/site/concepts/mental-model/index.html +146 -0
  113. package/site/concepts/mental-model/index.html.meta +7 -0
  114. package/site/concepts/mental-model.meta +8 -0
  115. package/site/concepts/message-types/index.html +2 -2
  116. package/site/concepts/targeting-and-context/index.html +2 -2
  117. package/site/concepts.meta +1 -1
  118. package/site/examples/end-to-end/index.html +2 -2
  119. package/site/examples/end-to-end-scene-transitions/index.html +2 -2
  120. package/site/examples.meta +1 -1
  121. package/site/getting-started/getting-started/index.html +3 -3
  122. package/site/getting-started/index.html +4 -4
  123. package/site/getting-started/install/index.html +3 -3
  124. package/site/getting-started/overview/index.html +2 -2
  125. package/site/getting-started/quick-start/index.html +2 -2
  126. package/site/getting-started/visual-guide/index.html +11 -11
  127. package/site/getting-started.meta +1 -1
  128. package/site/guides/advanced/index.html +2 -2
  129. package/site/guides/diagnostics/index.html +2 -2
  130. package/site/guides/migration-guide/index.html +2 -2
  131. package/site/guides/patterns/index.html +2 -2
  132. package/site/guides/testing/index.html +2 -2
  133. package/site/guides/unity-integration/index.html +2 -2
  134. package/site/guides.meta +1 -1
  135. package/site/hooks.py.meta +1 -1
  136. package/site/images/DxMessaging-banner.svg +119 -0
  137. package/site/images/DxMessaging-banner.svg.meta +7 -0
  138. package/site/images.meta +8 -0
  139. package/site/index.html +2 -2
  140. package/site/integrations/index.html +2 -2
  141. package/site/integrations/reflex/index.html +2 -2
  142. package/site/integrations/vcontainer/index.html +2 -2
  143. package/site/integrations/zenject/index.html +2 -2
  144. package/site/integrations.meta +1 -1
  145. package/site/javascripts/csharp-highlight.js.meta +7 -7
  146. package/site/javascripts/mermaid-config.js +4 -1
  147. package/site/javascripts/mermaid-config.js.meta +1 -1
  148. package/site/javascripts.meta +1 -1
  149. package/site/reference/compatibility/index.html +1 -1
  150. package/site/reference/faq/index.html +1 -1
  151. package/site/reference/glossary/index.html +2 -2
  152. package/site/reference/helpers/index.html +15 -15
  153. package/site/reference/quick-reference/index.html +3 -3
  154. package/site/reference/reference/index.html +37 -37
  155. package/site/reference/troubleshooting/index.html +1 -1
  156. package/site/reference.meta +1 -1
  157. package/site/search/search_index.json +1 -1
  158. package/site/sitemap.xml +46 -38
  159. package/site/sitemap.xml.gz +0 -0
  160. package/site/stylesheets/extra.css.meta +1 -1
  161. package/site/stylesheets.meta +1 -1
@@ -0,0 +1,467 @@
1
+ /**
2
+ * @fileoverview Tests for mermaid-config.js init directive stripping logic.
3
+ *
4
+ * These tests validate the INIT_DIRECTIVE_PATTERN regex and stripInitDirectives function
5
+ * used to remove per-diagram init directives that would override theme configuration.
6
+ * The pattern must handle various edge cases including:
7
+ * - Leading whitespace (spaces and tabs)
8
+ * - Different line ending formats (CRLF vs LF)
9
+ * - Directives at different positions in the file
10
+ * - Multi-line directives
11
+ */
12
+
13
+ "use strict";
14
+
15
+ /**
16
+ * Pattern to match Mermaid init directives that should be stripped.
17
+ *
18
+ * SYNC: Keep pattern in sync with docs/javascripts/mermaid-config.js INIT_DIRECTIVE_PATTERN
19
+ *
20
+ * Regex flags:
21
+ * - 'g' (global): Matches all occurrences
22
+ * - 'i' (case-insensitive): %%{init:...}%% and %%{INIT:...}%% both match
23
+ * - 'm' (multiline): ^ matches start of any line
24
+ * - 's' (dotAll): . matches any character including newlines
25
+ *
26
+ * Uses [ \t]* instead of \s* around the directive to avoid consuming newlines,
27
+ * which would concatenate adjacent diagram lines and break Mermaid syntax.
28
+ */
29
+ const INIT_DIRECTIVE_PATTERN = /^[ \t]*%%\{init:.*?\}%%[ \t]*\r?\n?/gims;
30
+
31
+ /**
32
+ * Strip per-diagram init directives that would override theme configuration.
33
+ *
34
+ * SYNC: Keep logic in sync with docs/javascripts/mermaid-config.js stripInitDirectives
35
+ *
36
+ * @param {string} source - The original Mermaid diagram source
37
+ * @returns {string} The source with init directives removed
38
+ */
39
+ function stripInitDirectives(source) {
40
+ return source.replace(INIT_DIRECTIVE_PATTERN, "");
41
+ }
42
+
43
+ /**
44
+ * Helper to test if a pattern matches an input.
45
+ * Creates a fresh regex to avoid global state issues with lastIndex.
46
+ *
47
+ * Derives the pattern from INIT_DIRECTIVE_PATTERN.source to avoid duplicating
48
+ * the regex literal, ensuring tests always validate the same pattern used by
49
+ * stripInitDirectives().
50
+ *
51
+ * @param {string} input - The input string to test
52
+ * @returns {boolean} Whether the pattern matches
53
+ */
54
+ function testPattern(input) {
55
+ // Create fresh regex from INIT_DIRECTIVE_PATTERN to avoid lastIndex state issues
56
+ // and ensure we're testing the exact same pattern used by stripInitDirectives()
57
+ const pattern = new RegExp(INIT_DIRECTIVE_PATTERN.source, INIT_DIRECTIVE_PATTERN.flags);
58
+ return pattern.test(input);
59
+ }
60
+
61
+ describe("INIT_DIRECTIVE_PATTERN", () => {
62
+ describe("basic directive matching", () => {
63
+ test("should match simple init directive", () => {
64
+ const input = '%%{init: {"theme": "dark"}}%%';
65
+ expect(testPattern(input)).toBe(true);
66
+ });
67
+
68
+ test("should match directive with empty config", () => {
69
+ const input = "%%{init: {}}%%";
70
+ expect(testPattern(input)).toBe(true);
71
+ });
72
+
73
+ test("should match directive with complex theme variables", () => {
74
+ const input =
75
+ '%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#ff0000"}}}%%';
76
+ expect(testPattern(input)).toBe(true);
77
+ });
78
+
79
+ test("should not match non-init directives", () => {
80
+ const input = "%%{config: {}}%%";
81
+ expect(testPattern(input)).toBe(false);
82
+ });
83
+
84
+ test("should not match regular Mermaid comments", () => {
85
+ const input = "%% This is a comment";
86
+ expect(testPattern(input)).toBe(false);
87
+ });
88
+
89
+ test("should not match diagram content without directives", () => {
90
+ const input = "graph TD\n A --> B";
91
+ expect(testPattern(input)).toBe(false);
92
+ });
93
+ });
94
+
95
+ describe("case insensitivity", () => {
96
+ test("should match lowercase init", () => {
97
+ const input = '%%{init: {"theme": "dark"}}%%';
98
+ expect(testPattern(input)).toBe(true);
99
+ });
100
+
101
+ test("should match uppercase INIT", () => {
102
+ const input = '%%{INIT: {"theme": "dark"}}%%';
103
+ expect(testPattern(input)).toBe(true);
104
+ });
105
+
106
+ test("should match mixed case Init", () => {
107
+ const input = '%%{Init: {"theme": "dark"}}%%';
108
+ expect(testPattern(input)).toBe(true);
109
+ });
110
+
111
+ test("should match iNiT with any case variation", () => {
112
+ const input = '%%{iNiT: {"theme": "dark"}}%%';
113
+ expect(testPattern(input)).toBe(true);
114
+ });
115
+ });
116
+
117
+ describe("leading whitespace handling", () => {
118
+ test("should match directive with leading spaces", () => {
119
+ const input = ' %%{init: {"theme": "dark"}}%%';
120
+ expect(testPattern(input)).toBe(true);
121
+ });
122
+
123
+ test("should match directive with leading tab", () => {
124
+ const input = '\t%%{init: {"theme": "dark"}}%%';
125
+ expect(testPattern(input)).toBe(true);
126
+ });
127
+
128
+ test("should match directive with multiple leading tabs", () => {
129
+ const input = '\t\t\t%%{init: {"theme": "dark"}}%%';
130
+ expect(testPattern(input)).toBe(true);
131
+ });
132
+
133
+ test("should match directive with mixed spaces and tabs", () => {
134
+ const input = ' \t \t%%{init: {"theme": "dark"}}%%';
135
+ expect(testPattern(input)).toBe(true);
136
+ });
137
+
138
+ test("should match directive with many leading spaces", () => {
139
+ const input = ' %%{init: {"theme": "dark"}}%%';
140
+ expect(testPattern(input)).toBe(true);
141
+ });
142
+ });
143
+
144
+ describe("line ending handling", () => {
145
+ test("should match directive followed by LF", () => {
146
+ const input = '%%{init: {"theme": "dark"}}%%\n';
147
+ expect(testPattern(input)).toBe(true);
148
+ });
149
+
150
+ test("should match directive followed by CRLF", () => {
151
+ const input = '%%{init: {"theme": "dark"}}%%\r\n';
152
+ expect(testPattern(input)).toBe(true);
153
+ });
154
+
155
+ test("should match directive with no trailing newline", () => {
156
+ const input = '%%{init: {"theme": "dark"}}%%';
157
+ expect(testPattern(input)).toBe(true);
158
+ });
159
+
160
+ test("should match directive with trailing spaces before LF", () => {
161
+ const input = '%%{init: {"theme": "dark"}}%% \n';
162
+ expect(testPattern(input)).toBe(true);
163
+ });
164
+
165
+ test("should match directive with trailing spaces before CRLF", () => {
166
+ const input = '%%{init: {"theme": "dark"}}%% \r\n';
167
+ expect(testPattern(input)).toBe(true);
168
+ });
169
+
170
+ test("should match directive with trailing tab before newline", () => {
171
+ const input = '%%{init: {"theme": "dark"}}%%\t\n';
172
+ expect(testPattern(input)).toBe(true);
173
+ });
174
+ });
175
+
176
+ describe("position in content", () => {
177
+ test("should match directive at start of file", () => {
178
+ const input = '%%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B';
179
+ expect(testPattern(input)).toBe(true);
180
+ });
181
+
182
+ test("should match directive in middle of file with LF", () => {
183
+ const input = 'graph TD\n%%{init: {"theme": "dark"}}%%\n A --> B';
184
+ expect(testPattern(input)).toBe(true);
185
+ });
186
+
187
+ test("should match directive at end of file", () => {
188
+ const input = 'graph TD\n A --> B\n%%{init: {"theme": "dark"}}%%';
189
+ expect(testPattern(input)).toBe(true);
190
+ });
191
+
192
+ test("should match directive after empty line", () => {
193
+ const input = 'graph TD\n\n%%{init: {"theme": "dark"}}%%\n A --> B';
194
+ expect(testPattern(input)).toBe(true);
195
+ });
196
+ });
197
+ });
198
+
199
+ describe("stripInitDirectives", () => {
200
+ beforeEach(() => {
201
+ // Reset the regex lastIndex before each test since it's global
202
+ INIT_DIRECTIVE_PATTERN.lastIndex = 0;
203
+ });
204
+
205
+ describe("single directive removal", () => {
206
+ test("should remove simple init directive", () => {
207
+ const input = '%%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B';
208
+ const expected = "graph TD\n A --> B";
209
+ expect(stripInitDirectives(input)).toBe(expected);
210
+ });
211
+
212
+ test("should remove directive with leading spaces", () => {
213
+ const input = ' %%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B';
214
+ const expected = "graph TD\n A --> B";
215
+ expect(stripInitDirectives(input)).toBe(expected);
216
+ });
217
+
218
+ test("should remove directive with leading tabs", () => {
219
+ const input = '\t%%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B';
220
+ const expected = "graph TD\n A --> B";
221
+ expect(stripInitDirectives(input)).toBe(expected);
222
+ });
223
+
224
+ test("should remove directive with CRLF line ending", () => {
225
+ const input = '%%{init: {"theme": "dark"}}%%\r\ngraph TD\r\n A --> B';
226
+ const expected = "graph TD\r\n A --> B";
227
+ expect(stripInitDirectives(input)).toBe(expected);
228
+ });
229
+
230
+ test("should remove directive with LF line ending", () => {
231
+ const input = '%%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B';
232
+ const expected = "graph TD\n A --> B";
233
+ expect(stripInitDirectives(input)).toBe(expected);
234
+ });
235
+
236
+ test("should handle directive with no trailing newline", () => {
237
+ const input = '%%{init: {"theme": "dark"}}%%';
238
+ const expected = "";
239
+ expect(stripInitDirectives(input)).toBe(expected);
240
+ });
241
+ });
242
+
243
+ describe("multiple directive removal", () => {
244
+ test("should remove multiple init directives with LF", () => {
245
+ const input =
246
+ '%%{init: {"theme": "dark"}}%%\ngraph TD\n%%{init: {"theme": "light"}}%%\n A --> B';
247
+ const expected = "graph TD\n A --> B";
248
+ expect(stripInitDirectives(input)).toBe(expected);
249
+ });
250
+
251
+ test("should remove multiple init directives with CRLF", () => {
252
+ const input =
253
+ '%%{init: {"theme": "dark"}}%%\r\ngraph TD\r\n%%{init: {"theme": "light"}}%%\r\n A --> B';
254
+ const expected = "graph TD\r\n A --> B";
255
+ expect(stripInitDirectives(input)).toBe(expected);
256
+ });
257
+
258
+ test("should remove three consecutive directives", () => {
259
+ const input =
260
+ '%%{init: {"a": 1}}%%\n%%{init: {"b": 2}}%%\n%%{init: {"c": 3}}%%\ngraph TD';
261
+ const expected = "graph TD";
262
+ expect(stripInitDirectives(input)).toBe(expected);
263
+ });
264
+
265
+ test("should remove directives at various positions", () => {
266
+ const input =
267
+ '%%{init: {"start": true}}%%\nsequenceDiagram\n %%{init: {"mid": true}}%%\n Alice->>Bob: Hello\n%%{init: {"end": true}}%%';
268
+ const expected = "sequenceDiagram\n Alice->>Bob: Hello\n";
269
+ expect(stripInitDirectives(input)).toBe(expected);
270
+ });
271
+ });
272
+
273
+ describe("preserving surrounding content", () => {
274
+ test("should preserve content before directive", () => {
275
+ const input = 'graph TD\n%%{init: {"theme": "dark"}}%%\n A --> B';
276
+ const expected = "graph TD\n A --> B";
277
+ expect(stripInitDirectives(input)).toBe(expected);
278
+ });
279
+
280
+ test("should preserve content after directive", () => {
281
+ const input = '%%{init: {"theme": "dark"}}%%\ngraph TD\n A --> B\n B --> C';
282
+ const expected = "graph TD\n A --> B\n B --> C";
283
+ expect(stripInitDirectives(input)).toBe(expected);
284
+ });
285
+
286
+ test("should preserve empty lines around directive", () => {
287
+ const input = 'graph TD\n\n%%{init: {"theme": "dark"}}%%\n\n A --> B';
288
+ const expected = "graph TD\n\n\n A --> B";
289
+ expect(stripInitDirectives(input)).toBe(expected);
290
+ });
291
+
292
+ test("should preserve regular Mermaid comments", () => {
293
+ const input =
294
+ '%%{init: {"theme": "dark"}}%%\ngraph TD\n %% This is a comment\n A --> B';
295
+ const expected = "graph TD\n %% This is a comment\n A --> B";
296
+ expect(stripInitDirectives(input)).toBe(expected);
297
+ });
298
+
299
+ test("should preserve indentation of following content", () => {
300
+ const input = ' %%{init: {"theme": "dark"}}%%\n A --> B';
301
+ const expected = " A --> B";
302
+ expect(stripInitDirectives(input)).toBe(expected);
303
+ });
304
+
305
+ test("should not consume extra newlines", () => {
306
+ const input = '%%{init: {}}%%\n\ngraph TD';
307
+ const expected = "\ngraph TD";
308
+ expect(stripInitDirectives(input)).toBe(expected);
309
+ });
310
+ });
311
+
312
+ describe("edge cases", () => {
313
+ test("should handle empty input", () => {
314
+ const input = "";
315
+ const expected = "";
316
+ expect(stripInitDirectives(input)).toBe(expected);
317
+ });
318
+
319
+ test("should handle input with only whitespace", () => {
320
+ const input = " \n\t\n ";
321
+ const expected = " \n\t\n ";
322
+ expect(stripInitDirectives(input)).toBe(expected);
323
+ });
324
+
325
+ test("should handle input with no init directives", () => {
326
+ const input = "graph TD\n A --> B\n B --> C";
327
+ const expected = "graph TD\n A --> B\n B --> C";
328
+ expect(stripInitDirectives(input)).toBe(expected);
329
+ });
330
+
331
+ test("should handle directive with very long config", () => {
332
+ const longConfig = JSON.stringify({
333
+ theme: "base",
334
+ themeVariables: {
335
+ primaryColor: "#ff0000",
336
+ secondaryColor: "#00ff00",
337
+ tertiaryColor: "#0000ff",
338
+ fontFamily: "Arial, sans-serif",
339
+ fontSize: "16px",
340
+ },
341
+ });
342
+ const input = `%%{init: ${longConfig}}%%\ngraph TD`;
343
+ const expected = "graph TD";
344
+ expect(stripInitDirectives(input)).toBe(expected);
345
+ });
346
+
347
+ test("should handle directive only (no other content)", () => {
348
+ const input = '%%{init: {"theme": "dark"}}%%\n';
349
+ const expected = "";
350
+ expect(stripInitDirectives(input)).toBe(expected);
351
+ });
352
+
353
+ test("should handle mixed CRLF and LF line endings", () => {
354
+ const input = '%%{init: {"a": 1}}%%\r\ngraph TD\n%%{init: {"b": 2}}%%\n A --> B';
355
+ const expected = "graph TD\n A --> B";
356
+ expect(stripInitDirectives(input)).toBe(expected);
357
+ });
358
+
359
+ test("should handle directive with special characters in config", () => {
360
+ const input = '%%{init: {"note": "Hello\\nWorld"}}%%\ngraph TD';
361
+ const expected = "graph TD";
362
+ expect(stripInitDirectives(input)).toBe(expected);
363
+ });
364
+
365
+ test("should handle consecutive spaces in config", () => {
366
+ const input = '%%{init: { "theme" : "dark" } }%%\ngraph TD';
367
+ const expected = "graph TD";
368
+ expect(stripInitDirectives(input)).toBe(expected);
369
+ });
370
+ });
371
+
372
+ describe("multi-line directive handling", () => {
373
+ test("should handle directive split across lines", () => {
374
+ const input = `%%{init: {
375
+ "theme": "dark",
376
+ "themeVariables": {
377
+ "primaryColor": "#ff0000"
378
+ }
379
+ }}%%
380
+ graph TD`;
381
+ const expected = "graph TD";
382
+ expect(stripInitDirectives(input)).toBe(expected);
383
+ });
384
+
385
+ test("should handle directive with CRLF in middle", () => {
386
+ const input = '%%{init: {\r\n "theme": "dark"\r\n}}%%\r\ngraph TD';
387
+ const expected = "graph TD";
388
+ expect(stripInitDirectives(input)).toBe(expected);
389
+ });
390
+
391
+ test("should handle multiple multi-line directives", () => {
392
+ const input = `%%{init: {
393
+ "a": 1
394
+ }}%%
395
+ graph TD
396
+ %%{init: {
397
+ "b": 2
398
+ }}%%
399
+ A --> B`;
400
+ const expected = "graph TD\n A --> B";
401
+ expect(stripInitDirectives(input)).toBe(expected);
402
+ });
403
+ });
404
+
405
+ describe("real-world examples", () => {
406
+ test("should handle typical sequence diagram with theme override", () => {
407
+ const input = `%%{init: {"theme": "dark", "themeVariables": {"actorBkg": "#2d2d2d"}}}%%
408
+ sequenceDiagram
409
+ participant A as Alice
410
+ participant B as Bob
411
+ A->>B: Hello Bob!
412
+ B-->>A: Hi Alice!`;
413
+
414
+ const expected = `sequenceDiagram
415
+ participant A as Alice
416
+ participant B as Bob
417
+ A->>B: Hello Bob!
418
+ B-->>A: Hi Alice!`;
419
+
420
+ expect(stripInitDirectives(input)).toBe(expected);
421
+ });
422
+
423
+ test("should handle flowchart with init directive in code block context", () => {
424
+ const input = `%%{init: {"flowchart": {"htmlLabels": true}}}%%
425
+ graph LR
426
+ A[Start] --> B{Decision}
427
+ B -->|Yes| C[End]
428
+ B -->|No| D[Retry]`;
429
+
430
+ const expected = `graph LR
431
+ A[Start] --> B{Decision}
432
+ B -->|Yes| C[End]
433
+ B -->|No| D[Retry]`;
434
+
435
+ expect(stripInitDirectives(input)).toBe(expected);
436
+ });
437
+
438
+ test("should handle class diagram with configuration", () => {
439
+ const input = `%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#409EFF"}}}%%
440
+ classDiagram
441
+ class Animal {
442
+ +name: string
443
+ +age: int
444
+ +makeSound()
445
+ }
446
+ class Dog {
447
+ +breed: string
448
+ +bark()
449
+ }
450
+ Animal <|-- Dog`;
451
+
452
+ const expected = `classDiagram
453
+ class Animal {
454
+ +name: string
455
+ +age: int
456
+ +makeSound()
457
+ }
458
+ class Dog {
459
+ +breed: string
460
+ +bark()
461
+ }
462
+ Animal <|-- Dog`;
463
+
464
+ expect(stripInitDirectives(input)).toBe(expected);
465
+ });
466
+ });
467
+ });
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 4d8e2f6a1b3c5d7e9f0a2b4c6d8e0f1a
3
+ DefaultImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant: