mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-03 20:34:20 +01:00 
			
		
		
		
	First pass at a requirement diagram.
This commit is contained in:
		@@ -1,20 +1,19 @@
 | 
			
		||||
import { setConfig } from '../../../config';
 | 
			
		||||
import erDb from '../erDb';
 | 
			
		||||
import erDiagram from './erDiagram';
 | 
			
		||||
import { setConfig } from '../../../config';
 | 
			
		||||
import log from '../../../logger';
 | 
			
		||||
 | 
			
		||||
setConfig({
 | 
			
		||||
  securityLevel: 'strict'
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('when parsing ER diagram it...', function() {
 | 
			
		||||
describe('when parsing ER diagram it...', function () {
 | 
			
		||||
 | 
			
		||||
  beforeEach(function() {
 | 
			
		||||
  beforeEach(function () {
 | 
			
		||||
    erDiagram.parser.yy = erDb;
 | 
			
		||||
    erDiagram.parser.yy.clear();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it ('should allow stand-alone entities with no relationships', function() {
 | 
			
		||||
  it('should allow stand-alone entities with no relationships', function () {
 | 
			
		||||
    const line1 = 'ISLAND';
 | 
			
		||||
    const line2 = 'MAINLAND';
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
 | 
			
		||||
@@ -23,7 +22,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(erDb.getRelationships().length).toBe(0);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it ('should allow hyphens and underscores in entity names', function() {
 | 
			
		||||
  it('should allow hyphens and underscores in entity names', function () {
 | 
			
		||||
    const line1 = 'DUCK-BILLED-PLATYPUS';
 | 
			
		||||
    const line2 = 'CHARACTER_SET';
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
 | 
			
		||||
@@ -33,7 +32,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities.hasOwnProperty('CHARACTER_SET')).toBe(true);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an entity with a single attribute to be defined', function() {
 | 
			
		||||
  it('should allow an entity with a single attribute to be defined', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
    const attribute = 'string title';
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +42,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(1);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an entity with multiple attributes to be defined', function() {
 | 
			
		||||
  it('should allow an entity with multiple attributes to be defined', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
    const attribute1 = 'string title';
 | 
			
		||||
    const attribute2 = 'string author';
 | 
			
		||||
@@ -54,7 +53,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow attribute definitions to be split into multiple blocks', function() {
 | 
			
		||||
  it('should allow attribute definitions to be split into multiple blocks', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
    const attribute1 = 'string title';
 | 
			
		||||
    const attribute2 = 'string author';
 | 
			
		||||
@@ -65,7 +64,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an empty attribute block', function() {
 | 
			
		||||
  it('should allow an empty attribute block', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${entity} {}`);
 | 
			
		||||
@@ -74,7 +73,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(0);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an attribute block to start immediately after the entity name', function() {
 | 
			
		||||
  it('should allow an attribute block to start immediately after the entity name', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${entity}{}`);
 | 
			
		||||
@@ -83,7 +82,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(0);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an attribute block to be separated from the entity name by spaces', function() {
 | 
			
		||||
  it('should allow an attribute block to be separated from the entity name by spaces', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${entity}         {}`);
 | 
			
		||||
@@ -92,7 +91,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(0);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow whitespace before and after attribute definitions', function() {
 | 
			
		||||
  it('should allow whitespace before and after attribute definitions', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
    const attribute = 'string title';
 | 
			
		||||
 | 
			
		||||
@@ -102,7 +101,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(1);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow no whitespace before and after attribute definitions', function() {
 | 
			
		||||
  it('should allow no whitespace before and after attribute definitions', function () {
 | 
			
		||||
    const entity = 'BOOK';
 | 
			
		||||
    const attribute = 'string title';
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +111,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(entities[entity].attributes.length).toBe(1);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should associate two entities correctly', function() {
 | 
			
		||||
  it('should associate two entities correctly', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nCAR ||--o{ DRIVER : "insured for"');
 | 
			
		||||
    const entities = erDb.getEntities();
 | 
			
		||||
    const relationships = erDb.getRelationships();
 | 
			
		||||
@@ -125,7 +124,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(relationships[0].relSpec.relType).toBe(erDb.Identification.IDENTIFYING);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should not create duplicate entities', function() {
 | 
			
		||||
  it('should not create duplicate entities', function () {
 | 
			
		||||
    const line1 = 'CAR ||--o{ DRIVER : "insured for"';
 | 
			
		||||
    const line2 = 'DRIVER ||--|| LICENSE : has';
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
 | 
			
		||||
@@ -134,7 +133,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(Object.keys(entities).length).toBe(3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create the role specified', function() {
 | 
			
		||||
  it('should create the role specified', function () {
 | 
			
		||||
    const teacherRole = 'is teacher of';
 | 
			
		||||
    const line1 = `TEACHER }o--o{ STUDENT : "${teacherRole}"`;
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${line1}`);
 | 
			
		||||
@@ -143,32 +142,32 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].roleA).toBe(`${teacherRole}`);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow recursive relationships', function() {
 | 
			
		||||
  it('should allow recursive relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nNODE ||--o{ NODE : "leads to"');
 | 
			
		||||
    expect(Object.keys(erDb.getEntities()).length).toBe(1);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow more than one relationship between the same two entities', function() {
 | 
			
		||||
  it('should allow more than one relationship between the same two entities', function () {
 | 
			
		||||
    const line1 = 'CAR ||--o{ PERSON : "insured for"';
 | 
			
		||||
    const line2 = 'CAR }o--|| PERSON : "owned by"';
 | 
			
		||||
    erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);
 | 
			
		||||
    const entities = erDb.getEntities();
 | 
			
		||||
    const rels     = erDb.getRelationships();
 | 
			
		||||
    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() {
 | 
			
		||||
  it('should limit the number of relationships between the same two entities', function () {
 | 
			
		||||
    /* TODO */
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it ('should not allow multiple relationships between the same two entities unless the roles are different', function() {
 | 
			
		||||
  it('should not allow multiple relationships between the same two entities unless the roles are different', function () {
 | 
			
		||||
    /* TODO */
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  it('should handle only-one-to-one-or-more relationships', function() {
 | 
			
		||||
  it('should handle only-one-to-one-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA ||--|{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -178,7 +177,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONLY_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle only-one-to-zero-or-more relationships', function() {
 | 
			
		||||
  it('should handle only-one-to-zero-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA ||..o{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -189,7 +188,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-one-to-zero-or-more relationships', function() {
 | 
			
		||||
  it('should handle zero-or-one-to-zero-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA |o..o{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -199,7 +198,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-one-to-one-or-more relationships', function() {
 | 
			
		||||
  it('should handle zero-or-one-to-one-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA |o--|{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -209,7 +208,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle one-or-more-to-only-one relationships', function() {
 | 
			
		||||
  it('should handle one-or-more-to-only-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }|--|| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -219,7 +218,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-more-to-only-one relationships', function() {
 | 
			
		||||
  it('should handle zero-or-more-to-only-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }o--|| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -229,7 +228,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-more-to-zero-or-one relationships', function() {
 | 
			
		||||
  it('should handle zero-or-more-to-zero-or-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }o..o| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -239,7 +238,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle one-or-more-to-zero-or-one relationships', function() {
 | 
			
		||||
  it('should handle one-or-more-to-zero-or-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }|..o| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -249,7 +248,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-one-to-only-one relationships', function() {
 | 
			
		||||
  it('should handle zero-or-one-to-only-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA |o..|| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -259,7 +258,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle only-one-to-only-one relationships', function() {
 | 
			
		||||
  it('should handle only-one-to-only-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA ||..|| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -269,7 +268,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONLY_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle only-one-to-zero-or-one relationships', function() {
 | 
			
		||||
  it('should handle only-one-to-zero-or-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA ||--o| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -279,7 +278,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONLY_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-one-to-zero-or-one relationships', function() {
 | 
			
		||||
  it('should handle zero-or-one-to-zero-or-one relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA |o..o| B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -289,7 +288,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_ONE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-more-to-zero-or-more relationships', function() {
 | 
			
		||||
  it('should handle zero-or-more-to-zero-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }o--o{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -299,7 +298,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle one-or-more-to-one-or-more relationships', function() {
 | 
			
		||||
  it('should handle one-or-more-to-one-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }|..|{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -309,7 +308,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle zero-or-more-to-one-or-more relationships', function() {
 | 
			
		||||
  it('should handle zero-or-more-to-one-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }o--|{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -319,7 +318,7 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle one-or-more-to-zero-or-more relationships', function() {
 | 
			
		||||
  it('should handle one-or-more-to-zero-or-more relationships', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nA }|..o{ B : has');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
 | 
			
		||||
@@ -329,38 +328,38 @@ describe('when parsing ER diagram it...', function() {
 | 
			
		||||
    expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should represent identifying relationships properly', function() {
 | 
			
		||||
  it('should represent identifying relationships properly', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nHOUSE ||--|{ ROOM : contains');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
    expect(rels[0].relSpec.relType).toBe(erDb.Identification.IDENTIFYING);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should represent non-identifying relationships properly', function() {
 | 
			
		||||
  it('should represent non-identifying relationships properly', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\n PERSON ||..o{ POSSESSION : owns');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
    expect(rels[0].relSpec.relType).toBe(erDb.Identification.NON_IDENTIFYING);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should not accept a syntax error', function() {
 | 
			
		||||
  it('should not accept a syntax error', function () {
 | 
			
		||||
    const doc = 'erDiagram\nA xxx B : has';
 | 
			
		||||
    expect(() => {
 | 
			
		||||
      erDiagram.parser.parse(doc);
 | 
			
		||||
    }).toThrowError();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an empty quoted label', function() {
 | 
			
		||||
  it('should allow an empty quoted label', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : ""');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
    expect(rels[0].roleA).toBe('');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an non-empty quoted label', function() {
 | 
			
		||||
  it('should allow an non-empty quoted label', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : "places"');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
    expect(rels[0].roleA).toBe('places');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should allow an non-empty unquoted label', function() {
 | 
			
		||||
  it('should allow an non-empty unquoted label', function () {
 | 
			
		||||
    erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : places');
 | 
			
		||||
    const rels = erDb.getRelationships();
 | 
			
		||||
    expect(rels[0].roleA).toBe('places');
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user