30.6 KB1215 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3describe('Flowchart v2', () => {
4 it('1: should render a simple flowchart', () => {
5 imgSnapshotTest(
6 `flowchart TD
7 A[Christmas] -->|Get money| B(Go shopping)
8 B --> C{Let me think}
9 C -->|One| D[Laptop]
10 C -->|Two| E[iPhone]
11 C -->|Three| F[fa:fa-car Car]
12 `,
13 {}
14 );
15 });
16
17 it('2: should render a simple flowchart with diagramPadding set to 0', () => {
18 imgSnapshotTest(
19 `flowchart TD
20 A[Christmas] -->|Get money| B(Go shopping)
21 B --> C{Let me think}
22 %% this is a comment
23 C -->|One| D[Laptop]
24 C -->|Two| E[iPhone]
25 C -->|Three| F[fa:fa-car Car]
26 `,
27 { flowchart: { diagramPadding: 0 } }
28 );
29 });
30
31 it('3: a link with correct arrowhead to a subgraph', () => {
32 imgSnapshotTest(
33 `flowchart TD
34 P1
35 P1 -->P1.5
36 subgraph P1.5
37 P2
38 P2.5(( A ))
39 P3
40 end
41 P2 --> P4
42 P3 --> P6
43 P1.5 --> P5
44 `,
45 {}
46 );
47 });
48
49 it('4: Length of edges', () => {
50 imgSnapshotTest(
51 `flowchart TD
52 L1 --- L2
53 L2 --- C
54 M1 ---> C
55 R1 .-> R2
56 R2 <.-> C
57 C -->|Label 1| E1
58 C <-- Label 2 ---> E2
59 C ----> E3
60 C <-...-> E4
61 C ======> E5
62 `,
63 {}
64 );
65 });
66 it('5: should render escaped without html labels', () => {
67 imgSnapshotTest(
68 `flowchart TD
69 a["<strong>Haiya</strong>"]---->b
70 `,
71 { htmlLabels: false, flowchart: { htmlLabels: false } }
72 );
73 });
74 it('6: should render non-escaped with html labels', () => {
75 imgSnapshotTest(
76 `flowchart TD
77 a["<strong>Haiya</strong>"]===>b
78 `,
79 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
80 );
81 });
82 it('6a: should render complex HTML in labels with sandbox security', () => {
83 imgSnapshotTest(
84 `flowchart TD
85 A[Christmas] -->|Get money| B(Go shopping)
86 B --> C{Let me think}
87 C -->|One| D[Laptop]
88 C -->|Two| E[iPhone]
89 C -->|Three| F[fa:fa-car Car]
90 `,
91 { securityLevel: 'sandbox', flowchart: { htmlLabels: true } }
92 );
93 });
94 it('7: should render a flowchart when useMaxWidth is true (default)', () => {
95 renderGraph(
96 `flowchart TD
97 A[Christmas] -->|Get money| B(Go shopping)
98 B --> C{Let me think}
99 C -->|One| D[Laptop]
100 C -->|Two| E[iPhone]
101 C -->|Three| F[fa:fa-car Car]
102 `,
103 { flowchart: { useMaxWidth: true } }
104 );
105 cy.get('svg').should((svg) => {
106 expect(svg).to.have.attr('width', '100%');
107 // expect(svg).to.have.attr('height');
108 // use within because the absolute value can be slightly different depending on the environment ±5%
109 // const height = parseFloat(svg.attr('height'));
110 // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
111 const style = svg.attr('style');
112 expect(style).to.match(/^max-width: [\d.]+px;$/);
113 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
114 expect(maxWidthValue).to.be.within(440 * 0.95, 440 * 1.05);
115 });
116 });
117 it('8: should render a flowchart when useMaxWidth is false', () => {
118 renderGraph(
119 `flowchart TD
120 A[Christmas] -->|Get money| B(Go shopping)
121 B --> C{Let me think}
122 C -->|One| D[Laptop]
123 C -->|Two| E[iPhone]
124 C -->|Three| F[fa:fa-car Car]
125 `,
126 { flowchart: { useMaxWidth: false } }
127 );
128 cy.get('svg').should((svg) => {
129 // const height = parseFloat(svg.attr('height'));
130 const width = parseFloat(svg.attr('width'));
131 // use within because the absolute value can be slightly different depending on the environment ±5%
132 // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
133 expect(width).to.be.within(440 * 0.95, 440 * 1.05);
134 expect(svg).to.not.have.attr('style');
135 });
136 });
137
138 it('V2 - 16: Render Stadium shape', () => {
139 imgSnapshotTest(
140 ` flowchart TD
141 A([stadium shape test])
142 A -->|Get money| B([Go shopping])
143 B --> C([Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?])
144 C -->|One| D([Laptop])
145 C -->|Two| E([iPhone])
146 C -->|Three| F([Car<br/>wroom wroom])
147 click A "index.html#link-clicked" "link test"
148 click B testClick "click test"
149 classDef someclass fill:#f96;
150 class A someclass;
151 class C someclass;
152 `,
153 { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
154 );
155 });
156
157 it('50: handle nested subgraphs in reverse order', () => {
158 imgSnapshotTest(
159 `flowchart LR
160 a -->b
161 subgraph A
162 B
163 end
164 subgraph B
165 b
166 end
167 `,
168 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
169 );
170 });
171
172 it('51: handle nested subgraphs in reverse order', () => {
173 imgSnapshotTest(
174 `flowchart LR
175 a -->b
176 subgraph A
177 B
178 end
179 subgraph B
180 b
181 end
182 `,
183 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
184 );
185 });
186
187 it('52: handle nested subgraphs in several levels.', () => {
188 imgSnapshotTest(
189 `flowchart TB
190 b-->B
191 a-->c
192 subgraph O
193 A
194 end
195 subgraph B
196 c
197 end
198 subgraph A
199 a
200 b
201 B
202 end
203 `,
204 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
205 );
206 });
207
208 it('53: handle nested subgraphs with edges in and out', () => {
209 imgSnapshotTest(
210 `flowchart TB
211 internet
212 nat
213 router
214 lb1
215 lb2
216 compute1
217 compute2
218 subgraph project
219 router
220 nat
221 subgraph subnet1
222 compute1
223 lb1
224 end
225 subgraph subnet2
226 compute2
227 lb2
228 end
229 end
230 internet --> router
231 router --> subnet1 & subnet2
232 subnet1 & subnet2 --> nat --> internet
233 `,
234 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
235 );
236 });
237
238 it('54: handle nested subgraphs with outgoing links', () => {
239 imgSnapshotTest(
240 `flowchart TD
241 subgraph main
242 subgraph subcontainer
243 subcontainer-child
244 end
245 subcontainer-child--> subcontainer-sibling
246 end
247 `,
248 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
249 );
250 });
251
252 it('55: handle nested subgraphs with outgoing links 2', () => {
253 imgSnapshotTest(
254 `flowchart TD
255
256subgraph one[One]
257 subgraph sub_one[Sub One]
258 _sub_one
259 end
260 subgraph sub_two[Sub Two]
261 _sub_two
262 end
263 _one
264end
265
266%% here, either the first or the second one
267sub_one --> sub_two
268_one --> b
269 `,
270 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
271 );
272 });
273
274 it('56: handle nested subgraphs with outgoing links 3', () => {
275 imgSnapshotTest(
276 `flowchart TB
277 subgraph container_Beta
278 process_C-->Process_D
279 end
280 subgraph container_Alpha
281 process_A-->process_B
282 process_A-->|messages|process_C
283 end
284 process_B-->|via_AWSBatch|container_Beta
285 `,
286 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
287 );
288 });
289 it('57: handle nested subgraphs with outgoing links 4', () => {
290 imgSnapshotTest(
291 `flowchart LR
292subgraph A
293a -->b
294end
295subgraph B
296b
297end
298 `,
299 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
300 );
301 });
302
303 it('57: handle nested subgraphs with outgoing links 2', () => {
304 imgSnapshotTest(
305 `flowchart TB
306 c1-->a2
307 subgraph one
308 a1-->a2
309 end
310 subgraph two
311 b1-->b2
312 end
313 subgraph three
314 c1-->c2
315 end
316 one --> two
317 three --> two
318 two --> c2
319 `,
320 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
321 );
322 });
323 it('57.x: handle nested subgraphs with outgoing links 5', () => {
324 imgSnapshotTest(
325 `%% this does not produce the desired result
326flowchart TB
327 subgraph container_Beta
328 process_C-->Process_D
329 end
330 subgraph container_Alpha
331 process_A-->process_B
332 process_B-->|via_AWSBatch|container_Beta
333 process_A-->|messages|process_C
334 end
335 `,
336 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
337 );
338 });
339 it('58: handle styling with style expressions', () => {
340 imgSnapshotTest(
341 `
342 flowchart LR
343 id1(Start)-->id2(Stop)
344 style id1 fill:#f9f,stroke:#333,stroke-width:4px
345 style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
346 `,
347 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
348 );
349 });
350 it('59: handle styling of subgraphs and links', () => {
351 imgSnapshotTest(
352 `
353flowchart TD
354 A[Christmas] ==> D
355 A[Christmas] -->|Get money| B(Go shopping)
356 A[Christmas] ==> C
357 subgraph T ["Test"]
358 A
359 B
360 C
361 end
362
363 classDef Test fill:#F84E68,stroke:#333,color:white;
364 class A,T Test
365 classDef TestSub fill:green;
366 class T TestSub
367 linkStyle 0,1 color:orange, stroke: orange;
368 `,
369 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
370 );
371 });
372 it('60: handle styling for all node shapes - v2', () => {
373 imgSnapshotTest(
374 `
375 flowchart LR
376 A[red text] -->|default style| B(blue text)
377 C([red text]) -->|default style| D[[blue text]]
378 E[(red text)] -->|default style| F((blue text))
379 G>red text] -->|default style| H{blue text}
380 I{{red text}} -->|default style| J[/blue text/]
381 K[\\ red text\\] -->|default style| L[/blue text\\]
382 M[\\ red text/] -->|default style| N[blue text];
383 O(((red text))) -->|default style| P(((blue text)));
384 linkStyle default color:Sienna;
385 style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
386 style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
387 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000;
388 style D stroke:#0000ff,fill:#ccccff,color:#0000ff;
389 style E stroke:#ff0000,fill:#ffcccc,color:#ff0000;
390 style F stroke:#0000ff,fill:#ccccff,color:#0000ff;
391 style G stroke:#ff0000,fill:#ffcccc,color:#ff0000;
392 style H stroke:#0000ff,fill:#ccccff,color:#0000ff;
393 style I stroke:#ff0000,fill:#ffcccc,color:#ff0000;
394 style J stroke:#0000ff,fill:#ccccff,color:#0000ff;
395 style K stroke:#ff0000,fill:#ffcccc,color:#ff0000;
396 style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
397 style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
398 style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
399 style O stroke:#ff0000,fill:#ffcccc,color:#ff0000;
400 style P stroke:#0000ff,fill:#ccccff,color:#0000ff;
401 `,
402 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
403 );
404 });
405 it('61: fontawesome icons in edge labels', () => {
406 imgSnapshotTest(
407 `
408 flowchart TD
409 C -->|fa:fa-car Car| F[fa:fa-car Car]
410 `,
411 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
412 );
413 });
414 it('62: should render styled subgraphs', () => {
415 imgSnapshotTest(
416 `
417 flowchart TB
418 A
419 B
420 subgraph foo[Foo SubGraph]
421 C
422 D
423 end
424 subgraph bar[Bar SubGraph]
425 E
426 F
427 end
428 G
429
430 A-->B
431 B-->C
432 C-->D
433 B-->D
434 D-->E
435 E-->A
436 E-->F
437 F-->D
438 F-->G
439 B-->G
440 G-->D
441
442 style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
443 style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
444 `,
445 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
446 );
447 });
448 it('63: title on subgraphs should be themeable', () => {
449 imgSnapshotTest(
450 `
451 %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
452 flowchart LR
453 subgraph A
454 a --> b
455 end
456 subgraph B
457 i -->f
458 end
459 A --> B
460 `,
461 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
462 );
463 });
464 it('65-1: text-color from classes', () => {
465 imgSnapshotTest(
466 `
467 flowchart LR
468 classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
469 Lorem --> Ipsum --> Dolor
470 class Lorem,Dolor dark
471 `,
472 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
473 );
474 });
475 it('65-2: bold text from classes', () => {
476 imgSnapshotTest(
477 `
478 flowchart
479 classDef cat fill:#f9d5e5, stroke:#233d4d,stroke-width:2px, font-weight:bold;
480 CS(A long bold text to be viewed):::cat
481 `,
482 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
483 );
484 });
485 it('65-3: bigger font from classes', () => {
486 imgSnapshotTest(
487 `
488flowchart
489 Node1:::class1 --> Node2:::class2
490 Node1:::class1 --> Node3:::class2
491 Node3 --> Node4((I am a circle)):::larger
492
493 classDef class1 fill:lightblue
494 classDef class2 fill:pink
495 classDef larger font-size:30px,fill:yellow
496 `,
497 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
498 );
499 });
500 it('66: More nested subgraph cases (TB)', () => {
501 imgSnapshotTest(
502 `
503flowchart TB
504 subgraph two
505 b1
506 end
507 subgraph three
508 c2
509 end
510
511 three --> two
512 two --> c2
513
514 `,
515 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
516 );
517 });
518 it('67: More nested subgraph cases (RL)', () => {
519 imgSnapshotTest(
520 `
521flowchart RL
522 subgraph two
523 b1
524 end
525 subgraph three
526 c2
527 end
528
529 three --> two
530 two --> c2
531
532 `,
533 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
534 );
535 });
536 it('68: More nested subgraph cases (BT)', () => {
537 imgSnapshotTest(
538 `
539flowchart BT
540 subgraph two
541 b1
542 end
543 subgraph three
544 c2
545 end
546
547 three --> two
548 two --> c2
549
550 `,
551 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
552 );
553 });
554 it('69: More nested subgraph cases (LR)', () => {
555 imgSnapshotTest(
556 `
557flowchart LR
558 subgraph two
559 b1
560 end
561 subgraph three
562 c2
563 end
564
565 three --> two
566 two --> c2
567
568 `,
569 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
570 );
571 });
572 it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
573 imgSnapshotTest(
574 `
575flowchart TB
576 subgraph S1
577 sub1 -->sub2
578 end
579 subgraph S2
580 sub4
581 end
582 S1 --> S2
583 sub1 --> sub4
584 `,
585 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
586 );
587 });
588 it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
589 imgSnapshotTest(
590 `
591flowchart RL
592 subgraph S1
593 sub1 -->sub2
594 end
595 subgraph S2
596 sub4
597 end
598 S1 --> S2
599 sub1 --> sub4
600 `,
601 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
602 );
603 });
604 it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
605 imgSnapshotTest(
606 `
607flowchart BT
608 subgraph S1
609 sub1 -->sub2
610 end
611 subgraph S2
612 sub4
613 end
614 S1 --> S2
615 sub1 --> sub4
616 `,
617 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
618 );
619 });
620 it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
621 imgSnapshotTest(
622 `
623flowchart RL
624 subgraph S1
625 sub1 -->sub2
626 end
627 subgraph S2
628 sub4
629 end
630 S1 --> S2
631 sub1 --> sub4
632 `,
633 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
634 );
635 });
636 it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
637 imgSnapshotTest(
638 `
639flowchart RL
640 subgraph one
641 a1 -- l1 --> a2
642 a1 -- l2 --> a2
643 end
644 `,
645 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
646 );
647 });
648
649 it('76: handle unicode encoded character with HTML labels true', () => {
650 imgSnapshotTest(
651 `flowchart TB
652 a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
653 --> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
654 `,
655 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
656 );
657 });
658
659 it('2050: handling of different rendering direction in subgraphs', () => {
660 imgSnapshotTest(
661 `
662 flowchart LR
663
664 subgraph TOP
665 direction TB
666 subgraph B1
667 direction RL
668 i1 -->f1
669 end
670 subgraph B2
671 direction BT
672 i2 -->f2
673 end
674 end
675 A --> TOP --> B
676 B1 --> B2
677 `,
678 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
679 );
680 });
681
682 it('2388: handling default in the node name', () => {
683 imgSnapshotTest(
684 `
685 flowchart LR
686 default-index.js --> dot.template.js
687 index.js --> module-utl.js
688 `,
689 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
690 );
691 });
692 it('2824: Clipping of edges', () => {
693 imgSnapshotTest(
694 `
695 flowchart TD
696 A --> B
697 A --> C
698 B --> C
699 `,
700 { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
701 );
702 });
703 it('1433: should render a titled flowchart with titleTopMargin set to 0', () => {
704 imgSnapshotTest(
705 `---
706title: Simple flowchart
707---
708flowchart TD
709A --> B
710`,
711 { flowchart: { titleTopMargin: 10 } }
712 );
713 });
714 it('3192: It should be possible to render flowcharts with invisible edges', () => {
715 imgSnapshotTest(
716 `---
717title: Simple flowchart with invisible edges
718---
719flowchart TD
720A ~~~ B
721`,
722 { flowchart: { titleTopMargin: 10 } }
723 );
724 });
725 it('4023: Should render html labels with images and-or text correctly', () => {
726 imgSnapshotTest(
727 `flowchart TD
728 B[<img src='https://mermaid.js.org/mermaid-logo.svg'>]
729 B-->C[<img src="https://mermaid.js.org/mermaid-logo.svg"> more text <img src='https://mermaid.js.org/mermaid-logo.svg'>]
730 B-->D(<img src='https://mermaid.js.org/mermaid-logo.svg'> some text)
731 B-->E(plain)`,
732 {}
733 );
734 });
735
736 it('4439: Should render the graph even if some images are missing', () => {
737 imgSnapshotTest(
738 `flowchart TD
739 B[<img>]
740 B-->C[<img>]`,
741 {}
742 );
743 });
744
745 it('5064: Should render when subgraph child has links to outside node and subgraph', () => {
746 imgSnapshotTest(
747 `flowchart TB
748 Out --> In
749 subgraph Sub
750 In
751 end
752 Sub --> In`
753 );
754 });
755
756 it('5059: Should render when subgraph contains only subgraphs, has link to outside and itself is part of a link', () => {
757 imgSnapshotTest(
758 `flowchart
759
760 subgraph Main
761 subgraph Child1
762 Node1
763 Node2
764 end
765 subgraph Child2
766 Node3
767 Node4
768 end
769 end
770 Main --> Out1
771 Child2 --> Out2`
772 );
773 });
774
775 it('3258: Should render subgraphs with main graph nodeSpacing and rankSpacing', () => {
776 imgSnapshotTest(
777 `---
778 title: Subgraph nodeSpacing and rankSpacing example
779 ---
780 flowchart LR
781 X --> Y
782 subgraph X
783 direction LR
784 A
785 C
786 end
787 subgraph Y
788 B
789 D
790 end
791 `,
792 { flowchart: { nodeSpacing: 1, rankSpacing: 1 } }
793 );
794 });
795
796 it('3258: Should render subgraphs with large nodeSpacing and rankSpacing', () => {
797 imgSnapshotTest(
798 `---
799 title: Subgraph nodeSpacing and rankSpacing example
800 config:
801 flowchart:
802 nodeSpacing: 250
803 rankSpacing: 250
804 ---
805 flowchart LR
806 X --> Y
807 subgraph X
808 direction LR
809 A
810 C
811 end
812 subgraph Y
813 B
814 D
815 end
816 `
817 );
818 });
819
820 describe('Markdown strings flowchart (#4220)', () => {
821 describe('html labels', () => {
822 it('With styling and classes', () => {
823 imgSnapshotTest(
824 `%%{init: {"flowchart": {"htmlLabels": true}} }%%
825flowchart LR
826 A:::someclass --> B["\`The **cat** in the hat\`"]:::someclass
827 id1(Start)-->id2(Stop)
828 style id1 fill:#f9f,stroke:#333,stroke-width:4px
829 style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
830 classDef someclass fill:#f96
831`,
832 { flowchart: { titleTopMargin: 0 } }
833 );
834 });
835 it('With formatting in a node', () => {
836 imgSnapshotTest(
837 `%%{init: {"flowchart": {"htmlLabels": true}} }%%
838flowchart LR
839 a{"\`The **cat** in the hat\`"} -- 1o --> b
840 a -- 2o --> c
841 a -- 3o --> d
842 g --2i--> a
843 d --1i--> a
844 h --3i -->a
845 b --> d(The dog in the hog)
846 c --> d
847`,
848 { flowchart: { titleTopMargin: 0 } }
849 );
850 });
851 it('New line in node and formatted edge label', () => {
852 imgSnapshotTest(
853 `%%{init: {"flowchart": {"htmlLabels": true}} }%%
854flowchart LR
855b("\`The dog in **the** hog.(1)
856NL\`") --"\`1o **bold**\`"--> c
857`,
858 { flowchart: { titleTopMargin: 0 } }
859 );
860 });
861 it('Wrapping long text with a new line', () => {
862 imgSnapshotTest(
863 `%%{init: {"flowchart": {"htmlLabels": true}} }%%
864flowchart LR
865b("\`The dog in **the** hog.(1).. a a a a *very long text* about it
866Word!
867
868Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`") --> c
869
870`,
871 { flowchart: { titleTopMargin: 0 } }
872 );
873 });
874 it('Sub graphs and markdown strings', () => {
875 imgSnapshotTest(
876 `%%{init: {"flowchart": {"htmlLabels": true}} }%%
877flowchart LR
878subgraph "One"
879 a("\`The **cat**
880 in the hat\`") -- "1o" --> b{{"\`The **dog** in the hog\`"}}
881end
882subgraph "\`**Two**\`"
883 c("\`The **cat**
884 in the hat\`") -- "\`1o **ipa**\`" --> d("The dog in the hog")
885end
886
887`,
888 { flowchart: { titleTopMargin: 0 } }
889 );
890 });
891 });
892
893 describe('svg text labels', () => {
894 it('With styling and classes', () => {
895 imgSnapshotTest(
896 `%%{init: {"flowchart": {"htmlLabels": false}} }%%
897flowchart LR
898 A:::someclass --> B["\`The **cat** in the hat\`"]:::someclass
899 id1(Start)-->id2(Stop)
900 style id1 fill:#f9f,stroke:#333,stroke-width:4px
901 style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
902 classDef someclass fill:#f96
903`,
904 { flowchart: { titleTopMargin: 0 } }
905 );
906 });
907 it('With formatting in a node', () => {
908 imgSnapshotTest(
909 `%%{init: {"flowchart": {"htmlLabels": false}} }%%
910flowchart LR
911 a{"\`The **cat** in the hat\`"} -- 1o --> b
912 a -- 2o --> c
913 a -- 3o --> d
914 g --2i--> a
915 d --1i--> a
916 h --3i -->a
917 b --> d(The dog in the hog)
918 c --> d
919`,
920 { flowchart: { titleTopMargin: 0 } }
921 );
922 });
923 it('New line in node and formatted edge label', () => {
924 imgSnapshotTest(
925 `%%{init: {"flowchart": {"htmlLabels": false}} }%%
926flowchart LR
927b("\`The dog in **the** hog.(1)
928NL\`") --"\`1o **bold**\`"--> c
929`,
930 { flowchart: { titleTopMargin: 0 } }
931 );
932 });
933 it('Wrapping long text with a new line', () => {
934 imgSnapshotTest(
935 `%%{init: {"flowchart": {"htmlLabels": false}} }%%
936flowchart LR
937b("\`The dog in **the** hog.(1).. a a a a *very long text* about it
938Word!
939
940Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`") --> c
941
942`,
943 { flowchart: { titleTopMargin: 0 } }
944 );
945 });
946 it('Sub graphs and markdown strings', () => {
947 imgSnapshotTest(
948 `%%{init: {"flowchart": {"htmlLabels": false}} }%%
949flowchart LR
950subgraph "One"
951 a("\`The **cat**
952 in the hat\`") -- "1o" --> b{{"\`The **dog** in the hog\`"}}
953end
954subgraph "\`**Two**\`"
955 c("\`The **cat**
956 in the hat\`") -- "\`1o **ipa**\`" --> d("The dog in the hog")
957end
958
959`,
960 { flowchart: { titleTopMargin: 0 } }
961 );
962 });
963 });
964
965 it('should not auto wrap when markdownAutoWrap is false', () => {
966 imgSnapshotTest(
967 `flowchart TD
968 angular_velocity["\`**angular_velocity**
969 *angular_displacement / duration*
970 [rad/s, 1/s]
971 {vector}\`"]
972 frequency["frequency\n(1 / period_duration)\n[Hz, 1/s]"]`,
973 { markdownAutoWrap: false }
974 );
975 });
976 });
977 describe('Subgraph title margins', () => {
978 it('Should render subgraphs with title margins set (LR)', () => {
979 imgSnapshotTest(
980 `flowchart LR
981
982 subgraph TOP
983 direction TB
984 subgraph B1
985 direction RL
986 i1 -->f1
987 end
988 subgraph B2
989 direction BT
990 i2 -->f2
991 end
992 end
993 A --> TOP --> B
994 B1 --> B2
995 `,
996 { flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } } }
997 );
998 });
999 it('Should render subgraphs with title margins set (TD)', () => {
1000 imgSnapshotTest(
1001 `flowchart TD
1002
1003 subgraph TOP
1004 direction LR
1005 subgraph B1
1006 direction RL
1007 i1 -->f1
1008 end
1009 subgraph B2
1010 direction BT
1011 i2 -->f2
1012 end
1013 end
1014 A --> TOP --> B
1015 B1 --> B2
1016 `,
1017 { flowchart: { subGraphTitleMargin: { top: 8, bottom: 16 } } }
1018 );
1019 });
1020 it('Should render subgraphs with title margins set (LR) and htmlLabels set to false', () => {
1021 imgSnapshotTest(
1022 `flowchart LR
1023
1024 subgraph TOP
1025 direction TB
1026 subgraph B1
1027 direction RL
1028 i1 -->f1
1029 end
1030 subgraph B2
1031 direction BT
1032 i2 -->f2
1033 end
1034 end
1035 A --> TOP --> B
1036 B1 --> B2
1037 `,
1038 {
1039 htmlLabels: false,
1040 flowchart: { htmlLabels: false, subGraphTitleMargin: { top: 10, bottom: 5 } },
1041 }
1042 );
1043 });
1044 it('Should render subgraphs with title margins and edge labels', () => {
1045 imgSnapshotTest(
1046 `flowchart LR
1047
1048 subgraph TOP
1049 direction TB
1050 subgraph B1
1051 direction RL
1052 i1 --lb1-->f1
1053 end
1054 subgraph B2
1055 direction BT
1056 i2 --lb2-->f2
1057 end
1058 end
1059 A --lb3--> TOP --lb4--> B
1060 B1 --lb5--> B2
1061 `,
1062 {
1063 flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } },
1064 }
1065 );
1066 });
1067 it('Should render self-loops', () => {
1068 imgSnapshotTest(
1069 `flowchart
1070 A --> A
1071 subgraph B
1072 B1 --> B1
1073 end
1074 subgraph C
1075 subgraph C1
1076 C2 --> C2
1077 subgraph D
1078 D1 --> D1
1079 end
1080 D --> D
1081 end
1082 C1 --> C1
1083 end
1084 `,
1085 {
1086 flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } },
1087 }
1088 );
1089 });
1090 });
1091 describe('New @ syntax for node metadata edge cases', () => {
1092 it('should be possible to use @ syntax to add labels on multi nodes', () => {
1093 imgSnapshotTest(
1094 `flowchart TB
1095 n2["label for n2"] & n4@{ label: "label for n4"} & n5@{ label: "label for n5"}
1096 `,
1097 {}
1098 );
1099 });
1100 it('should be possible to use @ syntax to add labels with trail spaces and &', () => {
1101 imgSnapshotTest(
1102 `flowchart TB
1103 n2["label for n2"] & n4@{ label: "label for n4"} & n5@{ label: "label for n5"}
1104 `,
1105 {}
1106 );
1107 });
1108 it('should be possible to use @ syntax to add labels with trail spaces', () => {
1109 imgSnapshotTest(
1110 `flowchart TB
1111 n2["label for n2"]
1112 n4@{ label: "label for n4"}
1113 n5@{ label: "label for n5"}
1114 `,
1115 {}
1116 );
1117 });
1118 it('should be possible to use @ syntax to add labels with trail spaces and edge/link', () => {
1119 imgSnapshotTest(
1120 `flowchart TD
1121 A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"}
1122 D@{label: "for D"}
1123 `,
1124 {}
1125 );
1126 });
1127 });
1128 describe('Flowchart Node Shape Rendering', () => {
1129 it('should render a stadium-shaped node', () => {
1130 imgSnapshotTest(
1131 `flowchart TB
1132 A(["Start"]) --> n1["Untitled Node"]
1133 A --> n2["Untitled Node"]
1134 `,
1135 {}
1136 );
1137 });
1138 it('should render a diamond-shaped node using shape config', () => {
1139 imgSnapshotTest(
1140 `flowchart BT
1141 n2["Untitled Node"] --> n1["Diamond"]
1142 n1@{ shape: diam}
1143 `,
1144 {}
1145 );
1146 });
1147 it('should render a rounded rectangle and a normal rectangle', () => {
1148 imgSnapshotTest(
1149 `flowchart BT
1150 n2["Untitled Node"] --> n1["Rounded Rectangle"]
1151 n3["Untitled Node"] --> n1
1152 n1@{ shape: rounded}
1153 n3@{ shape: rect}
1154 `,
1155 {}
1156 );
1157 });
1158 });
1159
1160 it('6617: Per Link Curve Styling using edge Ids', () => {
1161 imgSnapshotTest(
1162 `flowchart TD
1163 A e1@-->B e5@--> E
1164 E e7@--> D
1165 B e3@-->D
1166 A e2@-->C e4@-->D
1167 C e6@--> F
1168 F e8@--> D
1169 e1@{ curve: natural }
1170 e2@{ curve: stepAfter }
1171 e3@{ curve: monotoneY }
1172 e4@{ curve: bumpY }
1173 e5@{ curve: linear }
1174 e6@{ curve: catmullRom }
1175 e7@{ curve: cardinal }
1176 `
1177 );
1178 });
1179
1180 describe('when rendering unsuported markdown', () => {
1181 const graph = `flowchart TB
1182 mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
1183 mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
1184 subgraph subgraph1["\`How to fix **fix**\`"]
1185 broken --> B["B"]
1186 end
1187 githost["Github, Gitlab, BitBucket, etc."]
1188 githost2["\`Github, Gitlab, BitBucket, etc.\`"]
1189 a["1."]
1190 b["- x"]
1191 `;
1192
1193 it('should render raw strings', () => {
1194 imgSnapshotTest(graph);
1195 });
1196
1197 it('should render raw strings with htmlLabels: false', () => {
1198 imgSnapshotTest(graph, { htmlLabels: false });
1199 });
1200 });
1201
1202 it('V2 - 17: should apply class def colour to edge label', () => {
1203 imgSnapshotTest(
1204 ` graph LR
1205 id1(Start) link@-- "Label" -->id2(Stop)
1206 style id1 fill:#f9f,stroke:#333,stroke-width:4px
1207
1208class id2 myClass
1209classDef myClass fill:#bbf,stroke:#f66,stroke-width:2px,color:white,stroke-dasharray: 5 5
1210class link myClass
1211`
1212 );
1213 });
1214});
1215