zombie-mermaid 4.2.0 → 4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zombie-mermaid",
3
- "version": "4.2.0",
3
+ "version": "4.2.2",
4
4
  "license": "MIT",
5
5
  "description": "Render Mermaid diagrams as beautiful SVGs or ASCII art. Ultra-fast, fully themeable, zero DOM dependencies. Maintained fork of beautiful-mermaid.",
6
6
  "type": "module",
@@ -90,11 +90,11 @@
90
90
  "@modelcontextprotocol/sdk": "^1.30.0",
91
91
  "elkjs": "^0.11.0",
92
92
  "entities": "^7.0.1",
93
- "@zombie-mermaid/ascii-renderer": "4.2.0",
94
- "@zombie-mermaid/core": "4.2.0",
95
- "@zombie-mermaid/mcp": "4.2.0",
96
- "@zombie-mermaid/svg-renderer": "4.2.0",
97
- "@zombie-mermaid/mermaid-parser": "4.2.0"
93
+ "@zombie-mermaid/ascii-renderer": "4.2.2",
94
+ "@zombie-mermaid/core": "4.2.2",
95
+ "@zombie-mermaid/mermaid-parser": "4.2.2",
96
+ "@zombie-mermaid/svg-renderer": "4.2.2",
97
+ "@zombie-mermaid/mcp": "4.2.2"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@changesets/changelog-github": "^1.0.0",
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Regression tests for #1386: a start marker on its own draws nothing.
3
+ *
4
+ * Mermaid only draws a start marker when the end carries the matching one
5
+ * (`<-->`, `o--o`, `x--x`). `Top <-.- Bot`, `A <--- B` and `A o--- B` parse,
6
+ * but render as a plain line with no marker at all — the marker is dropped,
7
+ * not kept as a lone start arrowhead. Verified against Mermaid 11.17.2:
8
+ *
9
+ * <-.- none / none <-.-> point / point
10
+ * <--- none / none <--> point / point
11
+ * o--- none / none o--o circle / circle
12
+ * o--x none / cross <--x none / cross
13
+ *
14
+ * The two-character bodies (`<--`, `o--`) are not valid Mermaid, so they keep
15
+ * their existing lenient reading and are not covered here.
16
+ */
17
+ import { describe, it, expect } from 'vitest'
18
+ import { parseMermaid } from '@zombie-mermaid/mermaid-parser'
19
+ import { renderMermaidSVG } from '../index.ts'
20
+ import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
21
+
22
+ const edge = (link: string) => parseMermaid(`graph TD\n A ${link} B`).edges[0]!
23
+
24
+ describe('start marker without a matching end marker (#1386)', () => {
25
+ it.each(['<-.-', '<---', '<===', 'o---', 'x---', 'o-.-', 'x-.-'])(
26
+ 'drops the start marker on %s',
27
+ (link) => {
28
+ const e = edge(link)
29
+ expect(e.hasArrowStart).toBe(false)
30
+ expect(e.hasArrowEnd).toBe(false)
31
+ expect(e.startMarker).toBeUndefined()
32
+ },
33
+ )
34
+
35
+ it.each(['<--x', '<-.-x', 'o--x', 'x--o', 'o-.->'])(
36
+ 'drops the start marker but keeps the end marker on %s',
37
+ (link) => {
38
+ const e = edge(link)
39
+ expect(e.hasArrowStart).toBe(false)
40
+ expect(e.startMarker).toBeUndefined()
41
+ expect(e.hasArrowEnd).toBe(true)
42
+ },
43
+ )
44
+
45
+ it.each([
46
+ ['<-->', true, undefined],
47
+ ['<-.->', true, undefined],
48
+ ['<==>', true, undefined],
49
+ ['o--o', true, 'circle'],
50
+ ['x--x', true, 'cross'],
51
+ ] as const)('keeps the start marker on %s', (link, start, kind) => {
52
+ const e = edge(link)
53
+ expect(e.hasArrowStart).toBe(start)
54
+ expect(e.startMarker).toBe(kind)
55
+ expect(e.hasArrowEnd).toBe(true)
56
+ })
57
+
58
+ it('keeps the lenient two-character bodies', () => {
59
+ expect(edge('<--').hasArrowStart).toBe(true)
60
+ expect(edge('<==').hasArrowStart).toBe(true)
61
+ })
62
+ })
63
+
64
+ describe('Top <--> Bot beside Top <-.- Bot (#1386)', () => {
65
+ const source = 'graph TD\n Top <--> Bot\n Top <-.- Bot'
66
+
67
+ it('SVG: the solid edge has both markers, the dotted edge has none', () => {
68
+ const svg = renderMermaidSVG(source)
69
+ const edges = [...svg.matchAll(/<polyline class="edge"[^>]*>/g)].map(
70
+ (m) => m[0],
71
+ )
72
+ expect(edges).toHaveLength(2)
73
+ const [solid, dotted] = edges as [string, string]
74
+ expect(solid).toContain('data-style="solid"')
75
+ expect(solid).toContain('marker-start="url(#arrowhead-start)"')
76
+ expect(solid).toContain('marker-end="url(#arrowhead)"')
77
+ expect(dotted).toContain('data-style="dotted"')
78
+ expect(dotted).not.toContain('marker-start')
79
+ expect(dotted).not.toContain('marker-end')
80
+ })
81
+
82
+ it('ASCII: arrowheads only on the solid edge', () => {
83
+ const ascii = renderMermaidASCII(source, { colorMode: 'none' })
84
+ expect(ascii).toBe(
85
+ [
86
+ '┌─────┐ ',
87
+ '│ │ ',
88
+ '│ Top ├┄┐',
89
+ '│ │ ┆',
90
+ '└──▲──┘ ┆',
91
+ ' │ ┆',
92
+ ' │ ┆',
93
+ ' │ ┆',
94
+ ' │ ┆',
95
+ ' ▼ ┆',
96
+ '┌─────┐ ┆',
97
+ '│ │ ┆',
98
+ '│ Bot │┄┘',
99
+ '│ │ ',
100
+ '└─────┘ ',
101
+ ].join('\n'),
102
+ )
103
+ })
104
+ })