mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-11 19:39:43 +02:00
Initial parsing logic for ER diagrams
This commit is contained in:
77
src/diagrams/er/erDb.js
Normal file
77
src/diagrams/er/erDb.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { logger } from '../../logger';
|
||||||
|
|
||||||
|
let entities = {};
|
||||||
|
let relationships = [];
|
||||||
|
let title = '';
|
||||||
|
|
||||||
|
const Cardinality = {
|
||||||
|
ONLY_ONE_TO_ONE_OR_MORE : 'ONLY_ONE_TO_ONE_OR_MORE',
|
||||||
|
ONLY_ONE_TO_ZERO_OR_MORE : 'ONLY_ONE_TO_ZERO_OR_MORE',
|
||||||
|
ZERO_OR_ONE_TO_ZERO_OR_MORE : 'ZERO_OR_ONE_TO_ZERO_OR_MORE',
|
||||||
|
ZERO_OR_ONE_TO_ONE_OR_MORE : 'ZERO_OR_ONE_TO_ONE_OR_MORE',
|
||||||
|
ONE_OR_MORE_TO_ONLY_ONE : 'ONE_OR_MORE_TO_ONLY_ONE',
|
||||||
|
ZERO_OR_MORE_TO_ONLY_ONE : 'ZERO_OR_MORE_TO_ONLY_ONE',
|
||||||
|
ZERO_OR_MORE_TO_ZERO_OR_ONE : 'ZERO_OR_MORE_TO_ZERO_OR_ONE',
|
||||||
|
ONE_OR_MORE_TO_ZERO_OR_ONE : 'ONE_OR_MORE_TO_ZERO_OR_ONE',
|
||||||
|
ZERO_OR_ONE_TO_ONLY_ONE : 'ZERO_OR_ONE_TO_ONLY_ONE',
|
||||||
|
ONLY_ONE_TO_ONLY_ONE : 'ONLY_ONE_TO_ONLY_ONE',
|
||||||
|
ONLY_ONE_TO_ZERO_OR_ONE : 'ONLY_ONE_TO_ZERO_OR_ONE',
|
||||||
|
ZERO_OR_ONE_TO_ZERO_OR_ONE : 'ZERO_OR_ONE_TO_ZERO_OR_ONE',
|
||||||
|
ZERO_OR_MORE_TO_ZERO_OR_MORE: 'ZERO_OR_MORE_TO_ZERO_OR_MORE',
|
||||||
|
ZERO_OR_MORE_TO_ONE_OR_MORE : 'ZERO_OR_MORE_TO_ONE_OR_MORE',
|
||||||
|
ONE_OR_MORE_TO_ZERO_OR_MORE : 'ONE_OR_MORE_TO_ZERO_OR_MORE',
|
||||||
|
ONE_OR_MORE_TO_ONE_OR_MORE : 'ONE_OR_MORE_TO_ONE_OR_MORE'
|
||||||
|
};
|
||||||
|
|
||||||
|
const addEntity = function(name) {
|
||||||
|
if (typeof entities[name] === 'undefined') {
|
||||||
|
entities[name] = name;
|
||||||
|
logger.debug('Added new entity :', name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getEntities = () => entities;
|
||||||
|
|
||||||
|
const addRelationship = function(entA, rolA, entB, rolB, card) {
|
||||||
|
let rel = {
|
||||||
|
entityA : entA,
|
||||||
|
roleA : rolA,
|
||||||
|
entityB : entB,
|
||||||
|
roleB : rolB,
|
||||||
|
cardinality : card
|
||||||
|
};
|
||||||
|
|
||||||
|
relationships.push(rel);
|
||||||
|
logger.debug('Added new relationship :', rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRelationships = () => relationships;
|
||||||
|
|
||||||
|
// Keep this - TODO: revisit...allow the diagram to have a title
|
||||||
|
const setTitle = function(txt) {
|
||||||
|
title = txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTitle = function() {
|
||||||
|
return title;
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = function() {
|
||||||
|
entities = {};
|
||||||
|
relationships = [];
|
||||||
|
title = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Cardinality,
|
||||||
|
addEntity,
|
||||||
|
getEntities,
|
||||||
|
addRelationship,
|
||||||
|
getRelationships,
|
||||||
|
clear,
|
||||||
|
setTitle,
|
||||||
|
getTitle
|
||||||
|
};
|
84
src/diagrams/er/parser/erDiagram.jison
Normal file
84
src/diagrams/er/parser/erDiagram.jison
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
%lex
|
||||||
|
|
||||||
|
%x string
|
||||||
|
%options case-insensitive
|
||||||
|
|
||||||
|
%%
|
||||||
|
\s+ /* skip whitespace */
|
||||||
|
[\s]+ return 'SPACE';
|
||||||
|
["] { this.begin("string");}
|
||||||
|
<string>["] { this.popState(); }
|
||||||
|
<string>[^"]* { return 'STR'; }
|
||||||
|
"erDiagram" return 'ER_DIAGRAM';
|
||||||
|
[A-Za-z][A-Za-z0-9]* return 'ALPHANUM';
|
||||||
|
\>\?\-\?\< return 'ZERO_OR_MORE_TO_ZERO_OR_MORE';
|
||||||
|
\>\?\-\!\< return 'ZERO_OR_MORE_TO_ONE_OR_MORE';
|
||||||
|
\>\!\-\!\< return 'ONE_OR_MORE_TO_ONE_OR_MORE';
|
||||||
|
\>\!\-\?\< return 'ONE_OR_MORE_TO_ZERO_OR_MORE';
|
||||||
|
\!\-\!\< return 'ONLY_ONE_TO_ONE_OR_MORE';
|
||||||
|
\!\-\?\< return 'ONLY_ONE_TO_ZERO_OR_MORE';
|
||||||
|
\?\-\?\< return 'ZERO_OR_ONE_TO_ZERO_OR_MORE';
|
||||||
|
\?\-\!\< return 'ZERO_OR_ONE_TO_ONE_OR_MORE';
|
||||||
|
\>\!\-\! return 'ONE_OR_MORE_TO_ONLY_ONE';
|
||||||
|
\>\?\-\! return 'ZERO_OR_MORE_TO_ONLY_ONE';
|
||||||
|
\>\?\-\? return 'ZERO_OR_MORE_TO_ZERO_OR_ONE';
|
||||||
|
\>\!\-\? return 'ONE_OR_MORE_TO_ZERO_OR_ONE';
|
||||||
|
\?\-\! return 'ZERO_OR_ONE_TO_ONLY_ONE';
|
||||||
|
\!\-\! return 'ONLY_ONE_TO_ONLY_ONE';
|
||||||
|
\!\-\? return 'ONLY_ONE_TO_ZERO_OR_ONE';
|
||||||
|
\?\-\? return 'ZERO_OR_ONE_TO_ZERO_OR_ONE';
|
||||||
|
. return yytext[0];
|
||||||
|
<<EOF>> return 'EOF';
|
||||||
|
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
%start start
|
||||||
|
%% /* language grammar */
|
||||||
|
|
||||||
|
start
|
||||||
|
: 'ER_DIAGRAM' document 'EOF' { /*console.log('finished parsing');*/ }
|
||||||
|
;
|
||||||
|
|
||||||
|
document
|
||||||
|
: /* empty */
|
||||||
|
| document statement
|
||||||
|
;
|
||||||
|
|
||||||
|
statement
|
||||||
|
: entityName relationship entityName ':' role ',' role
|
||||||
|
{
|
||||||
|
yy.addEntity($1);
|
||||||
|
yy.addEntity($3);
|
||||||
|
yy.addRelationship($1, $5, $3, $7, $2);
|
||||||
|
/*console.log($1 + $2 + $3 + ':' + $5 + ',' + $7);*/
|
||||||
|
};
|
||||||
|
|
||||||
|
entityName
|
||||||
|
: 'ALPHANUM' { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
relationship
|
||||||
|
: 'ONLY_ONE_TO_ONE_OR_MORE' { $$ = yy.Cardinality.ONLY_ONE_TO_ONE_OR_MORE; }
|
||||||
|
| 'ONLY_ONE_TO_ZERO_OR_MORE' { $$ = yy.Cardinality.ONLY_ONE_TO_ZERO_OR_MORE; }
|
||||||
|
| 'ZERO_OR_ONE_TO_ZERO_OR_MORE' { $$ = yy.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_MORE; }
|
||||||
|
| 'ZERO_OR_ONE_TO_ONE_OR_MORE' { $$ = yy.Cardinality.ZERO_OR_ONE_TO_ONE_OR_MORE; }
|
||||||
|
| 'ONE_OR_MORE_TO_ONLY_ONE' { $$ = yy.Cardinality.ONE_OR_MORE_TO_ONLY_ONE; }
|
||||||
|
| 'ZERO_OR_MORE_TO_ONLY_ONE' { $$ = yy.Cardinality.ZERO_OR_MORE_TO_ONLY_ONE; }
|
||||||
|
| 'ZERO_OR_MORE_TO_ZERO_OR_ONE' { $$ = yy.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_ONE; }
|
||||||
|
| 'ONE_OR_MORE_TO_ZERO_OR_ONE' { $$ = yy.Cardinality.ONE_OR_MORE_TO_ZERO_OR_ONE; }
|
||||||
|
| 'ZERO_OR_ONE_TO_ONLY_ONE' { $$ = yy.Cardinality.ZERO_OR_ONE_TO_ONLY_ONE; }
|
||||||
|
| 'ONLY_ONE_TO_ONLY_ONE' { $$ = yy.Cardinality.ONLY_ONE_TO_ONLY_ONE; }
|
||||||
|
| 'ONLY_ONE_TO_ZERO_OR_ONE' { $$ = yy.Cardinality.ONLY_ONE_TO_ZERO_OR_ONE; }
|
||||||
|
| 'ZERO_OR_ONE_TO_ZERO_OR_ONE' { $$ = yy.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_ONE; }
|
||||||
|
| 'ZERO_OR_MORE_TO_ZERO_OR_MORE' { $$ = yy.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_MORE; }
|
||||||
|
| 'ZERO_OR_MORE_TO_ONE_OR_MORE' { $$ = yy.Cardinality.ZERO_OR_MORE_TO_ONE_OR_MORE; }
|
||||||
|
| 'ONE_OR_MORE_TO_ONE_OR_MORE' { $$ = yy.Cardinality.ONE_OR_MORE_TO_ONE_OR_MORE; }
|
||||||
|
| 'ONE_OR_MORE_TO_ZERO_OR_MORE' { $$ = yy.Cardinality.ONE_OR_MORE_TO_ZERO_OR_MORE; }
|
||||||
|
;
|
||||||
|
|
||||||
|
role
|
||||||
|
: 'STR' { $$ = $1; }
|
||||||
|
| 'ALPHANUM' { $$ = $1; }
|
||||||
|
;
|
||||||
|
%%
|
226
src/diagrams/er/parser/erDiagram.spec.js
Normal file
226
src/diagrams/er/parser/erDiagram.spec.js
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
import erDb from '../erDb';
|
||||||
|
import erDiagram from './erDiagram';
|
||||||
|
import { setConfig } from '../../../config';
|
||||||
|
import logger from '../../../logger';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
securityLevel: 'strict'
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when parsing ER diagram it...', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
erDiagram.parser.yy = erDb;
|
||||||
|
erDiagram.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should associate two entities correctly', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nCAR !-?< DRIVER : "insured for", "can drive"');
|
||||||
|
const entities = erDb.getEntities();
|
||||||
|
const relationships = erDb.getRelationships();
|
||||||
|
const carEntity = entities.CAR;
|
||||||
|
const driverEntity = entities.DRIVER;
|
||||||
|
|
||||||
|
expect(carEntity).toBe('CAR');
|
||||||
|
expect(driverEntity).toBe('DRIVER');
|
||||||
|
expect(relationships.length).toBe(1);
|
||||||
|
expect(relationships[0].cardinality).toBe(erDb.Cardinality.ONLY_ONE_TO_ZERO_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not create duplicate entities', function() {
|
||||||
|
const line1 = 'CAR !-?< DRIVER : "insured for", "can drive"';
|
||||||
|
const line2 = 'DRIVER !-! LICENSE : has, "belongs to"';
|
||||||
|
erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
|
||||||
|
const entities = erDb.getEntities();
|
||||||
|
|
||||||
|
expect(Object.keys(entities).length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create the roles specified', function() {
|
||||||
|
const teacherRole = 'is teacher of';
|
||||||
|
const studentRole = 'is student of';
|
||||||
|
const line1 = `TEACHER >?-?< STUDENT : "${teacherRole}", "${studentRole}"`;
|
||||||
|
erDiagram.parser.parse(`erDiagram\n${line1}`);
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(rels[0].roleA).toBe(`${teacherRole}`);
|
||||||
|
expect(rels[0].roleB).toBe(`${studentRole}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow recursive relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nNODE !-?< NODE : "leads to", "comes from"');
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow more than one relationship between the same two entities', function() {
|
||||||
|
const line1 = 'CAR !-?< PERSON : "insured for", "may drive"';
|
||||||
|
const line2 = 'CAR >?-! PERSON : "owned by", "owns"';
|
||||||
|
erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
|
||||||
|
const entities = erDb.getEntities();
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(entities).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should limit the number of relationships between the same two entities', function() {
|
||||||
|
/* TODO */
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should not allow relationships between the same two entities unless the roles are different', function() {
|
||||||
|
/* TODO */
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle only-one-to-one-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA !-!< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONLY_ONE_TO_ONE_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle only-one-to-zero-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA !-?< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONLY_ONE_TO_ZERO_OR_MORE);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-one-to-zero-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA ?-?< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-one-to-one-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA ?-!< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_ONE_TO_ONE_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle one-or-more-to-only-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >!-! B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONE_OR_MORE_TO_ONLY_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-more-to-only-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >?-! B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_MORE_TO_ONLY_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-more-to-zero-or-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >?-? B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle one-or-more-to-zero-or-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >!-? B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONE_OR_MORE_TO_ZERO_OR_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-one-to-only-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA ?-! B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_ONE_TO_ONLY_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle only-one-to-only-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA !-! B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONLY_ONE_TO_ONLY_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle only-one-to-zero-or-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA !-? B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONLY_ONE_TO_ZERO_OR_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-one-to-zero-or-one relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA ?-? B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_ONE_TO_ZERO_OR_ONE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-more-to-zero-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >?-?< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_MORE_TO_ZERO_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle one-or-more-to-one-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >!-!< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONE_OR_MORE_TO_ONE_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero-or-more-to-one-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >?-!< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ZERO_OR_MORE_TO_ONE_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle one-or-more-to-zero-or-more relationships', function() {
|
||||||
|
erDiagram.parser.parse('erDiagram\nA >!-?< B : has, has');
|
||||||
|
const rels = erDb.getRelationships();
|
||||||
|
|
||||||
|
expect(Object.keys(erDb.getEntities()).length).toBe(2);
|
||||||
|
expect(rels.length).toBe(1);
|
||||||
|
expect(rels[0].cardinality).toBe(erDb.Cardinality.ONE_OR_MORE_TO_ZERO_OR_MORE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not accept a syntax error', function() {
|
||||||
|
const doc = 'erDiagram\nA xxx B : has, has';
|
||||||
|
expect(() => {
|
||||||
|
erDiagram.parser.parse(doc);
|
||||||
|
}).toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Reference in New Issue
Block a user