18.4 KB835 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3describe('State diagram', () => {
4 it('v2 should render a simple info', () => {
5 imgSnapshotTest(
6 `
7 info
8 `,
9 { logLevel: 1, fontFamily: 'courier' }
10 );
11 });
12 it('v2 should render a simple state diagrams', () => {
13 imgSnapshotTest(
14 `
15 stateDiagram-v2
16
17 [*] --> State1
18 State1 --> [*]
19 `,
20 { logLevel: 0, fontFamily: 'courier' }
21 );
22 });
23 it('v2 should render a long descriptions instead of id when available', () => {
24 imgSnapshotTest(
25 `
26 stateDiagram-v2
27
28 [*] --> S1
29 state "Some long name" as S1
30 `,
31 { logLevel: 0, fontFamily: 'courier' }
32 );
33 });
34 it('v2 should render a long descriptions with additional descriptions', () => {
35 imgSnapshotTest(
36 `
37 stateDiagram-v2
38
39 [*] --> S1
40 state "Some long name" as S1: The description
41 `,
42 { logLevel: 0, fontFamily: 'courier' }
43 );
44 });
45 it('v2 should render a single state with short descriptions', () => {
46 imgSnapshotTest(
47 `
48 stateDiagram-v2
49 state "A long long name" as long1
50 state "A" as longlonglongid
51 `,
52 { logLevel: 0, fontFamily: 'courier' }
53 );
54 });
55 it('v2 should render a transition descriptions with new lines', () => {
56 imgSnapshotTest(
57 `
58 stateDiagram-v2
59
60 [*] --> S1
61 S1 --> S2: long line using<br/>should work
62 S1 --> S3: long line using <br>should work
63 S1 --> S4: long line using \\nshould work
64 `,
65 { logLevel: 0, fontFamily: 'courier' }
66 );
67 });
68 it('v2 should render a state with a note', () => {
69 imgSnapshotTest(
70 `
71 stateDiagram-v2
72 State1: The state with a note
73 note right of State1
74 Important information! You can write
75 notes.
76 end note
77 `,
78 { logLevel: 0, fontFamily: 'courier' }
79 );
80 });
81 it('v2 should render a state with on the left side when so specified', () => {
82 imgSnapshotTest(
83 `
84 stateDiagram-v2
85 State1: The state with a note with minus - and plus + in it
86 note left of State1
87 Important information! You can write
88 notes with . and in them.
89 end note
90 `,
91 { logLevel: 0, fontFamily: 'courier' }
92 );
93 });
94 it('v2 should render a state with a note together with another state', () => {
95 imgSnapshotTest(
96 `
97 stateDiagram-v2
98 State1: The state with a note +,-
99 note right of State1
100 Important information! You can write +,-
101 notes.
102 end note
103 State1 --> State2 : With +,-
104 note left of State2 : This is the note +,-<br/>
105 `,
106 { logLevel: 0, fontFamily: 'courier' }
107 );
108 });
109 it('v2 should render a note with multiple lines in it', () => {
110 imgSnapshotTest(
111 `
112 stateDiagram-v2
113 State1: The state with a note
114 note right of State1
115 Important information! You\ncan write
116 notes with multiple lines...
117 Here is another line...
118 And another line...
119 end note
120 `,
121 { logLevel: 0, fontFamily: 'courier' }
122 );
123 });
124 it('v2 should handle multiline notes with different line breaks', () => {
125 imgSnapshotTest(
126 `
127 stateDiagram-v2
128 State1
129 note right of State1
130 Line1<br>Line2<br/>Line3<br />Line4<br />Line5
131 end note
132 `,
133 { logLevel: 0, fontFamily: 'courier' }
134 );
135 });
136
137 it('v2 should render a states with descriptions including multi-line descriptions', () => {
138 imgSnapshotTest(
139 `
140 stateDiagram-v2
141 State1: This a single line description
142 State2: This a multi line description
143 State2: here comes the multi part
144 [*] --> State1
145 State1 --> State2
146 State2 --> [*]
147 `,
148 { logLevel: 0, fontFamily: 'courier' }
149 );
150 });
151 it('v2 should render a simple state diagrams 2', () => {
152 imgSnapshotTest(
153 `
154 stateDiagram-v2
155 [*] --> State1
156 State1 --> State2
157 State1 --> State3
158 State1 --> [*]
159 `,
160 { logLevel: 0, fontFamily: 'courier' }
161 );
162 });
163 it('v2 should render a simple state diagrams with labels', () => {
164 imgSnapshotTest(
165 `
166 stateDiagram-v2
167 [*] --> State1
168 State1 --> State2 : Transition 1
169 State1 --> State3 : Transition 2
170 State1 --> State4 : Transition 3
171 State1 --> State5 : Transition 4
172 State2 --> State3 : Transition 5
173 State1 --> [*]
174 `,
175 { logLevel: 0, fontFamily: 'courier' }
176 );
177 });
178 it('v2 should render state descriptions', () => {
179 imgSnapshotTest(
180 `
181 stateDiagram-v2
182 state "Long state description" as XState1
183 state "Another Long state description" as XState2
184 XState2 : New line
185 XState1 --> XState2
186 `,
187 { logLevel: 0, fontFamily: 'courier' }
188 );
189 });
190 it('v2 should render composite states', () => {
191 imgSnapshotTest(
192 `
193 stateDiagram-v2
194 [*] --> NotShooting: Pacifist
195 NotShooting --> A
196 NotShooting --> B
197 NotShooting --> C
198
199 state NotShooting {
200 [*] --> Idle: Yet another long long öong öong öong label
201 Idle --> Configuring : EvConfig
202 Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
203 }
204 `,
205 { logLevel: 0, fontFamily: 'courier' }
206 );
207 });
208 it('v2 should render multiple composite states', () => {
209 imgSnapshotTest(
210 `
211 stateDiagram-v2
212 [*]-->TV
213
214 state TV {
215 [*] --> Off: Off to start with
216 On --> Off : Turn off
217 Off --> On : Turn on
218 }
219
220 TV--> Console
221
222 state Console {
223 [*] --> Off2: Off to start with
224 On2--> Off2 : Turn off
225 Off2 --> On2 : Turn on
226 On2-->Playing
227
228 state Playing {
229 Alive --> Dead
230 Dead-->Alive
231 }
232 }
233 `,
234 { logLevel: 0, fontFamily: 'courier' }
235 );
236 });
237 it('v2 should render forks in composite states', () => {
238 imgSnapshotTest(
239 `
240 stateDiagram-v2
241 [*]-->TV
242
243 state TV {
244 state fork_state &lt;&lt;fork&gt;&gt;
245 [*] --> fork_state
246 fork_state --> State2
247 fork_state --> State3
248
249 state join_state &lt;&lt;join&gt;&gt;
250 State2 --> join_state
251 State3 --> join_state
252 join_state --> State4
253 State4 --> [*]
254 }
255 `,
256 { logLevel: 0, fontFamily: 'courier' }
257 );
258 });
259 it('v2 should render forks and joins', () => {
260 imgSnapshotTest(
261 `
262 stateDiagram-v2
263 state fork_state &lt;&lt;fork&gt;&gt;
264 [*] --> fork_state
265 fork_state --> State2
266 fork_state --> State3
267
268 state join_state &lt;&lt;join&gt;&gt;
269 State2 --> join_state
270 State3 --> join_state
271 join_state --> State4
272 State4 --> [*]
273 `,
274 { logLevel: 0, fontFamily: 'courier' }
275 );
276 });
277 it('v2 should render concurrency states', () => {
278 imgSnapshotTest(
279 `
280 stateDiagram-v2
281 [*] --> Active
282
283 state Active {
284 [*] --> NumLockOff
285 NumLockOff --> NumLockOn : EvNumLockPressed
286 NumLockOn --> NumLockOff : EvNumLockPressed
287 --
288 [*] --> CapsLockOff
289 CapsLockOff --> CapsLockOn : EvCapsLockPressed
290 CapsLockOn --> CapsLockOff : EvCapsLockPressed
291 --
292 [*] --> ScrollLockOff
293 ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
294 ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
295 }
296 `,
297 { logLevel: 0, fontFamily: 'courier' }
298 );
299 });
300 it('v2 should render a state with states in it', () => {
301 imgSnapshotTest(
302 `
303 stateDiagram-v2
304 state PilotCockpit {
305 state Parent {
306 C
307 }
308 }
309 `,
310 {
311 logLevel: 0,
312 }
313 );
314 });
315 it('v2 it should be possible to use a choice', () => {
316 imgSnapshotTest(
317 `
318 stateDiagram-v2
319 [*] --> Off
320 Off --> On
321 state MyChoice [[choice]]
322 On --> MyChoice
323 MyChoice --> Washing
324 MyChoice --> Drying
325 Washing --> Finished
326 Finished --> [*]
327 `,
328 {
329 logLevel: 0,
330 }
331 );
332 });
333 it('v2 A compound state should be able to link to itself', () => {
334 imgSnapshotTest(
335 `
336stateDiagram
337 state Active {
338 Idle
339 }
340 Inactive --> Idle: ACT
341 Active --> Active: LOG
342 `,
343 {
344 logLevel: 0,
345 }
346 );
347 });
348 it('v2 width of compound state should grow with title if title is wider', () => {
349 imgSnapshotTest(
350 `
351stateDiagram-v2
352 state "Long state name 2" as NotShooting {
353 a-->b
354 }
355 `,
356 {
357 logLevel: 0,
358 }
359 );
360 });
361 it('v2 state label with names in it', () => {
362 imgSnapshotTest(
363 `
364 stateDiagram-v2
365 Yswsii: Your state with spaces in it
366 [*] --> Yswsii
367 `,
368 {
369 logLevel: 0,
370 }
371 );
372 });
373 it('v2 Simplest composite state', () => {
374 imgSnapshotTest(
375 `
376 stateDiagram-v2
377 state Parent {
378 C
379 }
380 `,
381 {
382 logLevel: 0,
383 fontFamily: 'courier',
384 }
385 );
386 });
387 it('v2 should handle multiple arrows from one node to another', () => {
388 imgSnapshotTest(
389 `
390 stateDiagram-v2
391 a --> b: Start
392 a --> b: Stop
393 `,
394 {
395 logLevel: 0,
396 fontFamily: 'courier',
397 }
398 );
399 });
400 it('v2 should handle multiple notes added to one state', () => {
401 imgSnapshotTest(
402 `
403stateDiagram-v2
404 MyState
405 note left of MyState : I am a lefty
406 note right of MyState : I am a righty
407 `,
408 {
409 logLevel: 0,
410 fontFamily: 'courier',
411 }
412 );
413 });
414 it('v2 should handle different rendering directions in composite states', () => {
415 imgSnapshotTest(
416 `
417stateDiagram-v2
418 direction LR
419 state A {
420 direction BT
421 a --> b
422 }
423 state C {
424 direction RL
425 c --> d
426 }
427 A --> C
428 `,
429 {
430 logLevel: 0,
431 fontFamily: 'courier',
432 }
433 );
434 });
435 it('v2 handle transition from one state in a composite state to a composite state', () => {
436 imgSnapshotTest(
437 `
438stateDiagram-v2
439 state S1 {
440 sub1 -->sub2
441 }
442
443 state S2 {
444 sub4
445 }
446 S1 --> S2
447 sub1 --> sub4
448 `,
449 {
450 logLevel: 0,
451 fontFamily: 'courier',
452 }
453 );
454 });
455 it('v2 should render a state diagram when useMaxWidth is true (default)', () => {
456 renderGraph(
457 `
458 stateDiagram-v2
459
460 [*] --> State1
461 State1 --> [*]
462 `,
463 { state: { useMaxWidth: true } }
464 );
465 cy.get('svg').should((svg) => {
466 expect(svg).to.have.attr('width', '100%');
467 // expect(svg).to.have.attr('height');
468 // const height = parseFloat(svg.attr('height'));
469 // expect(height).to.be.within(177, 178);
470 const style = svg.attr('style');
471 expect(style).to.match(/^max-width: [\d.]+px;$/);
472 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
473 // use within because the absolute value can be slightly different depending on the environment ±5%
474 expect(maxWidthValue).to.be.within(65, 85);
475 });
476 });
477 it('v2 should render a state diagram when useMaxWidth is false', () => {
478 renderGraph(
479 `
480 stateDiagram-v2
481
482 [*] --> State1
483 State1 --> [*]
484 `,
485 { state: { useMaxWidth: false } }
486 );
487 cy.get('svg').should((svg) => {
488 // const height = parseFloat(svg.attr('height'));
489 const width = parseFloat(svg.attr('width'));
490 // expect(height).to.be.within(177, 178);
491 // use within because the absolute value can be slightly different depending on the environment ±5%
492 expect(width).to.be.within(65, 85);
493 expect(svg).to.not.have.attr('style');
494 });
495 });
496
497 it('v2 should render a state diagram and set the correct length of the labels', () => {
498 imgSnapshotTest(
499 `
500 stateDiagram-v2
501 [*] --> 1
502 1 --> 2: test({ foo#colon; 'far' })
503 2 --> [*]
504 `,
505 { logLevel: 0, fontFamily: 'courier' }
506 );
507 });
508
509 describe('classDefs and applying classes', () => {
510 it('v2 states can have a class applied', () => {
511 imgSnapshotTest(
512 `
513 stateDiagram-v2
514 [*] --> A
515 A --> B: test({ foo#colon; 'far' })
516 B --> [*]
517 classDef badBadEvent fill:#f00,color:white,font-weight:bold
518 class B badBadEvent
519 `,
520 { logLevel: 0, fontFamily: 'courier' }
521 );
522 });
523 it('v2 can have multiple classes applied to multiple states', () => {
524 imgSnapshotTest(
525 `
526 stateDiagram-v2
527 classDef notMoving fill:white
528 classDef movement font-style:italic;
529 classDef badBadEvent fill:#f00,color:white,font-weight:bold
530
531 [*] --> Still
532 Still --> [*]
533 Still --> Moving
534 Moving --> Still
535 Moving --> Crash
536 Crash --> [*]
537
538 class Still notMoving
539 class Moving, Crash movement
540 class Crash badBadEvent
541 `,
542 { logLevel: 0, fontFamily: 'courier' }
543 );
544 });
545 it(' can have styles applied ', () => {
546 imgSnapshotTest(
547 `
548stateDiagram-v2
549AState
550style AState fill:#636,border:1px solid red,color:white;
551 `,
552 { logLevel: 0, fontFamily: 'courier' }
553 );
554 });
555 it(' should let styles take precedence over classes', () => {
556 imgSnapshotTest(
557 `
558stateDiagram-v2
559AState: Should NOT be white
560BState
561classDef exampleStyleClass fill:#fff,color: blue;
562class AState,BState exampleStyleClass
563style AState fill:#636,border:1px solid red,color:white;
564 `,
565 { logLevel: 0, fontFamily: 'courier' }
566 );
567 });
568 it(' should allow styles to take effect in subgraphs', () => {
569 imgSnapshotTest(
570 `
571 stateDiagram
572 state roundWithTitle {
573 C: Black with white text
574 }
575 D: Black with white text
576
577 style C,D stroke:#00f, fill:black, color:white
578 `,
579 { logLevel: 0, fontFamily: 'courier' }
580 );
581 });
582 });
583 it('1433: should render a simple state diagram with a title', () => {
584 imgSnapshotTest(
585 `---
586title: simple state diagram
587---
588stateDiagram-v2
589[*] --> State1
590State1 --> [*]
591`,
592 {}
593 );
594 });
595 it('should align dividers correctly', () => {
596 imgSnapshotTest(
597 `stateDiagram-v2
598 state s2 {
599 s3
600 --
601 s4
602 --
603 55
604 }
605`,
606 {}
607 );
608 });
609 it('should render edge labels correctly', () => {
610 imgSnapshotTest(
611 `---
612title: On The Way To Something Something DarkSide
613config:
614 look: default
615 theme: default
616---
617
618stateDiagram-v2
619
620 state State1_____________
621 {
622 c0
623 }
624
625 state State2_____________
626 {
627 c1
628 }
629
630 state State3_____________
631 {
632 c7
633 }
634
635 state State4_____________
636 {
637 c2
638 }
639
640 state State5_____________
641 {
642 c3
643 }
644
645 state State6_____________
646 {
647 c4
648 }
649
650 state State7_____________
651 {
652 c5
653 }
654
655 state State8_____________
656 {
657 c6
658 }
659
660
661[*] --> State1_____________
662State1_____________ --> State2_____________ : Transition1_____
663State2_____________ --> State4_____________ : Transition2_____
664State2_____________ --> State3_____________ : Transition3_____
665State3_____________ --> State2_____________
666State4_____________ --> State2_____________ : Transition5_____
667State4_____________ --> State5_____________ : Transition6_____
668State5_____________ --> State6_____________ : Transition7_____
669State6_____________ --> State4_____________ : Transition8_____
670State2_____________ --> State7_____________ : Transition4_____
671State4_____________ --> State7_____________ : Transition4_____
672State5_____________ --> State7_____________ : Transition4_____
673State6_____________ --> State7_____________ : Transition4_____
674State7_____________ --> State1_____________ : Transition9_____
675State5_____________ --> State8_____________ : Transition10____
676State8_____________ --> State5_____________ : Transition11____
677`,
678 {}
679 );
680 });
681 it('should render edge labels correctly with multiple transitions', () => {
682 imgSnapshotTest(
683 `---
684title: Multiple Transitions
685config:
686 look: default
687 theme: default
688---
689
690stateDiagram-v2
691
692 state State1_____________
693 {
694 c0
695 }
696
697 state State2_____________
698 {
699 c1
700 }
701
702 state State3_____________
703 {
704 c7
705 }
706
707 state State4_____________
708 {
709 c2
710 }
711
712 state State5_____________
713 {
714 c3
715 }
716
717 state State6_____________
718 {
719 c4
720 }
721
722 state State7_____________
723 {
724 c5
725 }
726
727 state State8_____________
728 {
729 c6
730 }
731
732 state State9_____________
733 {
734 c9
735 }
736
737[*] --> State1_____________
738State1_____________ --> State2_____________ : Transition1_____
739State2_____________ --> State4_____________ : Transition2_____
740State2_____________ --> State3_____________ : Transition3_____
741State3_____________ --> State2_____________
742State4_____________ --> State2_____________ : Transition5_____
743State4_____________ --> State5_____________ : Transition6_____
744State5_____________ --> State6_____________ : Transition7_____
745State6_____________ --> State4_____________ : Transition8_____
746State2_____________ --> State7_____________ : Transition4_____
747State4_____________ --> State7_____________ : Transition4_____
748State5_____________ --> State7_____________ : Transition4_____
749State6_____________ --> State7_____________ : Transition4_____
750State7_____________ --> State1_____________ : Transition9_____
751State5_____________ --> State8_____________ : Transition10____
752State8_____________ --> State5_____________ : Transition11____
753State9_____________ --> State8_____________ : Transition12____
754`,
755 {}
756 );
757 });
758
759 it('should render edge labels correctly with multiple states', () => {
760 imgSnapshotTest(
761 `---
762title: Multiple States
763config:
764 look: default
765 theme: default
766---
767
768stateDiagram-v2
769
770 state State1_____________
771 {
772 c0
773 }
774
775 state State2_____________
776 {
777 c1
778 }
779
780 state State3_____________
781 {
782 c7
783 }
784
785 state State4_____________
786 {
787 c2
788 }
789
790 state State5_____________
791 {
792 c3
793 }
794
795 state State6_____________
796 {
797 c4
798 }
799
800 state State7_____________
801 {
802 c5
803 }
804
805 state State8_____________
806 {
807 c6
808 }
809
810 state State9_____________
811 {
812 c9
813 }
814
815 state State10_____________
816 {
817 c10
818 }
819
820[*] --> State1_____________
821State1_____________ --> State2_____________ : Transition1_____
822State2_____________ --> State3_____________ : Transition2_____
823State3_____________ --> State4_____________ : Transition3_____
824State4_____________ --> State5_____________ : Transition4_____
825State5_____________ --> State6_____________ : Transition5_____
826State6_____________ --> State7_____________ : Transition6_____
827State7_____________ --> State8_____________ : Transition7_____
828State8_____________ --> State9_____________ : Transition8_____
829State9_____________ --> State10_____________ : Transition9_____
830`,
831 {}
832 );
833 });
834});
835