collab/mermaid/cypress/integration/rendering/erDiagram.spec.jsblame
View source
6dd74de1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
6dd74de2
6dd74de3describe('Entity Relationship Diagram', () => {
6dd74de4 it('should render a simple ER diagram', () => {
6dd74de5 imgSnapshotTest(
6dd74de6 `
6dd74de7 erDiagram
6dd74de8 CUSTOMER ||--o{ ORDER : places
6dd74de9 ORDER ||--|{ LINE-ITEM : contains
6dd74de10 `,
6dd74de11 { logLevel: 1 }
6dd74de12 );
6dd74de13 });
6dd74de14
6dd74de15 it('should render an ER diagram with a recursive relationship', () => {
6dd74de16 imgSnapshotTest(
6dd74de17 `
6dd74de18 erDiagram
6dd74de19 CUSTOMER ||..o{ CUSTOMER : refers
6dd74de20 CUSTOMER ||--o{ ORDER : places
6dd74de21 ORDER ||--|{ LINE-ITEM : contains
6dd74de22 `,
6dd74de23 { logLevel: 1 }
6dd74de24 );
6dd74de25 });
6dd74de26
6dd74de27 it('should render an ER diagram with multiple relationships between the same two entities', () => {
6dd74de28 imgSnapshotTest(
6dd74de29 `
6dd74de30 erDiagram
6dd74de31 CUSTOMER ||--|{ ADDRESS : "invoiced at"
6dd74de32 CUSTOMER ||--|{ ADDRESS : "receives goods at"
6dd74de33 `,
6dd74de34 { logLevel: 1 }
6dd74de35 );
6dd74de36 });
6dd74de37
6dd74de38 it('should render a cyclical ER diagram', () => {
6dd74de39 imgSnapshotTest(
6dd74de40 `
6dd74de41 erDiagram
6dd74de42 A ||--|{ B : likes
6dd74de43 B ||--|{ C : likes
6dd74de44 C ||--|{ A : likes
6dd74de45 `,
6dd74de46 { logLevel: 1 }
6dd74de47 );
6dd74de48 });
6dd74de49
6dd74de50 it('should render a not-so-simple ER diagram', () => {
6dd74de51 imgSnapshotTest(
6dd74de52 `
6dd74de53 erDiagram
6dd74de54 CUSTOMER }|..|{ DELIVERY-ADDRESS : has
6dd74de55 CUSTOMER ||--o{ ORDER : places
6dd74de56 CUSTOMER ||--o{ INVOICE : "liable for"
6dd74de57 DELIVERY-ADDRESS ||--o{ ORDER : receives
6dd74de58 INVOICE ||--|{ ORDER : covers
6dd74de59 ORDER ||--|{ ORDER-ITEM : includes
6dd74de60 PRODUCT-CATEGORY ||--|{ PRODUCT : contains
6dd74de61 PRODUCT ||--o{ ORDER-ITEM : "ordered in"
6dd74de62 `,
6dd74de63 { logLevel: 1 }
6dd74de64 );
6dd74de65 });
6dd74de66
6dd74de67 it('should render multiple ER diagrams', () => {
6dd74de68 imgSnapshotTest(
6dd74de69 [
6dd74de70 `
6dd74de71 erDiagram
6dd74de72 CUSTOMER ||--o{ ORDER : places
6dd74de73 ORDER ||--|{ LINE-ITEM : contains
6dd74de74 `,
6dd74de75 `
6dd74de76 erDiagram
6dd74de77 CUSTOMER ||--o{ ORDER : places
6dd74de78 ORDER ||--|{ LINE-ITEM : contains
6dd74de79 `,
6dd74de80 ],
6dd74de81 { logLevel: 1 }
6dd74de82 );
6dd74de83 });
6dd74de84
6dd74de85 it('should render an ER diagram with blank or empty labels', () => {
6dd74de86 imgSnapshotTest(
6dd74de87 `
6dd74de88 erDiagram
6dd74de89 BOOK }|..|{ AUTHOR : ""
6dd74de90 BOOK }|..|{ GENRE : " "
6dd74de91 AUTHOR }|..|{ GENRE : " "
6dd74de92 `,
6dd74de93 { logLevel: 1 }
6dd74de94 );
6dd74de95 });
6dd74de96
6dd74de97 it('should render an ER diagrams when useMaxWidth is true (default)', () => {
6dd74de98 renderGraph(
6dd74de99 `
6dd74de100 erDiagram
6dd74de101 CUSTOMER ||--o{ ORDER : places
6dd74de102 ORDER ||--|{ LINE-ITEM : contains
6dd74de103 `,
6dd74de104 { er: { useMaxWidth: true } }
6dd74de105 );
6dd74de106 cy.get('svg').should((svg) => {
6dd74de107 expect(svg).to.have.attr('width', '100%');
6dd74de108 // expect(svg).to.have.attr('height', '465');
6dd74de109 const style = svg.attr('style');
6dd74de110 expect(style).to.match(/^max-width: [\d.]+px;$/);
6dd74de111 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
6dd74de112 // use within because the absolute value can be slightly different depending on the environment ±6%
6dd74de113 expect(maxWidthValue).to.be.within(140 * 0.96, 140 * 1.06);
6dd74de114 });
6dd74de115 });
6dd74de116
6dd74de117 it('should render an ER when useMaxWidth is false', () => {
6dd74de118 renderGraph(
6dd74de119 `
6dd74de120 erDiagram
6dd74de121 CUSTOMER ||--o{ ORDER : places
6dd74de122 ORDER ||--|{ LINE-ITEM : contains
6dd74de123 `,
6dd74de124 { er: { useMaxWidth: false } }
6dd74de125 );
6dd74de126 cy.get('svg').should((svg) => {
6dd74de127 const width = parseFloat(svg.attr('width'));
6dd74de128 // use within because the absolute value can be slightly different depending on the environment ±6%
6dd74de129 expect(width).to.be.within(140 * 0.96, 140 * 1.06);
6dd74de130 // expect(svg).to.have.attr('height', '465');
6dd74de131 expect(svg).to.not.have.attr('style');
6dd74de132 });
6dd74de133 });
6dd74de134
6dd74de135 it('should render entities that have no relationships', () => {
6dd74de136 renderGraph(
6dd74de137 `
6dd74de138 erDiagram
6dd74de139 DEAD_PARROT
6dd74de140 HERMIT
6dd74de141 RECLUSE
6dd74de142 SOCIALITE }o--o{ SOCIALITE : "interacts with"
6dd74de143 RECLUSE }o--o{ SOCIALITE : avoids
6dd74de144 `,
6dd74de145 { er: { useMaxWidth: false } }
6dd74de146 );
6dd74de147 });
6dd74de148
6dd74de149 it('should render entities with and without attributes', () => {
6dd74de150 renderGraph(
6dd74de151 `
6dd74de152 erDiagram
6dd74de153 BOOK { string title }
6dd74de154 AUTHOR }|..|{ BOOK : writes
6dd74de155 BOOK { float price }
6dd74de156 `,
6dd74de157 { logLevel: 1 }
6dd74de158 );
6dd74de159 });
6dd74de160
6dd74de161 it('should render entities with generic and array attributes', () => {
6dd74de162 renderGraph(
6dd74de163 `
6dd74de164 erDiagram
6dd74de165 BOOK {
6dd74de166 string title
6dd74de167 string[] authors
6dd74de168 type~T~ type
6dd74de169 }
6dd74de170 `,
6dd74de171 { logLevel: 1 }
6dd74de172 );
6dd74de173 });
6dd74de174
6dd74de175 it('should render entities with length in attributes type', () => {
6dd74de176 renderGraph(
6dd74de177 `
6dd74de178 erDiagram
6dd74de179 CLUSTER {
6dd74de180 varchar(99) name
6dd74de181 string(255) description
6dd74de182 }
6dd74de183 `,
6dd74de184 { logLevel: 1 }
6dd74de185 );
6dd74de186 });
6dd74de187
6dd74de188 it('should render entities and attributes with big and small entity names', () => {
6dd74de189 renderGraph(
6dd74de190 `
6dd74de191 erDiagram
6dd74de192 PRIVATE_FINANCIAL_INSTITUTION {
6dd74de193 string name
6dd74de194 int turnover
6dd74de195 }
6dd74de196 PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
6dd74de197 EMPLOYEE { bool officer_of_firm }
6dd74de198 `,
6dd74de199 { logLevel: 1 }
6dd74de200 );
6dd74de201 });
6dd74de202
6dd74de203 it('should render entities with attributes that begin with asterisk', () => {
6dd74de204 imgSnapshotTest(
6dd74de205 `
6dd74de206 erDiagram
6dd74de207 BOOK {
6dd74de208 int *id
6dd74de209 string name
6dd74de210 varchar(99) summary
6dd74de211 }
6dd74de212 BOOK }o..o{ STORE : soldBy
6dd74de213 STORE {
6dd74de214 int *id
6dd74de215 string name
6dd74de216 varchar(50) address
6dd74de217 }
6dd74de218 `,
6dd74de219 { loglevel: 1 }
6dd74de220 );
6dd74de221 });
6dd74de222
6dd74de223 it('should render entities with keys', () => {
6dd74de224 renderGraph(
6dd74de225 `
6dd74de226 erDiagram
6dd74de227 AUTHOR_WITH_LONG_ENTITY_NAME {
6dd74de228 string name PK
6dd74de229 }
6dd74de230 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
6dd74de231 BOOK {
6dd74de232 float price
6dd74de233 string author FK
6dd74de234 string title PK
6dd74de235 }
6dd74de236 `,
6dd74de237 { logLevel: 1 }
6dd74de238 );
6dd74de239 });
6dd74de240
6dd74de241 it('should render entities with comments', () => {
6dd74de242 renderGraph(
6dd74de243 `
6dd74de244 erDiagram
6dd74de245 AUTHOR_WITH_LONG_ENTITY_NAME {
6dd74de246 string name "comment"
6dd74de247 }
6dd74de248 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
6dd74de249 BOOK {
6dd74de250 string author
6dd74de251 string title "author comment"
6dd74de252 float price "price comment"
6dd74de253 }
6dd74de254 `,
6dd74de255 { logLevel: 1 }
6dd74de256 );
6dd74de257 });
6dd74de258
6dd74de259 it('should render entities with keys and comments', () => {
6dd74de260 renderGraph(
6dd74de261 `
6dd74de262 erDiagram
6dd74de263 AUTHOR_WITH_LONG_ENTITY_NAME {
6dd74de264 string name PK "comment"
6dd74de265 }
6dd74de266 AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
6dd74de267 BOOK {
6dd74de268 string description
6dd74de269 float price "price comment"
6dd74de270 string title PK "title comment"
6dd74de271 string author FK
6dd74de272 }
6dd74de273 `,
6dd74de274 { logLevel: 1 }
6dd74de275 );
6dd74de276 });
6dd74de277
6dd74de278 it('should render entities with aliases', () => {
6dd74de279 renderGraph(
6dd74de280 `
6dd74de281 erDiagram
6dd74de282 T1 one or zero to one or more T2 : test
6dd74de283 T2 one or many optionally to zero or one T3 : test
6dd74de284 T3 zero or more to zero or many T4 : test
6dd74de285 T4 many(0) to many(1) T5 : test
6dd74de286 T5 many optionally to one T6 : test
6dd74de287 T6 only one optionally to only one T1 : test
6dd74de288 T4 0+ to 1+ T6 : test
6dd74de289 T1 1 to 1 T3 : test
6dd74de290 `,
6dd74de291 { logLevel: 1 }
6dd74de292 );
6dd74de293 });
6dd74de294
6dd74de295 it('1433: should render a simple ER diagram with a title', () => {
6dd74de296 imgSnapshotTest(
6dd74de297 `---
6dd74de298title: simple ER diagram
6dd74de299---
6dd74de300erDiagram
6dd74de301CUSTOMER ||--o{ ORDER : places
6dd74de302ORDER ||--|{ LINE-ITEM : contains
6dd74de303`,
6dd74de304 {}
6dd74de305 );
6dd74de306 });
6dd74de307
6dd74de308 it('should render entities with entity name aliases', () => {
6dd74de309 imgSnapshotTest(
6dd74de310 `
6dd74de311 erDiagram
6dd74de312 p[Person] {
6dd74de313 varchar(64) firstName
6dd74de314 varchar(64) lastName
6dd74de315 }
6dd74de316 c["Customer Account"] {
6dd74de317 varchar(128) email
6dd74de318 }
6dd74de319 p ||--o| c : has
6dd74de320 `,
6dd74de321 { logLevel: 1 }
6dd74de322 );
6dd74de323 });
6dd74de324
6dd74de325 it('should render relationship labels with line breaks', () => {
6dd74de326 imgSnapshotTest(
6dd74de327 `
6dd74de328 erDiagram
6dd74de329 p[Person] {
6dd74de330 string firstName
6dd74de331 string lastName
6dd74de332 }
6dd74de333 a["Customer Account"] {
6dd74de334 string email
6dd74de335 }
6dd74de336
6dd74de337 b["Customer Account Secondary"] {
6dd74de338 string email
6dd74de339 }
6dd74de340
6dd74de341 c["Customer Account Tertiary"] {
6dd74de342 string email
6dd74de343 }
6dd74de344
6dd74de345 d["Customer Account Nth"] {
6dd74de346 string email
6dd74de347 }
6dd74de348
6dd74de349 p ||--o| a : "has<br />one"
6dd74de350 p ||--o| b : "has<br />one<br />two"
6dd74de351 p ||--o| c : "has<br />one<br/>two<br />three"
6dd74de352 p ||--o| d : "has<br />one<br />two<br/>three<br />...<br/>Nth"
6dd74de353 `,
6dd74de354 { logLevel: 1 }
6dd74de355 );
6dd74de356 });
6dd74de357
6dd74de358 describe('Include char sequence "graph" in text (#6795)', () => {
6dd74de359 it('has a label with char sequence "graph"', () => {
6dd74de360 imgSnapshotTest(
6dd74de361 `
6dd74de362 erDiagram
6dd74de363 p[Photograph] {
6dd74de364 varchar(12) jobId
6dd74de365 date dateCreated
6dd74de366 }
6dd74de367 `,
6dd74de368 { flowchart: { defaultRenderer: 'elk' } }
6dd74de369 );
6dd74de370 });
6dd74de371 });
6dd74de372
6dd74de373 describe('Special characters and numbers syntax', () => {
6dd74de374 it('should render ER diagram with numeric entity names', () => {
6dd74de375 imgSnapshotTest(
6dd74de376 `
6dd74de377 erDiagram
6dd74de378 1 ||--|| ORDER : places
6dd74de379 ORDER ||--|{ 2 : contains
6dd74de380 2 ||--o{ 3.5 : references
6dd74de381 `,
6dd74de382 { logLevel: 1 }
6dd74de383 );
6dd74de384 });
6dd74de385
6dd74de386 it('should render ER diagram with "u" character in entity names and cardinality', () => {
6dd74de387 imgSnapshotTest(
6dd74de388 `
6dd74de389 erDiagram
6dd74de390 CUSTOMER ||--|| u : has
6dd74de391 u ||--|| ORDER : places
6dd74de392 PROJECT u--o{ TEAM_MEMBER : "parent"
6dd74de393 `,
6dd74de394 { logLevel: 1 }
6dd74de395 );
6dd74de396 });
6dd74de397
6dd74de398 it('should render ER diagram with decimal numbers in relationships', () => {
6dd74de399 imgSnapshotTest(
6dd74de400 `
6dd74de401 erDiagram
6dd74de402 2.5 ||--|| 1.5 : has
6dd74de403 CUSTOMER ||--o{ 3.14 : references
6dd74de404 1.0 ||--|{ ORDER : contains
6dd74de405 `,
6dd74de406 { logLevel: 1 }
6dd74de407 );
6dd74de408 });
6dd74de409
6dd74de410 it('should render ER diagram with numeric entity names and attributes', () => {
6dd74de411 imgSnapshotTest(
6dd74de412 `
6dd74de413 erDiagram
6dd74de414 1 {
6dd74de415 string name
6dd74de416 int value
6dd74de417 }
6dd74de418 1 ||--|| ORDER : places
6dd74de419 ORDER {
6dd74de420 float price
6dd74de421 string description
6dd74de422 }
6dd74de423 `,
6dd74de424 { logLevel: 1 }
6dd74de425 );
6dd74de426 });
6dd74de427
6dd74de428 it('should render complex ER diagram with mixed special entity names', () => {
6dd74de429 imgSnapshotTest(
6dd74de430 `
6dd74de431 erDiagram
6dd74de432 CUSTOMER ||--o{ 1 : places
6dd74de433 1 ||--|{ u : contains
6dd74de434 1.5
6dd74de435 u ||--|| 2.5 : processes
6dd74de436 2.5 {
6dd74de437 string id
6dd74de438 float value
6dd74de439 }
6dd74de440 u {
6dd74de441 varchar(50) name
6dd74de442 int count
6dd74de443 }
6dd74de444 `,
6dd74de445 { logLevel: 1 }
6dd74de446 );
6dd74de447 });
6dd74de448 it('should render ER diagram with standalone numeric entities', () => {
6dd74de449 imgSnapshotTest(
6dd74de450 `erDiagram
6dd74de451 PRODUCT ||--o{ ORDER-ITEM : has
6dd74de452 1.5
6dd74de453 u
6dd74de454 1
6dd74de455 `,
6dd74de456 { logLevel: 1 }
6dd74de457 );
6dd74de458 });
6dd74de459 });
6dd74de460
6dd74de461 it('should render edge labels correctly when flowchart htmlLabels is false', () => {
6dd74de462 imgSnapshotTest(
6dd74de463 `
6dd74de464 erDiagram
6dd74de465 CUSTOMER ||--o{ ORDER : places
6dd74de466 ORDER ||--|{ LINE-ITEM : contains
6dd74de467 CUSTOMER ||--|{ ADDRESS : "invoiced at"
6dd74de468 CUSTOMER ||--|{ ADDRESS : "receives goods at"
6dd74de469 ORDER ||--o{ INVOICE : "liable for"
6dd74de470 `,
6dd74de471 { logLevel: 1, flowchart: { htmlLabels: false } }
6dd74de472 );
6dd74de473 });
6dd74de474
6dd74de475 it('should render ER diagram with "1" cardinality alias before relationship operators', () => {
6dd74de476 imgSnapshotTest(
6dd74de477 `
6dd74de478 erDiagram
6dd74de479 CUSTOMER 1--1 ORDER : "exactly one"
6dd74de480 ORDER 1--o{ LINE-ITEM : "one to many"
6dd74de481 PRODUCT 1--|{ CATEGORY : "one or more"
6dd74de482 USER 1..1 PROFILE : "exactly one optional"
6dd74de483 `,
6dd74de484 { logLevel: 1 }
6dd74de485 );
6dd74de486 });
6dd74de487
6dd74de488 it('should render ER diagram with "1" cardinality using all 4 relationship operator styles', () => {
6dd74de489 imgSnapshotTest(
6dd74de490 `
6dd74de491 erDiagram
6dd74de492 A 1--1 B : "solid-solid"
6dd74de493 C 1..1 D : "dotted-dotted"
6dd74de494 E 1.-1 F : "dotted-solid"
6dd74de495 G 1-.1 H : "solid-dotted"
6dd74de496 `,
6dd74de497 { logLevel: 1 }
6dd74de498 );
6dd74de499 });
6dd74de500});