9.3 KB379 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3describe('State diagram', () => {
4 it('should render a simple state diagrams', () => {
5 imgSnapshotTest(
6 `
7 stateDiagram
8 [*] --> State1
9 State1 --> [*]
10 `,
11 { logLevel: 0, fontFamily: 'courier' }
12 );
13 });
14 it('should render a long descriptions instead of id when available', () => {
15 imgSnapshotTest(
16 `
17 stateDiagram
18
19 [*] --> S1
20 state "Some long name" as S1
21 `,
22 { logLevel: 0, fontFamily: 'courier' }
23 );
24 });
25 it('should render a long descriptions with additional descriptions', () => {
26 imgSnapshotTest(
27 `
28 stateDiagram
29
30 [*] --> S1
31 state "Some long name" as S1: The description
32 `,
33 { logLevel: 0, fontFamily: 'courier' }
34 );
35 });
36 it('should render a single state with short descriptions', () => {
37 imgSnapshotTest(
38 `
39 stateDiagram
40 state "A long long name" as long1
41 state "A" as longlonglongid
42 `,
43 { logLevel: 0, fontFamily: 'courier' }
44 );
45 });
46 it('should render a transition descriptions with new lines', () => {
47 imgSnapshotTest(
48 `
49 stateDiagram
50
51 [*] --> S1
52 S1 --> S2: long line using<br/>should work
53 S1 --> S3: long line using <br>should work
54 S1 --> S4: long line using \\nshould work
55 `,
56 { logLevel: 0, fontFamily: 'courier' }
57 );
58 });
59 it('should render a state with a note', () => {
60 imgSnapshotTest(
61 `
62 stateDiagram
63 State1: The state with a note
64 note right of State1
65 Important information! You can write
66 notes.
67 end note
68 `,
69 { logLevel: 0, fontFamily: 'courier' }
70 );
71 });
72 it('should render a state with on the left side when so specified', () => {
73 imgSnapshotTest(
74 `
75 stateDiagram
76 State1: The state with a note with minus - and plus + in it
77 note left of State1
78 Important information! You can write
79 notes with . and in them.
80 end note
81 `,
82 { logLevel: 0, fontFamily: 'courier' }
83 );
84 });
85 it('should render a state with a note together with another state', () => {
86 imgSnapshotTest(
87 `
88 stateDiagram
89 State1: The state with a note +,-
90 note right of State1
91 Important information! You can write +,-
92 notes.
93 end note
94 State1 --> State2 : With +,-
95 note left of State2 : This is the note +,-<br/>
96 `,
97 { logLevel: 0, fontFamily: 'courier' }
98 );
99 });
100 it('should render a note with multiple lines in it', () => {
101 imgSnapshotTest(
102 `
103 stateDiagram
104 State1: The state with a note
105 note right of State1
106 Important information! You\ncan write
107 notes with multiple lines...
108 Here is another line...
109 And another line...
110 end note
111 `,
112 { logLevel: 0, fontFamily: 'courier' }
113 );
114 });
115 it('should handle multiline notes with different line breaks', () => {
116 imgSnapshotTest(
117 `
118 stateDiagram
119 State1
120 note right of State1
121 Line1<br>Line2<br/>Line3<br />Line4<br />Line5
122 end note
123 `,
124 { logLevel: 0, fontFamily: 'courier' }
125 );
126 });
127
128 it('should render a states with descriptions including multi-line descriptions', () => {
129 imgSnapshotTest(
130 `
131 stateDiagram
132 State1: This a single line description
133 State2: This a multi line description
134 State2: here comes the multi part
135 [*] --> State1
136 State1 --> State2
137 State2 --> [*]
138 `,
139 { logLevel: 0, fontFamily: 'courier' }
140 );
141 });
142 it('should render a simple state diagrams 2', () => {
143 imgSnapshotTest(
144 `
145 stateDiagram
146 [*] --> State1
147 State1 --> State2
148 State1 --> State3
149 State1 --> [*]
150 `,
151 { logLevel: 0, fontFamily: 'courier' }
152 );
153 });
154 it('should render a simple state diagrams with labels', () => {
155 imgSnapshotTest(
156 `
157 stateDiagram
158 [*] --> State1
159 State1 --> State2 : Transition 1
160 State1 --> State3 : Transition 2
161 State1 --> State4 : Transition 3
162 State1 --> State5 : Transition 4
163 State2 --> State3 : Transition 5
164 State1 --> [*]
165 `,
166 { logLevel: 0, fontFamily: 'courier' }
167 );
168 });
169 it('should render state descriptions', () => {
170 imgSnapshotTest(
171 `
172 stateDiagram
173 state "Long state description" as XState1
174 state "Another Long state description" as XState2
175 XState2 : New line
176 XState1 --> XState2
177 `,
178 { logLevel: 0, fontFamily: 'courier' }
179 );
180 });
181 it('should render composite states', () => {
182 imgSnapshotTest(
183 `
184 stateDiagram
185 [*] --> NotShooting: Pacifist
186 NotShooting --> A
187 NotShooting --> B
188 NotShooting --> C
189
190 state NotShooting {
191 [*] --> Idle: Yet another long long öong öong öong label
192 Idle --> Configuring : EvConfig
193 Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
194 }
195 `,
196 { logLevel: 0, fontFamily: 'courier' }
197 );
198 });
199 it('should render multiple composit states', () => {
200 imgSnapshotTest(
201 `
202 stateDiagram
203 [*]-->TV
204
205 state TV {
206 [*] --> Off: Off to start with
207 On --> Off : Turn off
208 Off --> On : Turn on
209 }
210
211 TV--> Console
212
213 state Console {
214 [*] --> Off2: Off to start with
215 On2--> Off2 : Turn off
216 Off2 --> On2 : Turn on
217 On2-->Playing
218
219 state Playing {
220 Alive --> Dead
221 Dead-->Alive
222 }
223 }
224 `,
225 { logLevel: 0, fontFamily: 'courier' }
226 );
227 });
228 it('should render forks in composit states', () => {
229 imgSnapshotTest(
230 `
231 stateDiagram
232 [*]-->TV
233
234 state TV {
235 state fork_state &lt;&lt;fork&gt;&gt;
236 [*] --> fork_state
237 fork_state --> State2
238 fork_state --> State3
239
240 state join_state &lt;&lt;join&gt;&gt;
241 State2 --> join_state
242 State3 --> join_state
243 join_state --> State4
244 State4 --> [*]
245 }
246 `,
247 { logLevel: 0, fontFamily: 'courier' }
248 );
249 });
250 it('should render forks and joins', () => {
251 imgSnapshotTest(
252 `
253 stateDiagram
254 state fork_state &lt;&lt;fork&gt;&gt;
255 [*] --> fork_state
256 fork_state --> State2
257 fork_state --> State3
258
259 state join_state &lt;&lt;join&gt;&gt;
260 State2 --> join_state
261 State3 --> join_state
262 join_state --> State4
263 State4 --> [*]
264 `,
265 { logLevel: 0, fontFamily: 'courier' }
266 );
267 });
268 it('should render concurrency states', () => {
269 imgSnapshotTest(
270 `
271 stateDiagram
272 [*] --> Active
273
274 state Active {
275 [*] --> NumLockOff
276 NumLockOff --> NumLockOn : EvNumLockPressed
277 NumLockOn --> NumLockOff : EvNumLockPressed
278 --
279 [*] --> CapsLockOff
280 CapsLockOff --> CapsLockOn : EvCapsLockPressed
281 CapsLockOn --> CapsLockOff : EvCapsLockPressed
282 --
283 [*] --> ScrollLockOff
284 ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
285 ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
286 }
287 `,
288 { logLevel: 0, fontFamily: 'courier' }
289 );
290 });
291 it('should render a state with states in it', () => {
292 imgSnapshotTest(
293 `
294 stateDiagram
295 state PilotCockpit {
296 state Parent {
297 C
298 }
299 }
300 `,
301 {
302 logLevel: 0,
303 fontFamily: 'courier',
304 }
305 );
306 });
307 it('Simplest composite state', () => {
308 imgSnapshotTest(
309 `
310 stateDiagram
311 state Parent {
312 C
313 }
314 `,
315 {
316 logLevel: 0,
317 fontFamily: 'courier',
318 }
319 );
320 });
321 it('should handle multiple arrows from one node to another', () => {
322 imgSnapshotTest(
323 `
324 stateDiagram
325 a --> b: Start
326 a --> b: Stop
327 `,
328 {
329 logLevel: 0,
330 fontFamily: 'courier',
331 }
332 );
333 });
334 it('should render a state diagram when useMaxWidth is true (default)', () => {
335 renderGraph(
336 `
337 stateDiagram
338 [*] --> State1
339 State1 --> [*]
340 `,
341 { state: { useMaxWidth: true } }
342 );
343 cy.get('svg').should((svg) => {
344 expect(svg).to.have.attr('width', '100%');
345 // expect(svg).to.have.attr('height');
346 // const height = parseFloat(svg.attr('height'));
347 // expect(height).to.be.within(176, 178);
348 const style = svg.attr('style');
349 expect(style).to.match(/^max-width: [\d.]+px;$/);
350 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
351 // use within because the absolute value can be slightly different depending on the environment ±5%
352 // Todo investigate difference
353 // expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
354 expect(maxWidthValue).to.be.within(65, 85);
355 });
356 });
357 it('should render a state diagram when useMaxWidth is false', () => {
358 renderGraph(
359 `
360 stateDiagram
361 [*] --> State1
362 State1 --> [*]
363 `,
364 { state: { useMaxWidth: false } }
365 );
366 cy.get('svg').should((svg) => {
367 // const height = parseFloat(svg.attr('height'));
368 const width = parseFloat(svg.attr('width'));
369 // expect(height).to.be.within(176, 178);
370 // use within because the absolute value can be slightly different depending on the environment ±5%
371 // Todo investigate difference
372 // expect(width).to.be.within(112 * .95, 112 * 1.05);
373 expect(width).to.be.within(65, 85);
374
375 expect(svg).to.not.have.attr('style');
376 });
377 });
378});
379