16.7 KB653 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3const testOptions = [
4 { description: '', options: { logLevel: 1 } },
5 { description: 'ELK: ', options: { logLevel: 1, layout: 'elk' } },
6 { description: 'HD: ', options: { logLevel: 1, look: 'handDrawn' } },
7];
8
9describe('Entity Relationship Diagram Unified', () => {
10 testOptions.forEach(({ description, options }) => {
11 it(`${description}should render a simple ER diagram`, () => {
12 imgSnapshotTest(
13 `
14 erDiagram
15 CUSTOMER ||--o{ ORDER : places
16 ORDER ||--|{ LINE-ITEM : contains
17 `,
18 options
19 );
20 });
21
22 it(`${description}should render a simple ER diagram without htmlLabels`, () => {
23 imgSnapshotTest(
24 `
25 erDiagram
26 CUSTOMER ||--o{ ORDER : places
27 ORDER ||--|{ LINE-ITEM : contains
28 `,
29 { ...options, htmlLabels: false }
30 );
31 });
32
33 it(`${description}should render an ER diagram with a recursive relationship`, () => {
34 imgSnapshotTest(
35 `
36 erDiagram
37 CUSTOMER ||..o{ CUSTOMER : refers
38 CUSTOMER ||--o{ ORDER : places
39 ORDER ||--|{ LINE-ITEM : contains
40 `,
41 options
42 );
43 });
44
45 it(`${description}should render an ER diagram with multiple relationships between the same two entities`, () => {
46 imgSnapshotTest(
47 `
48 erDiagram
49 CUSTOMER ||--|{ ADDRESS : "invoiced at"
50 CUSTOMER ||--|{ ADDRESS : "receives goods at"
51 `,
52 options
53 );
54 });
55
56 it(`${description}should render a cyclical ER diagram`, () => {
57 imgSnapshotTest(
58 `
59 erDiagram
60 A ||--|{ B : likes
61 B ||--|{ C : likes
62 C ||--|{ A : likes
63 `,
64 options
65 );
66 });
67
68 it(`${description}should render a not-so-simple ER diagram`, () => {
69 imgSnapshotTest(
70 `
71 erDiagram
72 CUSTOMER }|..|{ DELIVERY-ADDRESS : has
73 CUSTOMER ||--o{ ORDER : places
74 CUSTOMER ||--o{ INVOICE : "liable for"
75 DELIVERY-ADDRESS ||--o{ ORDER : receives
76 INVOICE ||--|{ ORDER : covers
77 ORDER ||--|{ ORDER-ITEM : includes
78 PRODUCT-CATEGORY ||--|{ PRODUCT : contains
79 PRODUCT ||--o{ ORDER-ITEM : "ordered in"
80 `,
81 options
82 );
83 });
84
85 it(`${description}should render a not-so-simple ER diagram without htmlLabels`, () => {
86 imgSnapshotTest(
87 `
88 erDiagram
89 CUSTOMER }|..|{ DELIVERY-ADDRESS : has
90 CUSTOMER ||--o{ ORDER : places
91 CUSTOMER ||--o{ INVOICE : "liable for"
92 DELIVERY-ADDRESS ||--o{ ORDER : receives
93 INVOICE ||--|{ ORDER : covers
94 ORDER ||--|{ ORDER-ITEM : includes
95 PRODUCT-CATEGORY ||--|{ PRODUCT : contains
96 PRODUCT ||--o{ ORDER-ITEM : "ordered in"
97 `,
98 { ...options, htmlLabels: false }
99 );
100 });
101
102 it(`${description}should render multiple ER diagrams`, () => {
103 imgSnapshotTest(
104 [
105 `
106 erDiagram
107 CUSTOMER ||--o{ ORDER : places
108 ORDER ||--|{ LINE-ITEM : contains
109 `,
110 `
111 erDiagram
112 CUSTOMER ||--o{ ORDER : places
113 ORDER ||--|{ LINE-ITEM : contains
114 `,
115 ],
116 options
117 );
118 });
119
120 it(`${description}should render an ER diagram with blank or empty labels`, () => {
121 imgSnapshotTest(
122 `
123 erDiagram
124 BOOK }|..|{ AUTHOR : ""
125 BOOK }|..|{ GENRE : " "
126 AUTHOR }|..|{ GENRE : " "
127 `,
128 options
129 );
130 });
131
132 it(`${description}should render entities that have no relationships`, () => {
133 renderGraph(
134 `
135 erDiagram
136 DEAD_PARROT
137 HERMIT
138 RECLUSE
139 SOCIALITE }o--o{ SOCIALITE : "interacts with"
140 RECLUSE }o--o{ SOCIALITE : avoids
141 `,
142 options
143 );
144 });
145
146 it(`${description}should render entities with and without attributes`, () => {
147 renderGraph(
148 `
149 erDiagram
150 BOOK { string title }
151 AUTHOR }|..|{ BOOK : writes
152 BOOK { float price }
153 `,
154 options
155 );
156 });
157
158 it(`${description}should render entities with generic and array attributes`, () => {
159 renderGraph(
160 `
161 erDiagram
162 BOOK {
163 string title
164 string[] authors
165 type~T~ type
166 }
167 `,
168 options
169 );
170 });
171
172 it(`${description}should render entities with generic and array attributes without htmlLabels`, () => {
173 renderGraph(
174 `
175 erDiagram
176 BOOK {
177 string title
178 string[] authors
179 type~T~ type
180 }
181 `,
182 { ...options, htmlLabels: false }
183 );
184 });
185
186 it(`${description}should render entities with length in attributes type`, () => {
187 renderGraph(
188 `
189 erDiagram
190 CLUSTER {
191 varchar(99) name
192 string(255) description
193 }
194 `,
195 options
196 );
197 });
198
199 it(`${description}should render entities with length in attributes type without htmlLabels`, () => {
200 renderGraph(
201 `
202 erDiagram
203 CLUSTER {
204 varchar(99) name
205 string(255) description
206 }
207 `,
208 { ...options, htmlLabels: false }
209 );
210 });
211
212 it(`${description}should render entities and attributes with big and small entity names`, () => {
213 renderGraph(
214 `
215 erDiagram
216 PRIVATE_FINANCIAL_INSTITUTION {
217 string name
218 int turnover
219 }
220 PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
221 EMPLOYEE { bool officer_of_firm }
222 `,
223 options
224 );
225 });
226
227 it(`${description}should render entities and attributes with big and small entity names without htmlLabels`, () => {
228 renderGraph(
229 `
230 erDiagram
231 PRIVATE_FINANCIAL_INSTITUTION {
232 string name
233 int turnover
234 }
235 PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
236 EMPLOYEE { bool officer_of_firm }
237 `,
238 { ...options, htmlLabels: false }
239 );
240 });
241
242 it(`${description}should render entities with attributes that begin with asterisk`, () => {
243 imgSnapshotTest(
244 `
245 erDiagram
246 BOOK {
247 int *id
248 string name
249 varchar(99) summary
250 }
251 BOOK }o..o{ STORE : soldBy
252 STORE {
253 int *id
254 string name
255 varchar(50) address
256 }
257 `,
258 options
259 );
260 });
261
262 it(`${description}should render entities with attributes that begin with asterisk without htmlLabels`, () => {
263 imgSnapshotTest(
264 `
265 erDiagram
266 BOOK {
267 int *id
268 string name
269 varchar(99) summary
270 }
271 BOOK }o..o{ STORE : soldBy
272 STORE {
273 int *id
274 string name
275 varchar(50) address
276 }
277 `,
278 { ...options, htmlLabels: false }
279 );
280 });
281
282 it(`${description}should render entities with keys`, () => {
283 renderGraph(
284 `
285 erDiagram
286 AUTHOR_WITH_LONG_ENTITY_NAME {
287 string name PK
288 }
289 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
290 BOOK {
291 float price
292 string author FK
293 string title PK
294 }
295 `,
296 options
297 );
298 });
299
300 it(`${description}should render entities with keys without htmlLabels`, () => {
301 renderGraph(
302 `
303 erDiagram
304 AUTHOR_WITH_LONG_ENTITY_NAME {
305 string name PK
306 }
307 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
308 BOOK {
309 float price
310 string author FK
311 string title PK
312 }
313 `,
314 { ...options, htmlLabels: false }
315 );
316 });
317
318 it(`${description}should render entities with comments`, () => {
319 renderGraph(
320 `
321 erDiagram
322 AUTHOR_WITH_LONG_ENTITY_NAME {
323 string name "comment"
324 }
325 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
326 BOOK {
327 string author
328 string title "author comment"
329 float price "price comment"
330 }
331 `,
332 options
333 );
334 });
335
336 it(`${description}should render entities with comments without htmlLabels`, () => {
337 renderGraph(
338 `
339 erDiagram
340 AUTHOR_WITH_LONG_ENTITY_NAME {
341 string name "comment"
342 }
343 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
344 BOOK {
345 string author
346 string title "author comment"
347 float price "price comment"
348 }
349 `,
350 { ...options, htmlLabels: false }
351 );
352 });
353
354 it(`${description}should render entities with keys and comments`, () => {
355 renderGraph(
356 `
357 erDiagram
358 AUTHOR_WITH_LONG_ENTITY_NAME {
359 string name PK "comment"
360 }
361 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
362 BOOK {
363 string description
364 float price "price comment"
365 string title PK "title comment"
366 string author FK
367 }
368 `,
369 options
370 );
371 });
372
373 it(`${description}should render entities with keys and comments without htmlLabels`, () => {
374 renderGraph(
375 `
376 erDiagram
377 AUTHOR_WITH_LONG_ENTITY_NAME {
378 string name PK "comment"
379 }
380 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
381 BOOK {
382 string description
383 float price "price comment"
384 string title PK "title comment"
385 string author FK
386 }
387 `,
388 { ...options, htmlLabels: false }
389 );
390 });
391
392 it(`${description}should render entities with aliases`, () => {
393 renderGraph(
394 `
395 erDiagram
396 T1 one or zero to one or more T2 : test
397 T2 one or many optionally to zero or one T3 : test
398 T3 zero or more to zero or many T4 : test
399 T4 many(0) to many(1) T5 : test
400 T5 many optionally to one T6 : test
401 T6 only one optionally to only one T1 : test
402 T4 0+ to 1+ T6 : test
403 T1 1 to 1 T3 : test
404 `,
405 options
406 );
407 });
408
409 it(`${description}should render a simple ER diagram with a title`, () => {
410 imgSnapshotTest(
411 `---
412 title: simple ER diagram
413 ---
414 erDiagram
415 CUSTOMER ||--o{ ORDER : places
416 ORDER ||--|{ LINE-ITEM : contains
417 `,
418 options
419 );
420 });
421
422 it(`${description}should render entities with entity name aliases`, () => {
423 imgSnapshotTest(
424 `
425 erDiagram
426 p[Person] {
427 varchar(64) firstName
428 varchar(64) lastName
429 }
430 c["Customer Account"] {
431 varchar(128) email
432 }
433 p ||--o| c : has
434 `,
435 options
436 );
437 });
438
439 it(`${description}should render relationship labels with line breaks`, () => {
440 imgSnapshotTest(
441 `
442 erDiagram
443 p[Person] {
444 string firstName
445 string lastName
446 }
447 a["Customer Account"] {
448 string email
449 }
450
451 b["Customer Account Secondary"] {
452 string email
453 }
454
455 c["Customer Account Tertiary"] {
456 string email
457 }
458
459 d["Customer Account Nth"] {
460 string email
461 }
462
463 p ||--o| a : "has<br />one"
464 p ||--o| b : "has<br />one<br />two"
465 p ||--o| c : "has<br />one<br/>two<br />three"
466 p ||--o| d : "has<br />one<br />two<br/>three<br />...<br/>Nth"
467 `,
468 options
469 );
470 });
471
472 it(`${description}should render an ER diagram with unicode text`, () => {
473 imgSnapshotTest(
474 `
475 erDiagram
476 _**testẽζ➕Ø😀㌕ぼ**_ {
477 *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
478 *string(99)~T~~~~~~* firstName "Only __99__ <br>characters are a<br>llowed dsfsdfsdfsdfs"
479 string last*Name*
480 string __phone__ UK
481 int _age_
482 }
483 `,
484 options
485 );
486 });
487
488 it(`${description}should render an ER diagram with unicode text without htmlLabels`, () => {
489 imgSnapshotTest(
490 `
491 erDiagram
492 _**testẽζ➕Ø😀㌕ぼ**_ {
493 *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
494 *string(99)~T~~~~~~* firstName "Only __99__ <br>characters are a<br>llowed dsfsdfsdfsdfs"
495 string last*Name*
496 string __phone__ UK
497 int _age_
498 }
499 `,
500 { ...options, htmlLabels: false }
501 );
502 });
503
504 it(`${description}should render an ER diagram with relationships with unicode text`, () => {
505 imgSnapshotTest(
506 `
507 erDiagram
508 person[😀] {
509 string *first*Name
510 string _**last**Name_
511 }
512 a["*Customer Account*"] {
513 **string** ema*i*l
514 }
515 person ||--o| a : __hẽ😀__
516 `,
517 options
518 );
519 });
520
521 it(`${description}should render an ER diagram with relationships with unicode text without htmlLabels`, () => {
522 imgSnapshotTest(
523 `
524 erDiagram
525 person[😀] {
526 string *first*Name
527 string _**last**Name_
528 }
529 a["*Customer Account*"] {
530 **string** ema*i*l
531 }
532 person ||--o| a : __hẽ😀__
533 `,
534 { ...options, htmlLabels: false }
535 );
536 });
537
538 it(`${description}should render an ER diagram with TB direction`, () => {
539 imgSnapshotTest(
540 `
541 erDiagram
542 direction TB
543 CAR ||--|{ NAMED-DRIVER : allows
544 PERSON ||..o{ NAMED-DRIVER : is
545 `,
546 options
547 );
548 });
549
550 it(`${description}should render an ER diagram with BT direction`, () => {
551 imgSnapshotTest(
552 `
553 erDiagram
554 direction BT
555 CAR ||--|{ NAMED-DRIVER : allows
556 PERSON ||..o{ NAMED-DRIVER : is
557 `,
558 options
559 );
560 });
561
562 it(`${description}should render an ER diagram with LR direction`, () => {
563 imgSnapshotTest(
564 `
565 erDiagram
566 direction LR
567 CAR ||--|{ NAMED-DRIVER : allows
568 PERSON ||..o{ NAMED-DRIVER : is
569 `,
570 options
571 );
572 });
573
574 it(`${description}should render an ER diagram with RL direction`, () => {
575 imgSnapshotTest(
576 `
577 erDiagram
578 direction RL
579 CAR ||--|{ NAMED-DRIVER : allows
580 PERSON ||..o{ NAMED-DRIVER : is
581 `,
582 options
583 );
584 });
585
586 it(`${description}should render entities with styles applied from style statement`, () => {
587 imgSnapshotTest(
588 `
589 erDiagram
590 c[CUSTOMER]
591 p[PERSON]
592 style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
593 `,
594 options
595 );
596 });
597
598 it(`${description}should render entities with styles applied from style statement without htmlLabels`, () => {
599 imgSnapshotTest(
600 `
601 erDiagram
602 c[CUSTOMER]
603 p[PERSON]
604 style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
605 `,
606 { ...options, htmlLabels: false }
607 );
608 });
609
610 it(`${description}should render entities with styles applied from class statement`, () => {
611 imgSnapshotTest(
612 `
613 erDiagram
614 c[CUSTOMER]
615 p[PERSON]:::blue
616 classDef bold font-size:24px, font-weight: bold
617 classDef blue stroke:lightblue, color: #0000FF
618 class c,p bold
619 `,
620 options
621 );
622 });
623
624 it(`${description}should render entities with styles applied from class statement without htmlLabels`, () => {
625 imgSnapshotTest(
626 `
627 erDiagram
628 c[CUSTOMER]
629 p[PERSON]:::blue
630 classDef bold font-size:24px, font-weight: bold
631 classDef blue stroke:lightblue, color: #0000FF
632 class c,p bold
633 `,
634 { ...options, htmlLabels: false }
635 );
636 });
637
638 it(`${description}should render entities with styles applied from the default class and other styles`, () => {
639 imgSnapshotTest(
640 `
641 erDiagram
642 c[CUSTOMER]
643 p[PERSON]:::blue
644 classDef blue stroke:lightblue, color: #0000FF
645 classDef default fill:pink
646 style c color:green
647 `,
648 { ...options }
649 );
650 });
651 });
652});
653