zombie-mermaid 2.2.1 → 2.2.2
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.
- package/LICENSE +1 -0
- package/README.md +7 -2
- package/dist/ascii.cjs +9 -9
- package/dist/ascii.cjs.map +1 -1
- package/dist/ascii.js +4069 -3969
- package/dist/ascii.js.map +1 -1
- package/dist/cli.js +7605 -7381
- package/dist/index.cjs +52 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7613 -7459
- package/dist/index.js.map +1 -1
- package/dist/mcp.cjs +14142 -13717
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +14142 -13717
- package/dist/mcp.js.map +1 -1
- package/package.json +27 -5
- package/packages/ascii-renderer/LICENSE +22 -0
- package/{src/ascii → packages/ascii-renderer/src}/class-diagram.ts +277 -57
- package/{src/ascii → packages/ascii-renderer/src}/er-diagram.ts +2 -2
- package/packages/ascii-renderer/src/flowchart.ts +94 -0
- package/{src/ascii → packages/ascii-renderer/src}/grid.ts +23 -0
- package/{src/ascii → packages/ascii-renderer/src}/index.ts +13 -84
- package/{src/ascii → packages/ascii-renderer/src}/registry.ts +23 -12
- package/{src/ascii → packages/ascii-renderer/src}/sequence.ts +55 -8
- package/{src/ascii → packages/ascii-renderer/src}/xychart.ts +6 -3
- package/packages/core/LICENSE +22 -0
- package/packages/core/src/click-directive.ts +106 -0
- package/packages/core/src/color-utils.ts +205 -0
- package/packages/core/src/diagram-type.ts +35 -0
- package/packages/core/src/direction-override.ts +46 -0
- package/packages/core/src/direction.ts +56 -0
- package/packages/core/src/index.ts +34 -0
- package/packages/core/src/init-directive.ts +248 -0
- package/packages/core/src/multiline-utils.ts +275 -0
- package/packages/core/src/statements.ts +197 -0
- package/packages/core/src/style-directives.ts +214 -0
- package/packages/core/src/text-metrics.ts +498 -0
- package/packages/core/src/theme.ts +696 -0
- package/packages/core/src/types.ts +670 -0
- package/packages/mcp/LICENSE +22 -0
- package/{src/mcp → packages/mcp/src}/server.ts +34 -2
- package/{src/mcp → packages/mcp/src}/tools/check-sequence-activations.ts +8 -5
- package/packages/mcp/src/tools/fix-sequence-activations.ts +77 -0
- package/{src/mcp → packages/mcp/src}/tools/render-ascii.ts +2 -2
- package/{src/mcp → packages/mcp/src}/tools/render-svg.ts +1 -1
- package/packages/mermaid-parser/LICENSE +22 -0
- package/{src → packages/mermaid-parser/src}/class/parser.ts +86 -8
- package/{src → packages/mermaid-parser/src}/er/parser.ts +59 -26
- package/packages/mermaid-parser/src/index.ts +48 -0
- package/{src → packages/mermaid-parser/src}/sequence/activation-check.ts +4 -3
- package/packages/mermaid-parser/src/sequence/activation-fix.ts +112 -0
- package/{src → packages/mermaid-parser/src}/sequence/parser.ts +74 -16
- package/{src → packages/mermaid-parser/src}/xychart/parser.ts +84 -6
- package/packages/svg-renderer/LICENSE +22 -0
- package/{src → packages/svg-renderer/src}/class/layout.ts +8 -4
- package/{src → packages/svg-renderer/src}/class/renderer.ts +7 -6
- package/packages/svg-renderer/src/edge-curves.ts +204 -0
- package/packages/svg-renderer/src/elk-instance.ts +292 -0
- package/{src → packages/svg-renderer/src}/er/layout.ts +6 -4
- package/{src → packages/svg-renderer/src}/er/renderer.ts +4 -4
- package/packages/svg-renderer/src/index.ts +58 -0
- package/packages/svg-renderer/src/layout-engine/constants.ts +19 -0
- package/packages/svg-renderer/src/layout-engine/edge-bundling.ts +379 -0
- package/packages/svg-renderer/src/layout-engine/elk-adapter-utils.ts +81 -0
- package/packages/svg-renderer/src/layout-engine/elk-graph-builder.ts +240 -0
- package/packages/svg-renderer/src/layout-engine/from-elk.ts +685 -0
- package/packages/svg-renderer/src/layout-engine/layer-alignment.ts +174 -0
- package/packages/svg-renderer/src/layout-engine/to-elk.ts +695 -0
- package/packages/svg-renderer/src/layout-engine.ts +74 -0
- package/packages/svg-renderer/src/layout.ts +8 -0
- package/packages/svg-renderer/src/renderer.ts +1485 -0
- package/packages/svg-renderer/src/resolve-colors.ts +339 -0
- package/{src → packages/svg-renderer/src}/sequence/layout.ts +2 -6
- package/{src → packages/svg-renderer/src}/sequence/renderer.ts +4 -4
- package/packages/svg-renderer/src/shape-clipping.ts +197 -0
- package/packages/svg-renderer/src/styles.ts +118 -0
- package/{src → packages/svg-renderer/src}/xychart/layout.ts +2 -2
- package/{src → packages/svg-renderer/src}/xychart/renderer.ts +6 -6
- package/src/__tests__/ascii-ansi.test.ts +6 -2
- package/src/__tests__/ascii-canvas-write.test.ts +2 -2
- package/src/__tests__/ascii-charset-border-junctions.test.ts +1 -1
- package/src/__tests__/ascii-cjk-width.test.ts +1 -1
- package/src/__tests__/ascii-class-box-occupancy.test.ts +147 -45
- package/src/__tests__/ascii-class-column-width-488-489.test.ts +1 -1
- package/src/__tests__/ascii-class-cross-level-jog-corruption.test.ts +187 -0
- package/src/__tests__/ascii-class-detour-label-routing-487.test.ts +1 -1
- package/src/__tests__/ascii-class-diagram-compartments.test.ts +1 -1
- package/src/__tests__/ascii-class-label-box-collision.test.ts +1 -1
- package/src/__tests__/ascii-class-label-row-collision-531.test.ts +1 -1
- package/src/__tests__/ascii-class-label-territory-row-awareness.test.ts +1 -1
- package/src/__tests__/ascii-class-padding.test.ts +1 -1
- package/src/__tests__/ascii-class-reciprocal-relationships-448.test.ts +86 -1
- package/src/__tests__/ascii-combining-mark-width.test.ts +2 -2
- package/src/__tests__/ascii-coords-overlay.test.ts +2 -2
- package/src/__tests__/ascii-decision-lr-box-start.test.ts +2 -2
- package/src/__tests__/ascii-display-width-unit.test.ts +1 -1
- package/src/__tests__/ascii-draw-arrows-coverage.test.ts +1 -1
- package/src/__tests__/ascii-draw-arrows-single-point-path.test.ts +12 -5
- package/src/__tests__/ascii-draw-bundles.test.ts +5 -5
- package/src/__tests__/ascii-edge-bundling-rank-violation-454.test.ts +1 -1
- package/src/__tests__/ascii-edge-bundling-routing.test.ts +9 -5
- package/src/__tests__/ascii-edge-cross-style-overlap.test.ts +10 -6
- package/src/__tests__/ascii-edge-ending-glyphs.test.ts +1 -1
- package/src/__tests__/ascii-edge-label-diagonal-fallback-418.test.ts +2 -2
- package/src/__tests__/ascii-edge-routing-fixes.test.ts +1 -1
- package/src/__tests__/ascii-edge-routing-single-point-path.test.ts +8 -4
- package/src/__tests__/ascii-edge-styles.test.ts +1 -1
- package/src/__tests__/ascii-emoji-cluster-width.test.ts +2 -2
- package/src/__tests__/ascii-er-box-occupancy.test.ts +1 -1
- package/src/__tests__/ascii-er-cardinality.test.ts +1 -1
- package/src/__tests__/ascii-er-corner-glyphs.test.ts +1 -1
- package/src/__tests__/ascii-er-jog-stray-line.test.ts +1 -1
- package/src/__tests__/ascii-er-label-padding.test.ts +1 -1
- package/src/__tests__/ascii-er-padding.test.ts +1 -1
- package/src/__tests__/ascii-er-relationship-label-corruption-350.test.ts +1 -1
- package/src/__tests__/ascii-er-relationship-overwrite.test.ts +1 -1
- package/src/__tests__/ascii-er-stray-connectors.test.ts +7 -4
- package/src/__tests__/ascii-er-unrelated-stem-separation-411.test.ts +1 -1
- package/src/__tests__/ascii-er-vertical-one-marker.test.ts +1 -1
- package/src/__tests__/ascii-grid-deep-chain.test.ts +4 -4
- package/src/__tests__/ascii-hyperlinks.test.ts +9 -6
- package/src/__tests__/ascii-label-line-terminal-fallback.test.ts +8 -4
- package/src/__tests__/ascii-lane-search.test.ts +1 -1
- package/src/__tests__/ascii-multibox-cjk-width.test.ts +1 -1
- package/src/__tests__/ascii-multiline.test.ts +6 -3
- package/src/__tests__/ascii-nested-subgraph-sibling-order-444.test.ts +8 -5
- package/src/__tests__/ascii-package-boundary.test.ts +47 -37
- package/src/__tests__/ascii-padding-edge-cases.test.ts +1 -1
- package/src/__tests__/ascii-parallel-edges-329.test.ts +8 -5
- package/src/__tests__/ascii-pathfinder-route-edge.test.ts +14 -4
- package/src/__tests__/ascii-reverse-direction-edges-629.test.ts +9 -5
- package/src/__tests__/ascii-sequence-alt-else-label.test.ts +1 -1
- package/src/__tests__/ascii-sequence-block-wall-clearance.test.ts +1 -1
- package/src/__tests__/ascii-sequence-box-group.test.ts +1 -1
- package/src/__tests__/ascii-sequence-cjk-width.test.ts +1 -1
- package/src/__tests__/ascii-sequence-create-destroy.test.ts +1 -1
- package/src/__tests__/ascii-sequence-form-invariants.test.ts +48 -50
- package/src/__tests__/ascii-sequence-mermaid-parity.test.ts +1 -1
- package/src/__tests__/ascii-sequence-notes.test.ts +1 -1
- package/src/__tests__/ascii-sequence-padding.test.ts +1 -1
- package/src/__tests__/ascii-sequence-self-arrow.test.ts +1 -1
- package/src/__tests__/ascii-shape-diamond.test.ts +3 -3
- package/src/__tests__/ascii-shape-rectangle.test.ts +5 -5
- package/src/__tests__/ascii-shape-rounded.test.ts +3 -3
- package/src/__tests__/ascii-shapes-circle.test.ts +3 -3
- package/src/__tests__/ascii-shapes-hexagon.test.ts +3 -3
- package/src/__tests__/ascii-shapes-special.test.ts +10 -5
- package/src/__tests__/ascii-shapes-stadium.test.ts +3 -3
- package/src/__tests__/ascii-shapes-state.test.ts +15 -5
- package/src/__tests__/ascii-state-bidirectional-label-swap-530.test.ts +1 -1
- package/src/__tests__/ascii-subgraph-bbox.test.ts +8 -4
- package/src/__tests__/ascii-subgraph-direction-honored-445.test.ts +1 -1
- package/src/__tests__/ascii-subgraph-label-border-clip.test.ts +88 -25
- package/src/__tests__/ascii-subgraph-later-edgeless-301.test.ts +8 -4
- package/src/__tests__/ascii-subgraph-title-padding.test.ts +1 -1
- package/src/__tests__/ascii-territory-unit.test.ts +2 -2
- package/src/__tests__/ascii-validate.test.ts +1 -1
- package/src/__tests__/ascii.test.ts +5 -2
- package/src/__tests__/box-color.test.ts +1 -1
- package/src/__tests__/class-arrow-directions.test.ts +1 -1
- package/src/__tests__/class-click-interactions.test.ts +3 -6
- package/src/__tests__/class-integration.test.ts +1 -1
- package/src/__tests__/class-notes.test.ts +3 -3
- package/src/__tests__/class-parser-error-messages.test.ts +162 -0
- package/src/__tests__/class-parser.test.ts +6 -6
- package/src/__tests__/class-styling.test.ts +2 -2
- package/src/__tests__/cli-render.test.ts +16 -1
- package/src/__tests__/direction-override.test.ts +1 -1
- package/src/__tests__/draw-lines.test.ts +2 -2
- package/src/__tests__/edge-cell-styles.test.ts +5 -2
- package/src/__tests__/elk-layout-cache.test.ts +6 -4
- package/src/__tests__/er-click-unsupported.test.ts +5 -8
- package/src/__tests__/er-parser-error-messages.test.ts +82 -0
- package/src/__tests__/er-parser.test.ts +3 -6
- package/src/__tests__/expanded-shapes.test.ts +1 -1
- package/src/__tests__/grid-occupancy.test.ts +1 -1
- package/src/__tests__/mcp-check-sequence-activations-tool.test.ts +1 -1
- package/src/__tests__/mcp-fix-sequence-activations-tool.test.ts +134 -0
- package/src/__tests__/mcp-render-ascii-tool.test.ts +5 -4
- package/src/__tests__/mcp-render-svg-theme-guard.test.ts +3 -3
- package/src/__tests__/mcp-render-svg-tool.test.ts +1 -1
- package/src/__tests__/mcp-server.test.ts +30 -1
- package/src/__tests__/multiline-labels.test.ts +29 -18
- package/src/__tests__/parser.test.ts +117 -5
- package/src/__tests__/pathfinder.test.ts +11 -4
- package/src/__tests__/render-options-overrides.test.ts +28 -21
- package/src/__tests__/render-options-per-type.test.ts +13 -9
- package/src/__tests__/resolve-colors.test.ts +1 -1
- package/src/__tests__/self-loop-edges.test.ts +112 -0
- package/src/__tests__/sequence-activation-check.test.ts +7 -8
- package/src/__tests__/sequence-activation-fix.test.ts +91 -0
- package/src/__tests__/sequence-layout.test.ts +4 -7
- package/src/__tests__/sequence-parser-syntax-errors.test.ts +179 -0
- package/src/__tests__/sequence-parser.test.ts +3 -6
- package/src/__tests__/statements.test.ts +53 -35
- package/src/__tests__/testdata/ascii/subgraph_direction_override.txt +21 -21
- package/src/__tests__/theme-palette-contrast.test.ts +84 -0
- package/src/__tests__/workspace-package-boundaries.test.ts +199 -25
- package/src/__tests__/xychart-ascii.test.ts +1 -1
- package/src/__tests__/xychart-colors.test.ts +3 -2
- package/src/__tests__/xychart-layout.test.ts +1 -1
- package/src/__tests__/xychart-parser-errors.test.ts +95 -0
- package/src/browser.ts +8 -2
- package/src/cli/mcp.ts +1 -1
- package/src/cli/render.ts +59 -25
- package/src/cli/web.ts +1 -1
- package/src/diagram-registry.ts +190 -25
- package/src/index.ts +34 -131
- package/src/parser.ts +102 -40
- /package/{src/ascii → packages/ascii-renderer/src}/ansi.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/canvas.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/converter.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/coords.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/display-width.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw-arrows.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw-boxes.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw-bundles.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw-lines.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw-subgraphs.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/draw.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/edge-bundling.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/edge-cell-styles.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/edge-routing.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/grid-occupancy.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/hyperlinks.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/lane-search.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/multiline-utils.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/pathfinder.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/circle.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/corners.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/diamond.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/hexagon.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/index.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/rectangle.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/rounded.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/special.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/stadium.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/state.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/shapes/types.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/territory.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/types.ts +0 -0
- /package/{src/ascii → packages/ascii-renderer/src}/validate.ts +0 -0
- /package/{src/mcp → packages/mcp/src}/index.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/class/format.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/class/types.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/er/types.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/expanded-shapes.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/sequence/box-color.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/sequence/types.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/xychart/colors.ts +0 -0
- /package/{src → packages/mermaid-parser/src}/xychart/types.ts +0 -0
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* migrated call site relies on `write()`'s inclusive bounds).
|
|
19
19
|
*/
|
|
20
20
|
import { describe, it, expect } from 'vitest'
|
|
21
|
-
import { renderMermaidASCII } from '
|
|
21
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
22
22
|
|
|
23
23
|
describe('ASCII subgraph label does not overwrite its own border', () => {
|
|
24
24
|
it('leaves the right border intact when the title is wider than the interior', () => {
|
|
@@ -30,9 +30,12 @@ describe('ASCII subgraph label does not overwrite its own border', () => {
|
|
|
30
30
|
const titleLine = output.split('\n').find((l) => l.includes('AAAAAAA'))
|
|
31
31
|
expect(titleLine).toBeDefined()
|
|
32
32
|
|
|
33
|
-
// The
|
|
34
|
-
//
|
|
35
|
-
|
|
33
|
+
// The box is now widened to fit the title in full (issue #632 — a
|
|
34
|
+
// subgraph label used to be truncated to whatever width the child
|
|
35
|
+
// nodes happened to need, dropping trailing characters), so the title
|
|
36
|
+
// is no longer clipped at all — but the row must still open and close
|
|
37
|
+
// with the border — never spill onto/through it.
|
|
38
|
+
expect(titleLine).toBe('│AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA│')
|
|
36
39
|
expect(titleLine?.startsWith('│')).toBe(true)
|
|
37
40
|
expect(titleLine?.endsWith('│')).toBe(true)
|
|
38
41
|
})
|
|
@@ -62,28 +65,88 @@ describe('ASCII subgraph label does not overwrite its own border', () => {
|
|
|
62
65
|
const output = renderMermaidASCII(mermaid)
|
|
63
66
|
expect(output).toBe(
|
|
64
67
|
[
|
|
65
|
-
'
|
|
66
|
-
'│
|
|
67
|
-
'│
|
|
68
|
-
'│
|
|
69
|
-
'│
|
|
70
|
-
'│
|
|
71
|
-
'│
|
|
72
|
-
'│
|
|
73
|
-
'│
|
|
74
|
-
'│
|
|
75
|
-
'│
|
|
76
|
-
'│
|
|
77
|
-
'│
|
|
78
|
-
'│
|
|
79
|
-
'│
|
|
80
|
-
'│
|
|
81
|
-
'│
|
|
82
|
-
'│
|
|
83
|
-
'│
|
|
84
|
-
'│
|
|
85
|
-
'
|
|
68
|
+
'┌──────────────────────────────────┐',
|
|
69
|
+
'│AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA│',
|
|
70
|
+
'│ │',
|
|
71
|
+
'│ │',
|
|
72
|
+
'│ ┌───┐ │',
|
|
73
|
+
'│ │ │ │',
|
|
74
|
+
'│ │ a │ │',
|
|
75
|
+
'│ │ │ │',
|
|
76
|
+
'│ └─┬─┘ │',
|
|
77
|
+
'│ │ │',
|
|
78
|
+
'│ │ │',
|
|
79
|
+
'│ │ │',
|
|
80
|
+
'│ │ │',
|
|
81
|
+
'│ ▼ │',
|
|
82
|
+
'│ ┌───┐ │',
|
|
83
|
+
'│ │ │ │',
|
|
84
|
+
'│ │ b │ │',
|
|
85
|
+
'│ │ │ │',
|
|
86
|
+
'│ └───┘ │',
|
|
87
|
+
'│ │',
|
|
88
|
+
'└──────────────────────────────────┘',
|
|
86
89
|
].join('\n'),
|
|
87
90
|
)
|
|
88
91
|
})
|
|
89
92
|
})
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Regression test for issue #632 — a weekly form-judge audit comparing this
|
|
96
|
+
* repo's ASCII output against real mermaid.js SVG flagged the "Subgraph
|
|
97
|
+
* Direction Override" sample (samples-data.ts): the cluster label
|
|
98
|
+
* "Processing Pipeline" was truncated mid-word to "Processing Pipe" even
|
|
99
|
+
* though the source SVG's cluster rect is wide enough to fit the full label
|
|
100
|
+
* untruncated.
|
|
101
|
+
*
|
|
102
|
+
* Root cause: `calculateSubgraphBoundingBox` (src/ascii/grid.ts) sized a
|
|
103
|
+
* subgraph's box purely from its child nodes' positions — it never
|
|
104
|
+
* considered the width of the subgraph's own label — so a label longer
|
|
105
|
+
* than the widest child node's contribution to the box got silently
|
|
106
|
+
* clipped by `drawSubgraphLabel`'s own border-safety guard (the fix
|
|
107
|
+
* verified by the tests above, which correctly stops a label from spilling
|
|
108
|
+
* onto the border, but does nothing to stop it needing to spill in the
|
|
109
|
+
* first place). The fix widens the box, symmetrically, whenever the
|
|
110
|
+
* label's own display width would otherwise exceed the interior the child
|
|
111
|
+
* nodes alone would have produced.
|
|
112
|
+
*/
|
|
113
|
+
describe('ASCII subgraph label does not truncate a label wider than its child nodes (issue #632)', () => {
|
|
114
|
+
it('renders "Processing Pipeline" in full instead of truncating it to "Processing Pipe"', () => {
|
|
115
|
+
const mermaid = `graph TD
|
|
116
|
+
subgraph pipeline [Processing Pipeline]
|
|
117
|
+
direction LR
|
|
118
|
+
A[Input] --> B[Parse] --> C[Transform] --> D[Output]
|
|
119
|
+
end
|
|
120
|
+
E[Source] --> A
|
|
121
|
+
D --> F[Sink]`
|
|
122
|
+
const output = renderMermaidASCII(mermaid)
|
|
123
|
+
|
|
124
|
+
expect(output).toContain('Processing Pipeline')
|
|
125
|
+
expect(output).not.toContain('Processing Pipe│')
|
|
126
|
+
expect(output).not.toContain('Processing Pipe\n')
|
|
127
|
+
|
|
128
|
+
const titleLine = output
|
|
129
|
+
.split('\n')
|
|
130
|
+
.find((l) => l.includes('Processing Pipeline'))
|
|
131
|
+
expect(titleLine).toBeDefined()
|
|
132
|
+
// The label sits fully inside the border on both sides, not clipped
|
|
133
|
+
// against (or spilling onto) either one.
|
|
134
|
+
expect(titleLine?.startsWith('│')).toBe(true)
|
|
135
|
+
expect(titleLine?.endsWith('│')).toBe(true)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('still truncates a title far wider than any reasonable box only via the border-safety clip, never mid-word from box sizing alone', () => {
|
|
139
|
+
// A label wider than the box has room for, on a subgraph with only a
|
|
140
|
+
// single tiny child node — the box widens to fit the label (this
|
|
141
|
+
// issue's fix), so nothing is truncated by width sizing; the only
|
|
142
|
+
// remaining clip source is `drawSubgraphLabel`'s own border guard
|
|
143
|
+
// (covered by the tests above), which only fires for pathological
|
|
144
|
+
// cases (e.g. a taller-than-tall label) that this fix does not touch.
|
|
145
|
+
const mermaid = `flowchart TD
|
|
146
|
+
subgraph ONE["A Rather Long Subgraph Title Here"]
|
|
147
|
+
A1["a"]
|
|
148
|
+
end`
|
|
149
|
+
const output = renderMermaidASCII(mermaid)
|
|
150
|
+
expect(output).toContain('A Rather Long Subgraph Title Here')
|
|
151
|
+
})
|
|
152
|
+
})
|
|
@@ -29,10 +29,14 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { describe, it, expect } from 'vitest'
|
|
31
31
|
import { parseMermaid } from '../parser.ts'
|
|
32
|
-
import { convertToAsciiGraph } from '
|
|
33
|
-
import { createMapping } from '
|
|
34
|
-
import { renderMermaidASCII } from '
|
|
35
|
-
import type {
|
|
32
|
+
import { convertToAsciiGraph } from '../../packages/ascii-renderer/src/converter.ts'
|
|
33
|
+
import { createMapping } from '../../packages/ascii-renderer/src/grid.ts'
|
|
34
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
35
|
+
import type {
|
|
36
|
+
AsciiConfig,
|
|
37
|
+
AsciiGraph,
|
|
38
|
+
AsciiSubgraph,
|
|
39
|
+
} from '../../packages/ascii-renderer/src/types.ts'
|
|
36
40
|
|
|
37
41
|
function layoutFlowchart(
|
|
38
42
|
source: string,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* space of left padding whenever the box has any slack at all.
|
|
16
16
|
*/
|
|
17
17
|
import { describe, it, expect } from 'vitest'
|
|
18
|
-
import { renderMermaidASCII } from '
|
|
18
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
19
19
|
|
|
20
20
|
/** Find the line containing a subgraph's rendered title text. */
|
|
21
21
|
function findTitleLine(output: string, title: string): string {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { allocateTerritory } from '
|
|
3
|
-
import type { TerritoryGeometry } from '
|
|
2
|
+
import { allocateTerritory } from '../../packages/ascii-renderer/src/territory.ts'
|
|
3
|
+
import type { TerritoryGeometry } from '../../packages/ascii-renderer/src/territory.ts'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Test items carry their own geometry so the accessor stays trivial and the
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
assertNoDiagonals,
|
|
12
12
|
findOrphanedJunctions,
|
|
13
13
|
hasOrphanedJunctions,
|
|
14
|
-
} from '
|
|
14
|
+
} from '../../packages/ascii-renderer/src/validate.ts'
|
|
15
15
|
|
|
16
16
|
describe('DIAGONAL_CHARS', () => {
|
|
17
17
|
it('exposes ascii, unicode, and combined character sets', () => {
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
* Test data: 44 ASCII files + 22 Unicode files = 66 total.
|
|
9
9
|
*/
|
|
10
10
|
import { describe, it, expect } from 'vitest'
|
|
11
|
-
import { renderMermaidASCII } from '
|
|
12
|
-
import {
|
|
11
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
12
|
+
import {
|
|
13
|
+
hasDiagonalLines,
|
|
14
|
+
DIAGONAL_CHARS,
|
|
15
|
+
} from '../../packages/ascii-renderer/src/validate.ts'
|
|
13
16
|
import { readdirSync, readFileSync } from 'node:fs'
|
|
14
17
|
import { join, dirname } from 'node:path'
|
|
15
18
|
import { fileURLToPath } from 'node:url'
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* whole header is the label. `transparent` is treated as "no colour".
|
|
7
7
|
*/
|
|
8
8
|
import { describe, it, expect } from 'vitest'
|
|
9
|
-
import { isCssColor, parseBoxHeader } from '
|
|
9
|
+
import { isCssColor, parseBoxHeader } from '@zombie-mermaid/mermaid-parser'
|
|
10
10
|
|
|
11
11
|
describe('isCssColor', () => {
|
|
12
12
|
it('recognizes CSS named colours, case-insensitively', () => {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { describe, test, expect } from 'vitest'
|
|
11
|
-
import { renderMermaidASCII } from '
|
|
11
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
12
12
|
|
|
13
13
|
describe('Class Diagram Arrow Directions', () => {
|
|
14
14
|
// ============================================================================
|
|
@@ -10,16 +10,13 @@
|
|
|
10
10
|
* src/__tests__/er-click-unsupported.test.ts for that side of issue #292.
|
|
11
11
|
*/
|
|
12
12
|
import { describe, it, expect } from 'vitest'
|
|
13
|
-
import { parseClassDiagram } from '
|
|
13
|
+
import { parseClassDiagram } from '@zombie-mermaid/mermaid-parser'
|
|
14
|
+
import { splitStatements } from '@zombie-mermaid/core'
|
|
14
15
|
import { renderMermaidSVG } from '../index.ts'
|
|
15
16
|
|
|
16
17
|
/** Helper to parse — preprocesses text the same way index.ts does */
|
|
17
18
|
function parse(text: string) {
|
|
18
|
-
|
|
19
|
-
.split('\n')
|
|
20
|
-
.map((l) => l.trim())
|
|
21
|
-
.filter((l) => l.length > 0 && !l.startsWith('%%'))
|
|
22
|
-
return parseClassDiagram(lines)
|
|
19
|
+
return parseClassDiagram(splitStatements(text))
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
describe('parseClassDiagram – click interactions', () => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { describe, it, expect } from 'vitest'
|
|
5
5
|
import { renderMermaidSVG } from '../index.ts'
|
|
6
|
-
import { renderMermaidASCII } from '
|
|
6
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
7
7
|
|
|
8
8
|
describe('renderMermaidSVG – class diagrams', () => {
|
|
9
9
|
it('renders a basic class diagram to valid SVG', () => {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* directly beside its class with a dashed connector.
|
|
9
9
|
*/
|
|
10
10
|
import { describe, it, expect } from 'vitest'
|
|
11
|
-
import { parseClassDiagram } from '
|
|
12
|
-
import { layoutClassDiagramSync } from '
|
|
11
|
+
import { parseClassDiagram } from '@zombie-mermaid/mermaid-parser'
|
|
12
|
+
import { layoutClassDiagramSync } from '@zombie-mermaid/svg-renderer'
|
|
13
13
|
import { renderMermaidSVG } from '../index.ts'
|
|
14
|
-
import { renderMermaidASCII } from '
|
|
14
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
15
15
|
import { splitStatements } from '@zombie-mermaid/core'
|
|
16
16
|
|
|
17
17
|
/** Parse through the same statement splitter index.ts uses. */
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error-message quality tests for the class diagram parser (issue #761).
|
|
3
|
+
*
|
|
4
|
+
* Before this pass, `parseClassDiagram` had zero `throw`/`Error` statements
|
|
5
|
+
* in the entire file — the only one of the five diagram parsers still in
|
|
6
|
+
* that state after #722 added targeted throws to ER and xychart-beta. A
|
|
7
|
+
* dangling relationship arrow with no target, an unclosed `class X { ... }`
|
|
8
|
+
* body, an unclosed method-signature paren, or a malformed `<<...>>`
|
|
9
|
+
* annotation were all silently dropped or silently mis-parsed, with no
|
|
10
|
+
* indication anything was wrong. These tests assert the parser now throws
|
|
11
|
+
* an actionable error instead, while confirming valid syntax and genuinely
|
|
12
|
+
* unrelated lines are unaffected — mirroring #722's "attempt, then
|
|
13
|
+
* validate" scoping so a line with no relationship-arrow token at all still
|
|
14
|
+
* falls through silently.
|
|
15
|
+
*/
|
|
16
|
+
import { describe, it, expect } from 'vitest'
|
|
17
|
+
import { parseClassDiagram } from '@zombie-mermaid/mermaid-parser'
|
|
18
|
+
import { splitStatements } from '@zombie-mermaid/core'
|
|
19
|
+
|
|
20
|
+
function parse(text: string) {
|
|
21
|
+
return parseClassDiagram(splitStatements(text))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('parseClassDiagram – malformed relationships', () => {
|
|
25
|
+
it('throws on a dangling relationship arrow with no target', () => {
|
|
26
|
+
expect(() =>
|
|
27
|
+
parse(`classDiagram
|
|
28
|
+
Animal <|--`),
|
|
29
|
+
).toThrow(/Malformed class-diagram relationship "Animal <\|--"/)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('throws on an unsupported/garbage arrow shape', () => {
|
|
33
|
+
expect(() =>
|
|
34
|
+
parse(`classDiagram
|
|
35
|
+
Animal <>-- Dog`),
|
|
36
|
+
).toThrow(/Malformed class-diagram relationship/)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('mentions the valid arrow tokens in the message', () => {
|
|
40
|
+
expect(() =>
|
|
41
|
+
parse(`classDiagram
|
|
42
|
+
Animal <|--`),
|
|
43
|
+
).toThrow(/<\|--, <\|\.\., \*--, o--, -->/)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('reports the 1-based line number', () => {
|
|
47
|
+
expect(() =>
|
|
48
|
+
parse(`classDiagram
|
|
49
|
+
class Animal
|
|
50
|
+
Animal <|--`),
|
|
51
|
+
).toThrow(/^Line 3:/)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe('parseClassDiagram – unclosed class body', () => {
|
|
56
|
+
it('throws when a class block is never closed before the diagram ends', () => {
|
|
57
|
+
expect(() =>
|
|
58
|
+
parse(`classDiagram
|
|
59
|
+
class Animal {
|
|
60
|
+
+String name`),
|
|
61
|
+
).toThrow(/Unclosed class body for "Animal"/)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('reports the line the class body opened on, not where the diagram ends', () => {
|
|
65
|
+
expect(() =>
|
|
66
|
+
parse(`classDiagram
|
|
67
|
+
class Animal {
|
|
68
|
+
+String name
|
|
69
|
+
+eat() void`),
|
|
70
|
+
).toThrow(/^Line 2:/)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('parseClassDiagram – malformed method signatures', () => {
|
|
75
|
+
it('throws on an unclosed "(" in a method signature', () => {
|
|
76
|
+
expect(() =>
|
|
77
|
+
parse(`classDiagram
|
|
78
|
+
class Animal {
|
|
79
|
+
+eat(void
|
|
80
|
+
}`),
|
|
81
|
+
).toThrow(/unclosed "\(" in a method signature/)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('throws for the same case on a single-line inline body', () => {
|
|
85
|
+
expect(() => parse('classDiagram\nclass Animal { +eat(void }')).toThrow(
|
|
86
|
+
/unclosed "\(" in a method signature/,
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
describe('parseClassDiagram – malformed annotations', () => {
|
|
92
|
+
it('throws on a multi-line-body annotation missing its closing ">>"', () => {
|
|
93
|
+
expect(() =>
|
|
94
|
+
parse(`classDiagram
|
|
95
|
+
class Shape {
|
|
96
|
+
<<abstract
|
|
97
|
+
}`),
|
|
98
|
+
).toThrow(/Malformed class annotation "<<abstract"/)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('throws on an inline-body annotation missing its closing ">>"', () => {
|
|
102
|
+
expect(() => parse('classDiagram\nclass Shape { <<abstract }')).toThrow(
|
|
103
|
+
/Malformed class annotation/,
|
|
104
|
+
)
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
describe('parseClassDiagram – valid syntax is unaffected', () => {
|
|
109
|
+
it('still parses a fully valid relationship without throwing', () => {
|
|
110
|
+
const d = parse(`classDiagram
|
|
111
|
+
Animal <|-- Dog`)
|
|
112
|
+
expect(d.relationships).toHaveLength(1)
|
|
113
|
+
expect(d.classes.map((c) => c.id).sort()).toEqual(['Animal', 'Dog'])
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('still parses a closed class body with a valid method and annotation', () => {
|
|
117
|
+
const d = parse(`classDiagram
|
|
118
|
+
class Animal {
|
|
119
|
+
<<abstract>>
|
|
120
|
+
+String name
|
|
121
|
+
+eat() void
|
|
122
|
+
}`)
|
|
123
|
+
const animal = d.classes.find((c) => c.id === 'Animal')!
|
|
124
|
+
expect(animal.annotation).toBe('abstract')
|
|
125
|
+
expect(animal.attributes).toHaveLength(1)
|
|
126
|
+
expect(animal.methods).toHaveLength(1)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('still parses a valid inline single-line body', () => {
|
|
130
|
+
const d = parse('classDiagram\nclass Shape { <<interface>> }')
|
|
131
|
+
expect(d.classes[0]!.annotation).toBe('interface')
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('still parses a valid cardinality + label relationship', () => {
|
|
135
|
+
const d = parse('classDiagram\nA "1" --> "*" B : uses')
|
|
136
|
+
expect(d.relationships[0]!.fromCardinality).toBe('1')
|
|
137
|
+
expect(d.relationships[0]!.toCardinality).toBe('*')
|
|
138
|
+
expect(d.relationships[0]!.label).toBe('uses')
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('does not throw for a standalone class declaration with no relationship or body', () => {
|
|
142
|
+
expect(() =>
|
|
143
|
+
parse(`classDiagram
|
|
144
|
+
class Animal`),
|
|
145
|
+
).not.toThrow()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('does not throw for a click line (no arrow token present)', () => {
|
|
149
|
+
expect(() =>
|
|
150
|
+
parse(`classDiagram
|
|
151
|
+
class Animal
|
|
152
|
+
click Animal "https://example.com" "Tooltip"`),
|
|
153
|
+
).not.toThrow()
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('does not throw for a valid inline attribute with a method-shaped default value', () => {
|
|
157
|
+
expect(() =>
|
|
158
|
+
parse(`classDiagram
|
|
159
|
+
Animal : +String name`),
|
|
160
|
+
).not.toThrow()
|
|
161
|
+
})
|
|
162
|
+
})
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
* relationships (all 6 types), cardinality, labels, inline attributes.
|
|
6
6
|
*/
|
|
7
7
|
import { describe, it, expect } from 'vitest'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
parseClassDiagram,
|
|
10
|
+
parseGenericTypes,
|
|
11
|
+
} from '@zombie-mermaid/mermaid-parser'
|
|
12
|
+
import { splitStatements } from '@zombie-mermaid/core'
|
|
9
13
|
|
|
10
14
|
/** Helper to parse — preprocesses text the same way index.ts does */
|
|
11
15
|
function parse(text: string) {
|
|
12
|
-
|
|
13
|
-
.split('\n')
|
|
14
|
-
.map((l) => l.trim())
|
|
15
|
-
.filter((l) => l.length > 0 && !l.startsWith('%%'))
|
|
16
|
-
return parseClassDiagram(lines)
|
|
16
|
+
return parseClassDiagram(splitStatements(text))
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// ============================================================================
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* flowchart ASCII renderer does.
|
|
10
10
|
*/
|
|
11
11
|
import { describe, it, expect } from 'vitest'
|
|
12
|
-
import { parseClassDiagram } from '
|
|
12
|
+
import { parseClassDiagram } from '@zombie-mermaid/mermaid-parser'
|
|
13
13
|
import { parseMermaid } from '../parser.ts'
|
|
14
14
|
import { renderMermaidSVG } from '../index.ts'
|
|
15
|
-
import { renderMermaidASCII } from '
|
|
15
|
+
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Escape regex metacharacters so a value can be interpolated into a
|
|
@@ -6,7 +6,7 @@ import { runRender } from '../cli/render.ts'
|
|
|
6
6
|
import { renderPng } from '../cli/png.ts'
|
|
7
7
|
import { renderMermaidSVG } from '../index.ts'
|
|
8
8
|
import { THEMES } from '@zombie-mermaid/core'
|
|
9
|
-
import { displayWidth } from '
|
|
9
|
+
import { displayWidth } from '../../packages/ascii-renderer/src/display-width.ts'
|
|
10
10
|
import { createMockStdout, renderArgs } from './cli-test-helpers.ts'
|
|
11
11
|
|
|
12
12
|
// ============================================================================
|
|
@@ -312,6 +312,21 @@ describe('runRender – output ergonomics', () => {
|
|
|
312
312
|
expect(mockStdout.output()).not.toContain('<svg')
|
|
313
313
|
expect(await readFile(outputPath, 'utf-8')).toContain('<svg')
|
|
314
314
|
})
|
|
315
|
+
|
|
316
|
+
it('writes nothing when a format resolves to neither stdout nor a file', async () => {
|
|
317
|
+
// Not reachable via the real CLI — parse-args always derives a file path
|
|
318
|
+
// or the stdout marker for --svg/--html/--png (see RenderArgs.output's
|
|
319
|
+
// doc comment) — but runRender doesn't itself enforce that invariant, so
|
|
320
|
+
// construct the args directly to exercise resolveTarget/emit's `skip`
|
|
321
|
+
// branch rather than leaving it untested dead code.
|
|
322
|
+
const inputPath = join(tmpDir, 'diagram.mmd')
|
|
323
|
+
await writeFile(inputPath, SIMPLE_FLOWCHART)
|
|
324
|
+
|
|
325
|
+
const mockStdout = createMockStdout()
|
|
326
|
+
await runRender(renderArgs({ input: inputPath, svg: true }), mockStdout)
|
|
327
|
+
|
|
328
|
+
expect(mockStdout.output()).toBe('')
|
|
329
|
+
})
|
|
315
330
|
})
|
|
316
331
|
|
|
317
332
|
// ============================================================================
|
|
@@ -21,7 +21,7 @@ import { describe, it, expect } from 'vitest'
|
|
|
21
21
|
import { renderMermaidSVG, renderMermaidASCII, parseMermaid } from '../index.ts'
|
|
22
22
|
import { withDirectionOverride } from '@zombie-mermaid/core'
|
|
23
23
|
import type { Direction, RenderOptions } from '@zombie-mermaid/core'
|
|
24
|
-
import type { AsciiRenderOptions } from '
|
|
24
|
+
import type { AsciiRenderOptions } from '@zombie-mermaid/ascii-renderer'
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Top-left corner of the first `<rect>` inside the `<g class="{cls}"
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* directly with hand-built inputs rather than through a full render.
|
|
14
14
|
*/
|
|
15
15
|
import { describe, it, expect } from 'vitest'
|
|
16
|
-
import { drawLine } from '
|
|
17
|
-
import { mkCanvas } from '
|
|
16
|
+
import { drawLine } from '../../packages/ascii-renderer/src/draw-lines.ts'
|
|
17
|
+
import { mkCanvas } from '../../packages/ascii-renderer/src/canvas.ts'
|
|
18
18
|
|
|
19
19
|
describe('drawLine diagonal routing', () => {
|
|
20
20
|
it('routes UpperLeft as a horizontal-then-vertical bend', () => {
|
|
@@ -3,8 +3,11 @@ import {
|
|
|
3
3
|
createEdgeCellStyles,
|
|
4
4
|
findStyleConflict,
|
|
5
5
|
claimPathCells,
|
|
6
|
-
} from '
|
|
7
|
-
import {
|
|
6
|
+
} from '../../packages/ascii-renderer/src/edge-cell-styles.ts'
|
|
7
|
+
import {
|
|
8
|
+
createGrid,
|
|
9
|
+
placeBlock,
|
|
10
|
+
} from '../../packages/ascii-renderer/src/grid-occupancy.ts'
|
|
8
11
|
|
|
9
12
|
describe('edge-cell-styles', () => {
|
|
10
13
|
it('reports no conflict against an empty map', () => {
|
|
@@ -13,17 +13,19 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { describe, it, expect } from 'vitest'
|
|
15
15
|
import { parseMermaid } from '../parser.ts'
|
|
16
|
-
import {
|
|
17
|
-
|
|
16
|
+
import {
|
|
17
|
+
parseClassDiagram,
|
|
18
|
+
parseErDiagram,
|
|
19
|
+
} from '@zombie-mermaid/mermaid-parser'
|
|
18
20
|
import { splitStatements } from '@zombie-mermaid/core'
|
|
19
21
|
import {
|
|
20
22
|
convertToElkFormat,
|
|
21
23
|
layoutGraphSync,
|
|
22
24
|
elkLayoutSync,
|
|
23
25
|
createLayoutCache,
|
|
26
|
+
layoutClassDiagramSync,
|
|
27
|
+
layoutErDiagramSync,
|
|
24
28
|
} from '@zombie-mermaid/svg-renderer'
|
|
25
|
-
import { layoutClassDiagramSync } from '../class/layout.ts'
|
|
26
|
-
import { layoutErDiagramSync } from '../er/layout.ts'
|
|
27
29
|
import { renderMermaidSVG } from '../index.ts'
|
|
28
30
|
|
|
29
31
|
describe('elkLayoutSync layout cache', () => {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* unimplemented (issue #292).
|
|
4
4
|
*
|
|
5
5
|
* Unlike flowcharts/state diagrams (src/parser.ts) and class diagrams
|
|
6
|
-
* (src/class/parser.ts, added alongside this file —
|
|
7
|
-
* class-click-interactions.test.ts), Mermaid's *own* erDiagram grammar has
|
|
6
|
+
* (packages/mermaid-parser/src/class/parser.ts, added alongside this file —
|
|
7
|
+
* see class-click-interactions.test.ts), Mermaid's *own* erDiagram grammar has
|
|
8
8
|
* no `click` directive to parse: as of this writing, upstream support is an
|
|
9
9
|
* open, unmerged feature request (mermaid-js/mermaid#2880, PR #6985), not a
|
|
10
10
|
* shipped part of the language. Guessing at a syntax Mermaid itself hasn't
|
|
@@ -18,16 +18,13 @@
|
|
|
18
18
|
* neither renders a link/tooltip nor corrupts the rest of the diagram.
|
|
19
19
|
*/
|
|
20
20
|
import { describe, it, expect } from 'vitest'
|
|
21
|
-
import { parseErDiagram } from '
|
|
21
|
+
import { parseErDiagram } from '@zombie-mermaid/mermaid-parser'
|
|
22
|
+
import { splitStatements } from '@zombie-mermaid/core'
|
|
22
23
|
import { renderMermaidSVG } from '../index.ts'
|
|
23
24
|
|
|
24
25
|
/** Helper to parse — preprocesses text the same way index.ts does */
|
|
25
26
|
function parse(text: string) {
|
|
26
|
-
|
|
27
|
-
.split('\n')
|
|
28
|
-
.map((l) => l.trim())
|
|
29
|
-
.filter((l) => l.length > 0 && !l.startsWith('%%'))
|
|
30
|
-
return parseErDiagram(lines)
|
|
27
|
+
return parseErDiagram(splitStatements(text))
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
describe('parseErDiagram – click statements are a no-op', () => {
|