Add integration tests, basic docs, and fix multi-diagram bug

This commit is contained in:
Adrian Hall 2020-03-18 16:53:26 +00:00
parent 3e76b2374c
commit d3f78299e7
3 changed files with 113 additions and 8 deletions

View File

@ -0,0 +1,92 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util';
describe('Entity Relationship Diagram', () => {
it('should render a simple ER diagram', () => {
imgSnapshotTest(
`
erDiagram
CUSTOMER !-?< ORDER : places
ORDER !-!< LINE-ITEM : contains
`,
{logLevel : 1}
);
cy.get('svg');
});
it('should render an ER diagram with a recursive relationship', () => {
imgSnapshotTest(
`
erDiagram
CUSTOMER !-?< CUSTOMER : refers
CUSTOMER !-?< ORDER : places
ORDER !-!< LINE-ITEM : contains
`,
{logLevel : 1}
);
cy.get('svg');
});
it('should render an ER diagram with multiple relationships between the same two entities', () => {
imgSnapshotTest(
`
erDiagram
CUSTOMER !-!< ADDRESS : "invoiced at"
CUSTOMER !-!< ADDRESS : "receives goods at"
`,
{logLevel : 1}
);
cy.get('svg');
});
it('should render a cyclical ER diagram', () => {
imgSnapshotTest(
`
erDiagram
A !-!< B : likes
B !-!< C : likes
C !-!< A : likes
`,
{logLevel : 1}
);
cy.get('svg');
});
it('should render a not-so-simple ER diagram', () => {
imgSnapshotTest(
`
erDiagram
DELIVERY-ADDRESS !-?< ORDER : receives
CUSTOMER >!-!< DELIVERY-ADDRESS : has
CUSTOMER !-?< ORDER : places
CUSTOMER !-?< INVOICE : "liable for"
INVOICE !-!< ORDER : covers
ORDER !-!< ORDER-ITEM : includes
PRODUCT-CATEGORY !-!< PRODUCT : contains
PRODUCT !-?< ORDER-ITEM : "ordered in"
`,
{logLevel : 1}
);
cy.get('svg');
});
it('should render multiple ER diagrams', () => {
imgSnapshotTest(
[
`
erDiagram
CUSTOMER !-?< ORDER : places
ORDER !-!< LINE-ITEM : contains
`,
`
erDiagram
CUSTOMER !-?< ORDER : places
ORDER !-!< LINE-ITEM : contains
`
],
{logLevel : 1}
);
cy.get('svg');
});
});

View File

@ -2,6 +2,8 @@
> An entityrelationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types). Wikipedia.
Note that practitioners of ER modelling almost always refer to entity types simply as entities. For example the CUSTOMER entity type would be referred to simply as the CUSTOMER entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract instance of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
Mermaid can render ER diagrams
```
erDiagram
@ -14,6 +16,14 @@ erDiagram
ORDER !-!< LINE-ITEM : contains
```
Entity names are often capitalised, although there is no accepted standard on this, and it is not required in Mermaid.
Relationships between entities are represented by lines with end markers representing cardinality. Mermaid uses the most popular crow's foot notation. The crow's foot intuitively conveys the possibility of many instances of the entity that it connects to.
## Status
ER diagrams are a new feature in Mermaid and are **experimental**. There are likely to be a few bugs and constraints, and enhancements will be made in due course.
## Syntax
### Entities and Relationships

View File

@ -86,14 +86,16 @@ const drawEntities = function(svgNode, entities, graph) {
const adjustEntities = function(svgNode, graph) {
graph.nodes().forEach(function(v) {
if (typeof v !== 'undefined' && typeof graph.node(v) !== 'undefined') {
d3.select('#' + v).attr(
'transform',
'translate(' +
(graph.node(v).x - graph.node(v).width / 2) +
',' +
(graph.node(v).y - graph.node(v).height / 2) +
' )'
);
svgNode
.select('#' + v)
.attr(
'transform',
'translate(' +
(graph.node(v).x - graph.node(v).width / 2) +
',' +
(graph.node(v).y - graph.node(v).height / 2) +
' )'
);
}
});
return;
@ -356,6 +358,7 @@ export const draw = function(text, id) {
marginx: 20,
marginy: 20,
nodesep: 100,
edgesep: 100,
ranksep: 100
})
.setDefaultEdgeLabel(function() {