13.0 KB542 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3describe('Class diagram', () => {
4 it('1: should render a simple class diagram', () => {
5 imgSnapshotTest(
6 `
7 classDiagram
8 Class01 <|-- AveryLongClass : Cool
9 &lt;&lt;interface&gt;&gt; Class01
10 Class03 *-- Class04
11 Class05 o-- Class06
12 Class07 .. Class08
13 Class09 --> C2 : Where am i?
14 Class09 --* C3
15 Class09 --|> Class07
16 Class12 <|.. Class08
17 Class11 ..>Class12
18 Class07 : equals()
19 Class07 : Object[] elementData
20 Class01 : size()
21 Class01 : int chimp
22 Class01 : int gorilla
23 Class01 : -int privateChimp
24 Class01 : +int publicGorilla
25 Class01 : #int protectedMarmoset
26 Class08 <--> C2: Cool label
27 class Class10 {
28 &lt;&lt;service&gt;&gt;
29 int id
30 test()
31 }
32 `,
33 { logLevel: 1 }
34 );
35 });
36
37 it('2: should render a simple class diagrams with cardinality', () => {
38 imgSnapshotTest(
39 `
40 classDiagram
41 Class01 "1" <|--|> "*" AveryLongClass : Cool
42 &lt;&lt;interface&gt;&gt; Class01
43 Class03 "1" *-- "*" Class04
44 Class05 "1" o-- "many" Class06
45 Class07 "1" .. "*" Class08
46 Class09 "1" --> "*" C2 : Where am i?
47 Class09 "*" --* "*" C3
48 Class09 "1" --|> "1" Class07
49 Class07 : equals()
50 Class07 : Object[] elementData
51 Class01 : size()
52 Class01 : int chimp
53 Class01 : int gorilla
54 Class08 "1" <--> "*" C2: Cool label
55 class Class10 {
56 &lt;&lt;service&gt;&gt;
57 int id
58 test()
59 }
60 `,
61 {}
62 );
63 });
64
65 it('3: should render a simple class diagram with different visibilities', () => {
66 imgSnapshotTest(
67 `
68 classDiagram
69 Class01 <|-- AveryLongClass : Cool
70 &lt;&lt;interface&gt;&gt; Class01
71 Class01 : -privateMethod()
72 Class01 : +publicMethod()
73 Class01 : #protectedMethod()
74 Class01 : -int privateChimp
75 Class01 : +int publicGorilla
76 Class01 : #int protectedMarmoset
77 `,
78 {}
79 );
80 });
81
82 it('4: should render a simple class diagram with comments', () => {
83 imgSnapshotTest(
84 `
85 classDiagram
86 %% this is a comment
87 Class01 <|-- AveryLongClass : Cool
88 &lt;&lt;interface&gt;&gt; Class01
89 Class03 *-- Class04
90 Class05 o-- Class06
91 Class07 .. Class08
92 Class09 --> C2 : Where am i?
93 Class09 --* C3
94 Class09 --|> Class07
95 Class07 : equals()
96 Class07 : Object[] elementData
97 Class01 : size()
98 Class01 : int chimp
99 Class01 : int gorilla
100 Class08 <--> C2: Cool label
101 class Class10 {
102 &lt;&lt;service&gt;&gt;
103 int id
104 test()
105 }
106 `,
107 {}
108 );
109 });
110
111 it('5: should render a simple class diagram with abstract method', () => {
112 imgSnapshotTest(
113 `
114 classDiagram
115 Class01 <|-- AveryLongClass : Cool
116 Class01 : someMethod()*
117 `,
118 {}
119 );
120 });
121
122 it('6: should render a simple class diagram with static method', () => {
123 imgSnapshotTest(
124 `
125 classDiagram
126 Class01 <|-- AveryLongClass : Cool
127 Class01 : someMethod()$
128 `,
129 {}
130 );
131 });
132
133 it('7: should render a simple class diagram with Generic class', () => {
134 imgSnapshotTest(
135 `
136 classDiagram
137 class Class01~T~
138 Class01 : size()
139 Class01 : int chimp
140 Class01 : int gorilla
141 Class08 <--> C2: Cool label
142 class Class10~T~ {
143 &lt;&lt;service&gt;&gt;
144 int id
145 test()
146 }
147 `,
148 {}
149 );
150 });
151
152 it('8: should render a simple class diagram with Generic class and relations', () => {
153 imgSnapshotTest(
154 `
155 classDiagram
156 Class01~T~ <|-- AveryLongClass : Cool
157 Class03~T~ *-- Class04~T~
158 Class01 : size()
159 Class01 : int chimp
160 Class01 : int gorilla
161 Class08 <--> C2: Cool label
162 class Class10~T~ {
163 &lt;&lt;service&gt;&gt;
164 int id
165 test()
166 }
167 `,
168 {}
169 );
170 });
171
172 it('9: should render a simple class diagram with clickable link', () => {
173 imgSnapshotTest(
174 `
175 classDiagram
176 Class01~T~ <|-- AveryLongClass : Cool
177 Class03~T~ *-- Class04~T~
178 Class01 : size()
179 Class01 : int chimp
180 Class01 : int gorilla
181 Class08 <--> C2: Cool label
182 class Class10~T~ {
183 &lt;&lt;service&gt;&gt;
184 int id
185 test()
186 }
187 link Class01 "google.com" "A Tooltip"
188 `,
189 {}
190 );
191 });
192
193 it('10: should render a simple class diagram with clickable callback', () => {
194 imgSnapshotTest(
195 `
196 classDiagram
197 Class01~T~ <|-- AveryLongClass : Cool
198 Class03~T~ *-- Class04~T~
199 Class01 : size()
200 Class01 : int chimp
201 Class01 : int gorilla
202 Class08 <--> C2: Cool label
203 class Class10~T~ {
204 &lt;&lt;service&gt;&gt;
205 int id
206 test()
207 }
208 callback Class01 "functionCall" "A Tooltip"
209 `,
210 {}
211 );
212 });
213
214 it('11: should render a simple class diagram with return type on method', () => {
215 imgSnapshotTest(
216 `
217 classDiagram
218 class Class10~T~ {
219 int[] id
220 test(int[] ids) bool
221 testArray() bool[]
222 }
223 `,
224 {}
225 );
226 });
227
228 it('12: should render a simple class diagram with generic types', () => {
229 imgSnapshotTest(
230 `
231 classDiagram
232 class Class10~T~ {
233 int[] id
234 List~int~ ids
235 test(List~int~ ids) List~bool~
236 testArray() bool[]
237 }
238 `,
239 {}
240 );
241 });
242
243 it('13: should render a simple class diagram with css classes applied', () => {
244 imgSnapshotTest(
245 `
246 classDiagram
247 class Class10 {
248 int[] id
249 List~int~ ids
250 test(List~int~ ids) List~bool~
251 testArray() bool[]
252 }
253
254 class Class10:::exClass2
255 `,
256 {}
257 );
258 });
259
260 it('14: should render a simple class diagram with css classes applied directly', () => {
261 imgSnapshotTest(
262 `
263 classDiagram
264 class Class10:::exClass2 {
265 int[] id
266 List~int~ ids
267 test(List~int~ ids) List~bool~
268 testArray() bool[]
269 }
270 `,
271 {}
272 );
273 });
274
275 it('15: should render a simple class diagram with css classes applied to multiple classes', () => {
276 imgSnapshotTest(
277 `
278 classDiagram
279 class Class10
280 class Class20
281
282 cssClass "Class10, Class20" exClass2
283 class Class20:::exClass2
284 `,
285 {}
286 );
287 });
288
289 it('16: should render multiple class diagrams', () => {
290 imgSnapshotTest(
291 [
292 `
293 classDiagram
294 Class01 "1" <|--|> "*" AveryLongClass : Cool
295 &lt;&lt;interface&gt;&gt; Class01
296 Class03 "1" *-- "*" Class04
297 Class05 "1" o-- "many" Class06
298 Class07 "1" .. "*" Class08
299 Class09 "1" --> "*" C2 : Where am i?
300 Class09 "*" --* "*" C3
301 Class09 "1" --|> "1" Class07
302 Class07 : equals()
303 Class07 : Object[] elementData
304 Class01 : size()
305 Class01 : int chimp
306 Class01 : int gorilla
307 Class08 "1" <--> "*" C2: Cool label
308 class Class10 {
309 &lt;&lt;service&gt;&gt;
310 int id
311 test()
312 }
313 `,
314 `
315 classDiagram
316 Class01 "1" <|--|> "*" AveryLongClass : Cool
317 &lt;&lt;interface&gt;&gt; Class01
318 Class03 "1" *-- "*" Class04
319 Class05 "1" o-- "many" Class06
320 Class07 "1" .. "*" Class08
321 Class09 "1" --> "*" C2 : Where am i?
322 Class09 "*" --* "*" C3
323 Class09 "1" --|> "1" Class07
324 Class07 : equals()
325 Class07 : Object[] elementData
326 Class01 : size()
327 Class01 : int chimp
328 Class01 : int gorilla
329 Class08 "1" <--> "*" C2: Cool label
330 class Class10 {
331 &lt;&lt;service&gt;&gt;
332 int id
333 test()
334 }
335 `,
336 ],
337 {}
338 );
339 });
340
341 // it('17: should render a class diagram when useMaxWidth is true (default)', () => {
342 // renderGraph(
343 // `
344 // classDiagram
345 // Class01 <|-- AveryLongClass : Cool
346 // Class01 : size()
347 // Class01 : int chimp
348 // Class01 : int gorilla
349 // Class01 : -int privateChimp
350 // Class01 : +int publicGorilla
351 // Class01 : #int protectedMarmoset
352 // `,
353 // { class: { useMaxWidth: true } }
354 // );
355 // cy.get('svg')
356 // .should((svg) => {
357 // expect(svg).to.have.attr('width', '100%');
358 // const height = parseFloat(svg.attr('height'));
359 // expect(height).to.be.within(332, 333);
360 // // expect(svg).to.have.attr('height', '218');
361 // const style = svg.attr('style');
362 // expect(style).to.match(/^max-width: [\d.]+px;$/);
363 // const maxWidthValue = parseInt(style.match(/[\d.]+/g).join(''));
364 // // use within because the absolute value can be slightly different depending on the environment ±5%
365 // expect(maxWidthValue).to.be.within(203, 204);
366 // });
367 // });
368
369 // it('18: should render a class diagram when useMaxWidth is false', () => {
370 // renderGraph(
371 // `
372 // classDiagram
373 // Class01 <|-- AveryLongClass : Cool
374 // Class01 : size()
375 // Class01 : int chimp
376 // Class01 : int gorilla
377 // Class01 : -int privateChimp
378 // Class01 : +int publicGorilla
379 // Class01 : #int protectedMarmoset
380 // `,
381 // { class: { useMaxWidth: false } }
382 // );
383 // cy.get('svg')
384 // .should((svg) => {
385 // const width = parseFloat(svg.attr('width'));
386 // // use within because the absolute value can be slightly different depending on the environment ±5%
387 // expect(width).to.be.within(100, 101);
388 // const height = parseFloat(svg.attr('height'));
389 // expect(height).to.be.within(332, 333);
390 // // expect(svg).to.have.attr('height', '332');
391 // // expect(svg).to.not.have.attr('style');
392 // });
393 // });
394
395 it('19: should render a simple class diagram with notes', () => {
396 imgSnapshotTest(
397 `
398 classDiagram
399 note "I love this diagram!\nDo you love it?"
400 class Class10 {
401 int id
402 size()
403 }
404 note for Class10 "Cool class\nI said it's very cool class!"
405 `,
406 { logLevel: 1 }
407 );
408 });
409
410 it('should render class diagram with newlines in title', () => {
411 imgSnapshotTest(`
412 classDiagram
413 Animal <|-- \`Du\nck\`
414 Animal : +int age
415 Animal : +String gender
416 Animal: +isMammal()
417 Animal: +mate()
418 class \`Du\nck\` {
419 +String beakColor
420 +String featherColor
421 +swim()
422 +quack()
423 }
424 `);
425 });
426
427 it('should render class diagram with many newlines in title', () => {
428 imgSnapshotTest(`
429 classDiagram
430 class \`This\nTitle\nHas\nMany\nNewlines\` {
431 +String Also
432 -String Many
433 #int Members
434 +And()
435 -Many()
436 #Methods()
437 }
438 `);
439 });
440
441 it('should render with newlines in title and an annotation', () => {
442 imgSnapshotTest(`
443 classDiagram
444 class \`This\nTitle\nHas\nMany\nNewlines\` {
445 +String Also
446 -String Many
447 #int Members
448 +And()
449 -Many()
450 #Methods()
451 }
452 &lt;&lt;Interface&gt;&gt; \`This\nTitle\nHas\nMany\nNewlines\`
453 `);
454 });
455
456 it('should handle newline title in namespace', () => {
457 imgSnapshotTest(`
458 classDiagram
459 namespace testingNamespace {
460 class \`This\nTitle\nHas\nMany\nNewlines\` {
461 +String Also
462 -String Many
463 #int Members
464 +And()
465 -Many()
466 #Methods()
467 }
468 }
469 `);
470 });
471
472 it('should handle newline in string label', () => {
473 imgSnapshotTest(`
474 classDiagram
475 class A["This has\na newline!"] {
476 +String boop
477 -Int beep
478 #double bop
479 }
480
481 class B["This title also has\na newline"]
482 B : +with(more)
483 B : -methods()
484 `);
485 });
486
487 it('should handle notes with anchor tag having target attribute', () => {
488 renderGraph(
489 `classDiagram
490 class test { }
491 note for test "<a href='https://mermaid.js.org/' target="_blank"><code>note about mermaid</code></a>"`
492 );
493
494 cy.get('svg').then((svg) => {
495 cy.get('a').should('have.attr', 'target', '_blank').should('have.attr', 'rel', 'noopener');
496 });
497 });
498
499 describe('Include char sequence "graph" in text (#6795)', () => {
500 it('has a label with char sequence "graph"', () => {
501 imgSnapshotTest(
502 `
503 classDiagram
504 class Person {
505 +String name
506 -Int id
507 #double age
508 +Text demographicProfile
509 }
510 `,
511 { flowchart: { defaultRenderer: 'elk' } }
512 );
513 });
514 });
515
516 it('should handle backticks for namespace and class names', () => {
517 imgSnapshotTest(
518 `
519 classDiagram
520 namespace \`A::B\` {
521 class \`IPC::Sender\`
522 }
523 RenderProcessHost --|> \`IPC::Sender\`
524 `,
525 {}
526 );
527 it('should handle an empty class body with empty braces', () => {
528 imgSnapshotTest(
529 ` classDiagram
530 class FooBase~T~ {}
531 class Bar {
532 +Zip
533 +Zap()
534 }
535 FooBase <|-- Ba
536 `,
537 { flowchart: { defaultRenderer: 'elk' } }
538 );
539 });
540 });
541});
542