diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 000000000..a1aed17d7
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "parserOptions": {
+ "ecmaFeatures": {
+ "experimentalObjectRestSpread": true,
+ "jsx": true
+ },
+ "sourceType": "module"
+ },
+ "extends": ["prettier"],
+ "plugins": ["prettier"],
+ "rules": {
+ "prettier/prettier": ["error"]
+ }
+}
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 000000000..5ac85e271
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "printWidth": 100,
+ "singleQuote": true
+}
diff --git a/package.json b/package.json
index d0e7a6a9b..5cd538f71 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
"build:watch": "yarn build --watch",
"minify": "minify ./dist/mermaid.js > ./dist/mermaid.min.js",
"release": "yarn build -p --config webpack.config.prod.babel.js",
- "lint": "standard",
+ "lint": "eslint src",
"e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js",
"cypress": "percy exec -- cypress run",
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
@@ -51,11 +51,15 @@
"dagre-d3-renderer": "^0.5.8",
"dagre-layout": "^0.8.8",
"documentation": "^12.0.1",
+ "eslint": "^6.3.0",
+ "eslint-config-prettier": "^6.3.0",
+ "eslint-plugin-prettier": "^3.1.0",
"graphlibrary": "^2.2.0",
"he": "^1.2.0",
"lodash": "^4.17.11",
"minify": "^4.1.1",
"moment-mini": "^2.22.1",
+ "prettier": "^1.18.2",
"scope-css": "^1.2.1"
},
"devDependencies": {
diff --git a/src/config.js b/src/config.js
index d288155ce..0b5df6e0c 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,28 +1,27 @@
-let config = {
-}
+let config = {};
-const setConf = function (cnf) {
+const setConf = function(cnf) {
// Top level initially mermaid, gflow, sequenceDiagram and gantt
- const lvl1Keys = Object.keys(cnf)
+ const lvl1Keys = Object.keys(cnf);
for (let i = 0; i < lvl1Keys.length; i++) {
if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {
- const lvl2Keys = Object.keys(cnf[lvl1Keys[i]])
+ const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]);
for (let j = 0; j < lvl2Keys.length; j++) {
// logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
if (typeof config[lvl1Keys[i]] === 'undefined') {
- config[lvl1Keys[i]] = {}
+ config[lvl1Keys[i]] = {};
}
// logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]])
- config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]
+ config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]];
}
} else {
- config[lvl1Keys[i]] = cnf[lvl1Keys[i]]
+ config[lvl1Keys[i]] = cnf[lvl1Keys[i]];
}
}
-}
+};
export const setConfig = conf => {
- setConf(conf)
-}
-export const getConfig = () => config
+ setConf(conf);
+};
+export const getConfig = () => config;
diff --git a/src/diagrams/class/classDb.js b/src/diagrams/class/classDb.js
index 227d95875..94ec0e21e 100644
--- a/src/diagrams/class/classDb.js
+++ b/src/diagrams/class/classDb.js
@@ -1,8 +1,7 @@
+import { logger } from '../../logger';
-import { logger } from '../../logger'
-
-let relations = []
-let classes = {}
+let relations = [];
+let classes = {};
/**
* Function called by parser when a node definition has been found.
@@ -11,75 +10,75 @@ let classes = {}
* @param type
* @param style
*/
-export const addClass = function (id) {
+export const addClass = function(id) {
if (typeof classes[id] === 'undefined') {
classes[id] = {
id: id,
methods: [],
members: []
- }
+ };
}
-}
+};
-export const clear = function () {
- relations = []
- classes = {}
-}
+export const clear = function() {
+ relations = [];
+ classes = {};
+};
-export const getClass = function (id) {
- return classes[id]
-}
-export const getClasses = function () {
- return classes
-}
+export const getClass = function(id) {
+ return classes[id];
+};
+export const getClasses = function() {
+ return classes;
+};
-export const getRelations = function () {
- return relations
-}
+export const getRelations = function() {
+ return relations;
+};
-export const addRelation = function (relation) {
- logger.debug('Adding relation: ' + JSON.stringify(relation))
- addClass(relation.id1)
- addClass(relation.id2)
- relations.push(relation)
-}
+export const addRelation = function(relation) {
+ logger.debug('Adding relation: ' + JSON.stringify(relation));
+ addClass(relation.id1);
+ addClass(relation.id2);
+ relations.push(relation);
+};
-export const addMember = function (className, member) {
- const theClass = classes[className]
+export const addMember = function(className, member) {
+ const theClass = classes[className];
if (typeof member === 'string') {
if (member.substr(-1) === ')') {
- theClass.methods.push(member)
+ theClass.methods.push(member);
} else {
- theClass.members.push(member)
+ theClass.members.push(member);
}
}
-}
+};
-export const addMembers = function (className, MembersArr) {
+export const addMembers = function(className, MembersArr) {
if (Array.isArray(MembersArr)) {
- MembersArr.forEach(member => addMember(className, member))
+ MembersArr.forEach(member => addMember(className, member));
}
-}
+};
-export const cleanupLabel = function (label) {
+export const cleanupLabel = function(label) {
if (label.substring(0, 1) === ':') {
- return label.substr(2).trim()
+ return label.substr(2).trim();
} else {
- return label.trim()
+ return label.trim();
}
-}
+};
export const lineType = {
LINE: 0,
DOTTED_LINE: 1
-}
+};
export const relationType = {
AGGREGATION: 0,
EXTENSION: 1,
COMPOSITION: 2,
DEPENDENCY: 3
-}
+};
export default {
addClass,
@@ -93,4 +92,4 @@ export default {
cleanupLabel,
lineType,
relationType
-}
+};
diff --git a/src/diagrams/class/classDiagram.spec.js b/src/diagrams/class/classDiagram.spec.js
index 38657e11d..154898907 100644
--- a/src/diagrams/class/classDiagram.spec.js
+++ b/src/diagrams/class/classDiagram.spec.js
@@ -1,208 +1,211 @@
/* eslint-env jasmine */
-import { parser } from './parser/classDiagram'
-import classDb from './classDb'
+import { parser } from './parser/classDiagram';
+import classDb from './classDb';
-describe('class diagram, ', function () {
- describe('when parsing an info graph it', function () {
- beforeEach(function () {
- parser.yy = classDb
- })
+describe('class diagram, ', function() {
+ describe('when parsing an info graph it', function() {
+ beforeEach(function() {
+ parser.yy = classDb;
+ });
- it('should handle relation definitions', function () {
- const str = 'classDiagram\n' +
-'Class01 <|-- Class02\n' +
-'Class03 *-- Class04\n' +
-'Class05 o-- Class06\n' +
-'Class07 .. Class08\n' +
-'Class09 -- Class1'
+ it('should handle relation definitions', function() {
+ const str =
+ 'classDiagram\n' +
+ 'Class01 <|-- Class02\n' +
+ 'Class03 *-- Class04\n' +
+ 'Class05 o-- Class06\n' +
+ 'Class07 .. Class08\n' +
+ 'Class09 -- Class1';
- parser.parse(str)
- })
- it('should handle relation definition of different types and directions', function () {
- const str = 'classDiagram\n' +
-'Class11 <|.. Class12\n' +
-'Class13 --> Class14\n' +
-'Class15 ..> Class16\n' +
-'Class17 ..|> Class18\n' +
-'Class19 <--* Class20'
+ parser.parse(str);
+ });
+ it('should handle relation definition of different types and directions', function() {
+ const str =
+ 'classDiagram\n' +
+ 'Class11 <|.. Class12\n' +
+ 'Class13 --> Class14\n' +
+ 'Class15 ..> Class16\n' +
+ 'Class17 ..|> Class18\n' +
+ 'Class19 <--* Class20';
- parser.parse(str)
- })
+ parser.parse(str);
+ });
- it('should handle cardinality and labels', function () {
- const str = 'classDiagram\n' +
-'Class01 "1" *-- "many" Class02 : contains\n' +
-'Class03 o-- Class04 : aggregation\n' +
-'Class05 --> "1" Class06'
+ it('should handle cardinality and labels', function() {
+ const str =
+ 'classDiagram\n' +
+ 'Class01 "1" *-- "many" Class02 : contains\n' +
+ 'Class03 o-- Class04 : aggregation\n' +
+ 'Class05 --> "1" Class06';
- parser.parse(str)
- })
- it('should handle class definitions', function () {
- const str = 'classDiagram\n' +
-'class Car\n' +
-'Driver -- Car : drives >\n' +
-'Car *-- Wheel : have 4 >\n' +
-'Car -- Person : < owns'
+ parser.parse(str);
+ });
+ it('should handle class definitions', function() {
+ const str =
+ 'classDiagram\n' +
+ 'class Car\n' +
+ 'Driver -- Car : drives >\n' +
+ 'Car *-- Wheel : have 4 >\n' +
+ 'Car -- Person : < owns';
- parser.parse(str)
- })
+ parser.parse(str);
+ });
- it('should handle method statements', function () {
- const str = 'classDiagram\n' +
-'Object <|-- ArrayList\n' +
-'Object : equals()\n' +
-'ArrayList : Object[] elementData\n' +
-'ArrayList : size()'
+ it('should handle method statements', function() {
+ const str =
+ 'classDiagram\n' +
+ 'Object <|-- ArrayList\n' +
+ 'Object : equals()\n' +
+ 'ArrayList : Object[] elementData\n' +
+ 'ArrayList : size()';
- parser.parse(str)
- })
- it('should handle parsing of method statements grouped by brackets', function () {
- const str = 'classDiagram\n' +
-'class Dummy {\n' +
-'String data\n' +
-' void methods()\n' +
-'}\n' +
-'\n' +
-'class Flight {\n' +
-' flightNumber : Integer\n' +
-' departureTime : Date\n' +
-'}'
+ parser.parse(str);
+ });
+ it('should handle parsing of method statements grouped by brackets', function() {
+ const str =
+ 'classDiagram\n' +
+ 'class Dummy {\n' +
+ 'String data\n' +
+ ' void methods()\n' +
+ '}\n' +
+ '\n' +
+ 'class Flight {\n' +
+ ' flightNumber : Integer\n' +
+ ' departureTime : Date\n' +
+ '}';
- parser.parse(str)
- })
+ parser.parse(str);
+ });
- it('should handle parsing of separators', function () {
- const str = 'classDiagram\n' +
- 'class Foo1 {\n' +
- ' You can use\n' +
- ' several lines\n' +
- '..\n' +
- 'as you want\n' +
- 'and group\n' +
- '==\n' +
- 'things together.\n' +
- '__\n' +
- 'You can have as many groups\n' +
- 'as you want\n' +
- '--\n' +
- 'End of class\n' +
- '}\n' +
- '\n' +
- 'class User {\n' +
- '.. Simple Getter ..\n' +
- '+ getName()\n' +
- '+ getAddress()\n' +
- '.. Some setter ..\n' +
- '+ setName()\n' +
- '__ private data __\n' +
- 'int age\n' +
- '-- encrypted --\n' +
- 'String password\n' +
- '}'
+ it('should handle parsing of separators', function() {
+ const str =
+ 'classDiagram\n' +
+ 'class Foo1 {\n' +
+ ' You can use\n' +
+ ' several lines\n' +
+ '..\n' +
+ 'as you want\n' +
+ 'and group\n' +
+ '==\n' +
+ 'things together.\n' +
+ '__\n' +
+ 'You can have as many groups\n' +
+ 'as you want\n' +
+ '--\n' +
+ 'End of class\n' +
+ '}\n' +
+ '\n' +
+ 'class User {\n' +
+ '.. Simple Getter ..\n' +
+ '+ getName()\n' +
+ '+ getAddress()\n' +
+ '.. Some setter ..\n' +
+ '+ setName()\n' +
+ '__ private data __\n' +
+ 'int age\n' +
+ '-- encrypted --\n' +
+ 'String password\n' +
+ '}';
- parser.parse(str)
- })
- })
+ parser.parse(str);
+ });
+ });
- describe('when fetching data from an classDiagram graph it', function () {
- beforeEach(function () {
- parser.yy = classDb
- parser.yy.clear()
- })
- it('should handle relation definitions EXTENSION', function () {
- const str = 'classDiagram\n' +
- 'Class01 <|-- Class02'
+ describe('when fetching data from an classDiagram graph it', function() {
+ beforeEach(function() {
+ parser.yy = classDb;
+ parser.yy.clear();
+ });
+ it('should handle relation definitions EXTENSION', function() {
+ const str = 'classDiagram\n' + 'Class01 <|-- Class02';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class02').id).toBe('Class02')
- expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
- expect(relations[0].relation.type2).toBe('none')
- expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
- })
- it('should handle relation definitions AGGREGATION and dotted line', function () {
- const str = 'classDiagram\n' +
- 'Class01 o.. Class02'
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class02').id).toBe('Class02');
+ expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION);
+ expect(relations[0].relation.type2).toBe('none');
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE);
+ });
+ it('should handle relation definitions AGGREGATION and dotted line', function() {
+ const str = 'classDiagram\n' + 'Class01 o.. Class02';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class02').id).toBe('Class02')
- expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION)
- expect(relations[0].relation.type2).toBe('none')
- expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
- })
- it('should handle relation definitions COMPOSITION on both sides', function () {
- const str = 'classDiagram\n' +
- 'Class01 *--* Class02'
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class02').id).toBe('Class02');
+ expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION);
+ expect(relations[0].relation.type2).toBe('none');
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE);
+ });
+ it('should handle relation definitions COMPOSITION on both sides', function() {
+ const str = 'classDiagram\n' + 'Class01 *--* Class02';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class02').id).toBe('Class02')
- expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION)
- expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION)
- expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
- })
- it('should handle relation definitions no types', function () {
- const str = 'classDiagram\n' +
- 'Class01 -- Class02'
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class02').id).toBe('Class02');
+ expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION);
+ expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION);
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE);
+ });
+ it('should handle relation definitions no types', function() {
+ const str = 'classDiagram\n' + 'Class01 -- Class02';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class02').id).toBe('Class02')
- expect(relations[0].relation.type1).toBe('none')
- expect(relations[0].relation.type2).toBe('none')
- expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
- })
- it('should handle relation definitions with type only on right side', function () {
- const str = 'classDiagram\n' +
- 'Class01 --|> Class02'
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class02').id).toBe('Class02');
+ expect(relations[0].relation.type1).toBe('none');
+ expect(relations[0].relation.type2).toBe('none');
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE);
+ });
+ it('should handle relation definitions with type only on right side', function() {
+ const str = 'classDiagram\n' + 'Class01 --|> Class02';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class02').id).toBe('Class02')
- expect(relations[0].relation.type1).toBe('none')
- expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION)
- expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
- })
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class02').id).toBe('Class02');
+ expect(relations[0].relation.type1).toBe('none');
+ expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION);
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE);
+ });
- it('should handle multiple classes and relation definitions', function () {
- const str = 'classDiagram\n' +
- 'Class01 <|-- Class02\n' +
- 'Class03 *-- Class04\n' +
- 'Class05 o-- Class06\n' +
- 'Class07 .. Class08\n' +
- 'Class09 -- Class10'
+ it('should handle multiple classes and relation definitions', function() {
+ const str =
+ 'classDiagram\n' +
+ 'Class01 <|-- Class02\n' +
+ 'Class03 *-- Class04\n' +
+ 'Class05 o-- Class06\n' +
+ 'Class07 .. Class08\n' +
+ 'Class09 -- Class10';
- parser.parse(str)
+ parser.parse(str);
- const relations = parser.yy.getRelations()
+ const relations = parser.yy.getRelations();
- expect(parser.yy.getClass('Class01').id).toBe('Class01')
- expect(parser.yy.getClass('Class10').id).toBe('Class10')
+ expect(parser.yy.getClass('Class01').id).toBe('Class01');
+ expect(parser.yy.getClass('Class10').id).toBe('Class10');
- expect(relations.length).toBe(5)
+ expect(relations.length).toBe(5);
- expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
- expect(relations[0].relation.type2).toBe('none')
- expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
- expect(relations[3].relation.type1).toBe('none')
- expect(relations[3].relation.type2).toBe('none')
- expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
- })
- })
-})
+ expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION);
+ expect(relations[0].relation.type2).toBe('none');
+ expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE);
+ expect(relations[3].relation.type1).toBe('none');
+ expect(relations[3].relation.type2).toBe('none');
+ expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE);
+ });
+ });
+});
diff --git a/src/diagrams/class/classRenderer.js b/src/diagrams/class/classRenderer.js
index a64bae1be..37a6629ae 100644
--- a/src/diagrams/class/classRenderer.js
+++ b/src/diagrams/class/classRenderer.js
@@ -1,38 +1,38 @@
-import * as d3 from 'd3'
-import dagre from 'dagre-layout'
-import graphlib from 'graphlibrary'
-import { logger } from '../../logger'
-import classDb from './classDb'
-import { parser } from './parser/classDiagram'
+import * as d3 from 'd3';
+import dagre from 'dagre-layout';
+import graphlib from 'graphlibrary';
+import { logger } from '../../logger';
+import classDb from './classDb';
+import { parser } from './parser/classDiagram';
-parser.yy = classDb
+parser.yy = classDb;
-const idCache = {}
+const idCache = {};
-let classCnt = 0
+let classCnt = 0;
const conf = {
dividerMargin: 10,
padding: 5,
textHeight: 10
-}
+};
// Todo optimize
-const getGraphId = function (label) {
- const keys = Object.keys(idCache)
+const getGraphId = function(label) {
+ const keys = Object.keys(idCache);
for (let i = 0; i < keys.length; i++) {
if (idCache[keys[i]].label === label) {
- return keys[i]
+ return keys[i];
}
}
- return undefined
-}
+ return undefined;
+};
/**
* Setup arrow head and define the marker. The result is appended to the svg.
*/
-const insertMarkers = function (elem) {
+const insertMarkers = function(elem) {
elem
.append('defs')
.append('marker')
@@ -44,7 +44,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 1,7 L18,13 V 1 Z')
+ .attr('d', 'M 1,7 L18,13 V 1 Z');
elem
.append('defs')
@@ -56,7 +56,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead
+ .attr('d', 'M 1,1 V 13 L18,7 Z'); // this is actual shape for arrowhead
elem
.append('defs')
@@ -69,7 +69,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
+ .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z');
elem
.append('defs')
@@ -81,7 +81,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
+ .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z');
elem
.append('defs')
@@ -94,7 +94,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
+ .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z');
elem
.append('defs')
@@ -106,7 +106,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
+ .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z');
elem
.append('defs')
@@ -119,7 +119,7 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z')
+ .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z');
elem
.append('defs')
@@ -131,96 +131,86 @@ const insertMarkers = function (elem) {
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z')
-}
+ .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
+};
-let edgeCount = 0
-let total = 0
-const drawEdge = function (elem, path, relation) {
- const getRelationType = function (type) {
+let edgeCount = 0;
+let total = 0;
+const drawEdge = function(elem, path, relation) {
+ const getRelationType = function(type) {
switch (type) {
case classDb.relationType.AGGREGATION:
- return 'aggregation'
+ return 'aggregation';
case classDb.relationType.EXTENSION:
- return 'extension'
+ return 'extension';
case classDb.relationType.COMPOSITION:
- return 'composition'
+ return 'composition';
case classDb.relationType.DEPENDENCY:
- return 'dependency'
+ return 'dependency';
}
- }
+ };
- path.points = path.points.filter(p => !Number.isNaN(p.y))
+ path.points = path.points.filter(p => !Number.isNaN(p.y));
// The data for our line
- const lineData = path.points
+ const lineData = path.points;
// This is the accessor function we talked about above
const lineFunction = d3
.line()
- .x(function (d) {
- return d.x
+ .x(function(d) {
+ return d.x;
})
- .y(function (d) {
- return d.y
+ .y(function(d) {
+ return d.y;
})
- .curve(d3.curveBasis)
+ .curve(d3.curveBasis);
const svgPath = elem
.append('path')
.attr('d', lineFunction(lineData))
.attr('id', 'edge' + edgeCount)
- .attr('class', 'relation')
- let url = ''
+ .attr('class', 'relation');
+ let url = '';
if (conf.arrowMarkerAbsolute) {
url =
window.location.protocol +
'//' +
window.location.host +
window.location.pathname +
- window.location.search
- url = url.replace(/\(/g, '\\(')
- url = url.replace(/\)/g, '\\)')
+ window.location.search;
+ url = url.replace(/\(/g, '\\(');
+ url = url.replace(/\)/g, '\\)');
}
if (relation.relation.type1 !== 'none') {
svgPath.attr(
'marker-start',
- 'url(' +
- url +
- '#' +
- getRelationType(relation.relation.type1) +
- 'Start' +
- ')'
- )
+ 'url(' + url + '#' + getRelationType(relation.relation.type1) + 'Start' + ')'
+ );
}
if (relation.relation.type2 !== 'none') {
svgPath.attr(
'marker-end',
- 'url(' +
- url +
- '#' +
- getRelationType(relation.relation.type2) +
- 'End' +
- ')'
- )
+ 'url(' + url + '#' + getRelationType(relation.relation.type2) + 'End' + ')'
+ );
}
- let x, y
- const l = path.points.length
+ let x, y;
+ const l = path.points.length;
if (l % 2 !== 0 && l > 1) {
- const p1 = path.points[Math.floor(l / 2)]
- const p2 = path.points[Math.ceil(l / 2)]
- x = (p1.x + p2.x) / 2
- y = (p1.y + p2.y) / 2
+ const p1 = path.points[Math.floor(l / 2)];
+ const p2 = path.points[Math.ceil(l / 2)];
+ x = (p1.x + p2.x) / 2;
+ y = (p1.y + p2.y) / 2;
} else {
- const p = path.points[Math.floor(l / 2)]
- x = p.x
- y = p.y
+ const p = path.points[Math.floor(l / 2)];
+ x = p.x;
+ y = p.y;
}
if (typeof relation.title !== 'undefined') {
- const g = elem.append('g').attr('class', 'classLabel')
+ const g = elem.append('g').attr('class', 'classLabel');
const label = g
.append('text')
.attr('class', 'label')
@@ -228,189 +218,177 @@ const drawEdge = function (elem, path, relation) {
.attr('y', y)
.attr('fill', 'red')
.attr('text-anchor', 'middle')
- .text(relation.title)
+ .text(relation.title);
- window.label = label
- const bounds = label.node().getBBox()
+ window.label = label;
+ const bounds = label.node().getBBox();
g.insert('rect', ':first-child')
.attr('class', 'box')
.attr('x', bounds.x - conf.padding / 2)
.attr('y', bounds.y - conf.padding / 2)
.attr('width', bounds.width + conf.padding)
- .attr('height', bounds.height + conf.padding)
+ .attr('height', bounds.height + conf.padding);
}
- edgeCount++
-}
+ edgeCount++;
+};
-const drawClass = function (elem, classDef) {
- logger.info('Rendering class ' + classDef)
+const drawClass = function(elem, classDef) {
+ logger.info('Rendering class ' + classDef);
- const addTspan = function (textEl, txt, isFirst) {
+ const addTspan = function(textEl, txt, isFirst) {
const tSpan = textEl
.append('tspan')
.attr('x', conf.padding)
- .text(txt)
+ .text(txt);
if (!isFirst) {
- tSpan.attr('dy', conf.textHeight)
+ tSpan.attr('dy', conf.textHeight);
}
- }
+ };
- const id = 'classId' + (classCnt % total)
+ const id = 'classId' + (classCnt % total);
const classInfo = {
id: id,
label: classDef.id,
width: 0,
height: 0
- }
+ };
const g = elem
.append('g')
.attr('id', id)
- .attr('class', 'classGroup')
+ .attr('class', 'classGroup');
const title = g
.append('text')
.attr('x', conf.padding)
.attr('y', conf.textHeight + conf.padding)
- .text(classDef.id)
+ .text(classDef.id);
- const titleHeight = title.node().getBBox().height
+ const titleHeight = title.node().getBBox().height;
const membersLine = g
.append('line') // text label for the x axis
.attr('x1', 0)
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
- .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
+ .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2);
const members = g
.append('text') // text label for the x axis
.attr('x', conf.padding)
.attr('y', titleHeight + conf.dividerMargin + conf.textHeight)
.attr('fill', 'white')
- .attr('class', 'classText')
+ .attr('class', 'classText');
- let isFirst = true
- classDef.members.forEach(function (member) {
- addTspan(members, member, isFirst)
- isFirst = false
- })
+ let isFirst = true;
+ classDef.members.forEach(function(member) {
+ addTspan(members, member, isFirst);
+ isFirst = false;
+ });
- const membersBox = members.node().getBBox()
+ const membersBox = members.node().getBBox();
const methodsLine = g
.append('line') // text label for the x axis
.attr('x1', 0)
- .attr(
- 'y1',
- conf.padding + titleHeight + conf.dividerMargin + membersBox.height
- )
- .attr(
- 'y2',
- conf.padding + titleHeight + conf.dividerMargin + membersBox.height
- )
+ .attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
+ .attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height);
const methods = g
.append('text') // text label for the x axis
.attr('x', conf.padding)
- .attr(
- 'y',
- titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight
- )
+ .attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
.attr('fill', 'white')
- .attr('class', 'classText')
+ .attr('class', 'classText');
- isFirst = true
+ isFirst = true;
- classDef.methods.forEach(function (method) {
- addTspan(methods, method, isFirst)
- isFirst = false
- })
+ classDef.methods.forEach(function(method) {
+ addTspan(methods, method, isFirst);
+ isFirst = false;
+ });
- const classBox = g.node().getBBox()
+ const classBox = g.node().getBBox();
g.insert('rect', ':first-child')
.attr('x', 0)
.attr('y', 0)
.attr('width', classBox.width + 2 * conf.padding)
- .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
+ .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin);
- membersLine.attr('x2', classBox.width + 2 * conf.padding)
- methodsLine.attr('x2', classBox.width + 2 * conf.padding)
+ membersLine.attr('x2', classBox.width + 2 * conf.padding);
+ methodsLine.attr('x2', classBox.width + 2 * conf.padding);
- classInfo.width = classBox.width + 2 * conf.padding
- classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin
+ classInfo.width = classBox.width + 2 * conf.padding;
+ classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin;
- idCache[id] = classInfo
- classCnt++
- return classInfo
-}
+ idCache[id] = classInfo;
+ classCnt++;
+ return classInfo;
+};
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
- keys.forEach(function (key) {
- conf[key] = cnf[key]
- })
-}
+ keys.forEach(function(key) {
+ conf[key] = cnf[key];
+ });
+};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text
* @param id
*/
-export const draw = function (text, id) {
- parser.yy.clear()
- parser.parse(text)
+export const draw = function(text, id) {
+ parser.yy.clear();
+ parser.parse(text);
- logger.info('Rendering diagram ' + text)
+ logger.info('Rendering diagram ' + text);
/// / Fetch the default direction, use TD if none was found
- const diagram = d3.select(`[id='${id}']`)
- insertMarkers(diagram)
+ const diagram = d3.select(`[id='${id}']`);
+ insertMarkers(diagram);
// Layout graph, Create a new directed graph
const g = new graphlib.Graph({
multigraph: true
- })
+ });
// Set an object for the graph label
g.setGraph({
isMultiGraph: true
- })
+ });
// Default to assigning a new object as a label for each new edge.
- g.setDefaultEdgeLabel(function () {
- return {}
- })
+ g.setDefaultEdgeLabel(function() {
+ return {};
+ });
- const classes = classDb.getClasses()
- const keys = Object.keys(classes)
- total = keys.length
+ const classes = classDb.getClasses();
+ const keys = Object.keys(classes);
+ total = keys.length;
for (let i = 0; i < keys.length; i++) {
- const classDef = classes[keys[i]]
- const node = drawClass(diagram, classDef)
+ const classDef = classes[keys[i]];
+ const node = drawClass(diagram, classDef);
// Add nodes to the graph. The first argument is the node id. The second is
// metadata about the node. In this case we're going to add labels to each of
// our nodes.
- g.setNode(node.id, node)
- logger.info('Org height: ' + node.height)
+ g.setNode(node.id, node);
+ logger.info('Org height: ' + node.height);
}
- const relations = classDb.getRelations()
- relations.forEach(function (relation) {
+ const relations = classDb.getRelations();
+ relations.forEach(function(relation) {
logger.info(
- 'tjoho' +
- getGraphId(relation.id1) +
- getGraphId(relation.id2) +
- JSON.stringify(relation)
- )
+ 'tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation)
+ );
g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), {
relation: relation
- })
- })
- dagre.layout(g)
- g.nodes().forEach(function (v) {
+ });
+ });
+ dagre.layout(g);
+ g.nodes().forEach(function(v) {
if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') {
- logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)))
+ logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)));
d3.select('#' + v).attr(
'transform',
'translate(' +
@@ -418,27 +396,22 @@ export const draw = function (text, id) {
',' +
(g.node(v).y - g.node(v).height / 2) +
' )'
- )
+ );
}
- })
- g.edges().forEach(function (e) {
+ });
+ g.edges().forEach(function(e) {
if (typeof e !== 'undefined' && typeof g.edge(e) !== 'undefined') {
- logger.debug(
- 'Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))
- )
- drawEdge(diagram, g.edge(e), g.edge(e).relation)
+ logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)));
+ drawEdge(diagram, g.edge(e), g.edge(e).relation);
}
- })
+ });
- diagram.attr('height', '100%')
- diagram.attr('width', '100%')
- diagram.attr(
- 'viewBox',
- '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20)
- )
-}
+ diagram.attr('height', '100%');
+ diagram.attr('width', '100%');
+ diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20));
+};
export default {
setConf,
draw
-}
+};
diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js
index b9e397eca..8928ad42f 100644
--- a/src/diagrams/flowchart/flowDb.js
+++ b/src/diagrams/flowchart/flowDb.js
@@ -1,33 +1,33 @@
-import * as d3 from 'd3'
-import { sanitizeUrl } from '@braintree/sanitize-url'
-import { logger } from '../../logger'
-import utils from '../../utils'
-import { getConfig } from '../../config'
+import * as d3 from 'd3';
+import { sanitizeUrl } from '@braintree/sanitize-url';
+import { logger } from '../../logger';
+import utils from '../../utils';
+import { getConfig } from '../../config';
-const config = getConfig()
-let vertices = {}
-let edges = []
-let classes = []
-let subGraphs = []
-let subGraphLookup = {}
-let tooltips = {}
-let subCount = 0
-let direction
+const config = getConfig();
+let vertices = {};
+let edges = [];
+let classes = [];
+let subGraphs = [];
+let subGraphLookup = {};
+let tooltips = {};
+let subCount = 0;
+let direction;
// Functions to be run after graph rendering
-let funs = []
+let funs = [];
const sanitize = text => {
- let txt = text
+ let txt = text;
if (config.securityLevel !== 'loose') {
- txt = txt.replace(/
/g, '#br#')
- txt = txt.replace(/
/g, '#br#')
- txt = txt.replace(//g, '>')
- txt = txt.replace(/=/g, '=')
- txt = txt.replace(/#br#/g, '
')
+ txt = txt.replace(/
/g, '#br#');
+ txt = txt.replace(/
/g, '#br#');
+ txt = txt.replace(//g, '>');
+ txt = txt.replace(/=/g, '=');
+ txt = txt.replace(/#br#/g, '
');
}
- return txt
-}
+ return txt;
+};
/**
* Function called by parser when a node definition has been found
@@ -37,53 +37,53 @@ const sanitize = text => {
* @param style
* @param classes
*/
-export const addVertex = function (_id, text, type, style, classes) {
- let txt
- let id = _id
+export const addVertex = function(_id, text, type, style, classes) {
+ let txt;
+ let id = _id;
if (typeof id === 'undefined') {
- return
+ return;
}
if (id.trim().length === 0) {
- return
+ return;
}
- if (id[0].match(/\d/)) id = 's' + id
+ if (id[0].match(/\d/)) id = 's' + id;
if (typeof vertices[id] === 'undefined') {
- vertices[id] = { id: id, styles: [], classes: [] }
+ vertices[id] = { id: id, styles: [], classes: [] };
}
if (typeof text !== 'undefined') {
- txt = sanitize(text.trim())
+ txt = sanitize(text.trim());
// strip quotes if string starts and exnds with a quote
if (txt[0] === '"' && txt[txt.length - 1] === '"') {
- txt = txt.substring(1, txt.length - 1)
+ txt = txt.substring(1, txt.length - 1);
}
- vertices[id].text = txt
+ vertices[id].text = txt;
} else {
if (!vertices[id].text) {
- vertices[id].text = _id
+ vertices[id].text = _id;
}
}
if (typeof type !== 'undefined') {
- vertices[id].type = type
+ vertices[id].type = type;
}
if (typeof style !== 'undefined') {
if (style !== null) {
- style.forEach(function (s) {
- vertices[id].styles.push(s)
- })
+ style.forEach(function(s) {
+ vertices[id].styles.push(s);
+ });
}
}
if (typeof classes !== 'undefined') {
if (classes !== null) {
- classes.forEach(function (s) {
- vertices[id].classes.push(s)
- })
+ classes.forEach(function(s) {
+ vertices[id].classes.push(s);
+ });
}
}
-}
+};
/**
* Function called by parser when a link/edge definition has been found
@@ -92,134 +92,138 @@ export const addVertex = function (_id, text, type, style, classes) {
* @param type
* @param linktext
*/
-export const addLink = function (_start, _end, type, linktext) {
- let start = _start
- let end = _end
- if (start[0].match(/\d/)) start = 's' + start
- if (end[0].match(/\d/)) end = 's' + end
- logger.info('Got edge...', start, end)
+export const addLink = function(_start, _end, type, linktext) {
+ let start = _start;
+ let end = _end;
+ if (start[0].match(/\d/)) start = 's' + start;
+ if (end[0].match(/\d/)) end = 's' + end;
+ logger.info('Got edge...', start, end);
- const edge = { start: start, end: end, type: undefined, text: '' }
- linktext = type.text
+ const edge = { start: start, end: end, type: undefined, text: '' };
+ linktext = type.text;
if (typeof linktext !== 'undefined') {
- edge.text = sanitize(linktext.trim())
+ edge.text = sanitize(linktext.trim());
// strip quotes if string starts and exnds with a quote
if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
- edge.text = edge.text.substring(1, edge.text.length - 1)
+ edge.text = edge.text.substring(1, edge.text.length - 1);
}
}
if (typeof type !== 'undefined') {
- edge.type = type.type
- edge.stroke = type.stroke
+ edge.type = type.type;
+ edge.stroke = type.stroke;
}
- edges.push(edge)
-}
+ edges.push(edge);
+};
/**
* Updates a link's line interpolation algorithm
* @param pos
* @param interpolate
*/
-export const updateLinkInterpolate = function (positions, interp) {
- positions.forEach(function (pos) {
+export const updateLinkInterpolate = function(positions, interp) {
+ positions.forEach(function(pos) {
if (pos === 'default') {
- edges.defaultInterpolate = interp
+ edges.defaultInterpolate = interp;
} else {
- edges[pos].interpolate = interp
+ edges[pos].interpolate = interp;
}
- })
-}
+ });
+};
/**
* Updates a link with a style
* @param pos
* @param style
*/
-export const updateLink = function (positions, style) {
- positions.forEach(function (pos) {
+export const updateLink = function(positions, style) {
+ positions.forEach(function(pos) {
if (pos === 'default') {
- edges.defaultStyle = style
+ edges.defaultStyle = style;
} else {
if (utils.isSubstringInArray('fill', style) === -1) {
- style.push('fill:none')
+ style.push('fill:none');
}
- edges[pos].style = style
+ edges[pos].style = style;
}
- })
-}
+ });
+};
-export const addClass = function (id, style) {
+export const addClass = function(id, style) {
if (typeof classes[id] === 'undefined') {
- classes[id] = { id: id, styles: [] }
+ classes[id] = { id: id, styles: [] };
}
if (typeof style !== 'undefined') {
if (style !== null) {
- style.forEach(function (s) {
- classes[id].styles.push(s)
- })
+ style.forEach(function(s) {
+ classes[id].styles.push(s);
+ });
}
}
-}
+};
/**
* Called by parser when a graph definition is found, stores the direction of the chart.
* @param dir
*/
-export const setDirection = function (dir) {
- direction = dir
-}
+export const setDirection = function(dir) {
+ direction = dir;
+};
/**
* Called by parser when a special node is found, e.g. a clickable element.
* @param ids Comma separated list of ids
* @param className Class to add
*/
-export const setClass = function (ids, className) {
- ids.split(',').forEach(function (_id) {
- let id = _id
- if (_id[0].match(/\d/)) id = 's' + id
+export const setClass = function(ids, className) {
+ ids.split(',').forEach(function(_id) {
+ let id = _id;
+ if (_id[0].match(/\d/)) id = 's' + id;
if (typeof vertices[id] !== 'undefined') {
- vertices[id].classes.push(className)
+ vertices[id].classes.push(className);
}
if (typeof subGraphLookup[id] !== 'undefined') {
- subGraphLookup[id].classes.push(className)
+ subGraphLookup[id].classes.push(className);
}
- })
-}
+ });
+};
-const setTooltip = function (ids, tooltip) {
- ids.split(',').forEach(function (id) {
+const setTooltip = function(ids, tooltip) {
+ ids.split(',').forEach(function(id) {
if (typeof tooltip !== 'undefined') {
- tooltips[id] = sanitize(tooltip)
+ tooltips[id] = sanitize(tooltip);
}
- })
-}
+ });
+};
-const setClickFun = function (_id, functionName) {
- let id = _id
- if (_id[0].match(/\d/)) id = 's' + id
+const setClickFun = function(_id, functionName) {
+ let id = _id;
+ if (_id[0].match(/\d/)) id = 's' + id;
if (config.securityLevel !== 'loose') {
- return
+ return;
}
if (typeof functionName === 'undefined') {
- return
+ return;
}
if (typeof vertices[id] !== 'undefined') {
- funs.push(function (element) {
- const elem = document.querySelector(`[id="${id}"]`)
+ funs.push(function(element) {
+ const elem = document.querySelector(`[id="${id}"]`);
if (elem !== null) {
- elem.addEventListener('click', function () {
- window[functionName](id)
- }, false)
+ elem.addEventListener(
+ 'click',
+ function() {
+ window[functionName](id);
+ },
+ false
+ );
}
- })
+ });
}
-}
+};
/**
* Called by parser when a link is found. Adds the URL to the vertex data.
@@ -227,24 +231,24 @@ const setClickFun = function (_id, functionName) {
* @param linkStr URL to create a link for
* @param tooltip Tooltip for the clickable element
*/
-export const setLink = function (ids, linkStr, tooltip) {
- ids.split(',').forEach(function (_id) {
- let id = _id
- if (_id[0].match(/\d/)) id = 's' + id
+export const setLink = function(ids, linkStr, tooltip) {
+ ids.split(',').forEach(function(_id) {
+ let id = _id;
+ if (_id[0].match(/\d/)) id = 's' + id;
if (typeof vertices[id] !== 'undefined') {
if (config.securityLevel !== 'loose') {
- vertices[id].link = sanitizeUrl(linkStr) // .replace(/javascript:.*/g, '')
+ vertices[id].link = sanitizeUrl(linkStr); // .replace(/javascript:.*/g, '')
} else {
- vertices[id].link = linkStr
+ vertices[id].link = linkStr;
}
}
- })
- setTooltip(ids, tooltip)
- setClass(ids, 'clickable')
-}
-export const getTooltip = function (id) {
- return tooltips[id]
-}
+ });
+ setTooltip(ids, tooltip);
+ setClass(ids, 'clickable');
+};
+export const getTooltip = function(id) {
+ return tooltips[id];
+};
/**
* Called by parser when a click definition is found. Registers an event handler.
@@ -252,209 +256,219 @@ export const getTooltip = function (id) {
* @param functionName Function to be called on click
* @param tooltip Tooltip for the clickable element
*/
-export const setClickEvent = function (ids, functionName, tooltip) {
- ids.split(',').forEach(function (id) { setClickFun(id, functionName) })
- setTooltip(ids, tooltip)
- setClass(ids, 'clickable')
-}
+export const setClickEvent = function(ids, functionName, tooltip) {
+ ids.split(',').forEach(function(id) {
+ setClickFun(id, functionName);
+ });
+ setTooltip(ids, tooltip);
+ setClass(ids, 'clickable');
+};
-export const bindFunctions = function (element) {
- funs.forEach(function (fun) {
- fun(element)
- })
-}
-export const getDirection = function () {
- return direction
-}
+export const bindFunctions = function(element) {
+ funs.forEach(function(fun) {
+ fun(element);
+ });
+};
+export const getDirection = function() {
+ return direction;
+};
/**
* Retrieval function for fetching the found nodes after parsing has completed.
* @returns {{}|*|vertices}
*/
-export const getVertices = function () {
- return vertices
-}
+export const getVertices = function() {
+ return vertices;
+};
/**
* Retrieval function for fetching the found links after parsing has completed.
* @returns {{}|*|edges}
*/
-export const getEdges = function () {
- return edges
-}
+export const getEdges = function() {
+ return edges;
+};
/**
* Retrieval function for fetching the found class definitions after parsing has completed.
* @returns {{}|*|classes}
*/
-export const getClasses = function () {
- return classes
-}
+export const getClasses = function() {
+ return classes;
+};
-const setupToolTips = function (element) {
- let tooltipElem = d3.select('.mermaidTooltip')
+const setupToolTips = function(element) {
+ let tooltipElem = d3.select('.mermaidTooltip');
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
- tooltipElem = d3.select('body')
+ tooltipElem = d3
+ .select('body')
.append('div')
.attr('class', 'mermaidTooltip')
- .style('opacity', 0)
+ .style('opacity', 0);
}
- const svg = d3.select(element).select('svg')
+ const svg = d3.select(element).select('svg');
- const nodes = svg.selectAll('g.node')
+ const nodes = svg.selectAll('g.node');
nodes
- .on('mouseover', function () {
- const el = d3.select(this)
- const title = el.attr('title')
+ .on('mouseover', function() {
+ const el = d3.select(this);
+ const title = el.attr('title');
// Dont try to draw a tooltip if no data is provided
if (title === null) {
- return
+ return;
}
- const rect = this.getBoundingClientRect()
+ const rect = this.getBoundingClientRect();
- tooltipElem.transition()
+ tooltipElem
+ .transition()
.duration(200)
- .style('opacity', '.9')
- tooltipElem.html(el.attr('title'))
- .style('left', (rect.left + (rect.right - rect.left) / 2) + 'px')
- .style('top', (rect.top - 14 + document.body.scrollTop) + 'px')
- el.classed('hover', true)
+ .style('opacity', '.9');
+ tooltipElem
+ .html(el.attr('title'))
+ .style('left', rect.left + (rect.right - rect.left) / 2 + 'px')
+ .style('top', rect.top - 14 + document.body.scrollTop + 'px');
+ el.classed('hover', true);
})
- .on('mouseout', function () {
- tooltipElem.transition()
+ .on('mouseout', function() {
+ tooltipElem
+ .transition()
.duration(500)
- .style('opacity', 0)
- const el = d3.select(this)
- el.classed('hover', false)
- })
-}
-funs.push(setupToolTips)
+ .style('opacity', 0);
+ const el = d3.select(this);
+ el.classed('hover', false);
+ });
+};
+funs.push(setupToolTips);
/**
* Clears the internal graph db so that a new graph can be parsed.
*/
-export const clear = function () {
- vertices = {}
- classes = {}
- edges = []
- funs = []
- funs.push(setupToolTips)
- subGraphs = []
- subGraphLookup = {}
- subCount = 0
- tooltips = []
-}
+export const clear = function() {
+ vertices = {};
+ classes = {};
+ edges = [];
+ funs = [];
+ funs.push(setupToolTips);
+ subGraphs = [];
+ subGraphLookup = {};
+ subCount = 0;
+ tooltips = [];
+};
/**
*
* @returns {string}
*/
-export const defaultStyle = function () {
- return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;'
-}
+export const defaultStyle = function() {
+ return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;';
+};
/**
* Clears the internal graph db so that a new graph can be parsed.
*/
-export const addSubGraph = function (_id, list, _title) {
- let id = _id
- let title = _title
+export const addSubGraph = function(_id, list, _title) {
+ let id = _id;
+ let title = _title;
if (_id === _title && _title.match(/\s/)) {
- id = undefined
+ id = undefined;
}
- function uniq (a) {
- const prims = { 'boolean': {}, 'number': {}, 'string': {} }
- const objs = []
+ function uniq(a) {
+ const prims = { boolean: {}, number: {}, string: {} };
+ const objs = [];
- return a.filter(function (item) {
- const type = typeof item
+ return a.filter(function(item) {
+ const type = typeof item;
if (item.trim() === '') {
- return false
+ return false;
}
- if (type in prims) { return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true) } else { return objs.indexOf(item) >= 0 ? false : objs.push(item) }
- })
+ if (type in prims) {
+ return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
+ } else {
+ return objs.indexOf(item) >= 0 ? false : objs.push(item);
+ }
+ });
}
- let nodeList = []
+ let nodeList = [];
- nodeList = uniq(nodeList.concat.apply(nodeList, list))
+ nodeList = uniq(nodeList.concat.apply(nodeList, list));
for (let i = 0; i < nodeList.length; i++) {
- if (nodeList[i][0].match(/\d/)) nodeList[i] = 's' + nodeList[i]
+ if (nodeList[i][0].match(/\d/)) nodeList[i] = 's' + nodeList[i];
}
- id = id || ('subGraph' + subCount)
- if (id[0].match(/\d/)) id = 's' + id
- title = title || ''
- title = sanitize(title)
- subCount = subCount + 1
- const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] }
- subGraphs.push(subGraph)
- subGraphLookup[id] = subGraph
- return id
-}
+ id = id || 'subGraph' + subCount;
+ if (id[0].match(/\d/)) id = 's' + id;
+ title = title || '';
+ title = sanitize(title);
+ subCount = subCount + 1;
+ const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] };
+ subGraphs.push(subGraph);
+ subGraphLookup[id] = subGraph;
+ return id;
+};
-const getPosForId = function (id) {
+const getPosForId = function(id) {
for (let i = 0; i < subGraphs.length; i++) {
if (subGraphs[i].id === id) {
- return i
+ return i;
}
}
- return -1
-}
-let secCount = -1
-const posCrossRef = []
-const indexNodes2 = function (id, pos) {
- const nodes = subGraphs[pos].nodes
- secCount = secCount + 1
+ return -1;
+};
+let secCount = -1;
+const posCrossRef = [];
+const indexNodes2 = function(id, pos) {
+ const nodes = subGraphs[pos].nodes;
+ secCount = secCount + 1;
if (secCount > 2000) {
- return
+ return;
}
- posCrossRef[secCount] = pos
+ posCrossRef[secCount] = pos;
// Check if match
if (subGraphs[pos].id === id) {
return {
result: true,
count: 0
- }
+ };
}
- let count = 0
- let posCount = 1
+ let count = 0;
+ let posCount = 1;
while (count < nodes.length) {
- const childPos = getPosForId(nodes[count])
+ const childPos = getPosForId(nodes[count]);
// Ignore regular nodes (pos will be -1)
if (childPos >= 0) {
- const res = indexNodes2(id, childPos)
+ const res = indexNodes2(id, childPos);
if (res.result) {
return {
result: true,
count: posCount + res.count
- }
+ };
} else {
- posCount = posCount + res.count
+ posCount = posCount + res.count;
}
}
- count = count + 1
+ count = count + 1;
}
return {
result: false,
count: posCount
- }
-}
+ };
+};
-export const getDepthFirstPos = function (pos) {
- return posCrossRef[pos]
-}
-export const indexNodes = function () {
- secCount = -1
+export const getDepthFirstPos = function(pos) {
+ return posCrossRef[pos];
+};
+export const indexNodes = function() {
+ secCount = -1;
if (subGraphs.length > 0) {
- indexNodes2('none', subGraphs.length - 1, 0)
+ indexNodes2('none', subGraphs.length - 1, 0);
}
-}
+};
-export const getSubGraphs = function () {
- return subGraphs
-}
+export const getSubGraphs = function() {
+ return subGraphs;
+};
export default {
addVertex,
@@ -478,4 +492,4 @@ export default {
getDepthFirstPos,
indexNodes,
getSubGraphs
-}
+};
diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js
index 3df7a6ad9..ef696a8f7 100644
--- a/src/diagrams/flowchart/flowRenderer.js
+++ b/src/diagrams/flowchart/flowRenderer.js
@@ -1,274 +1,288 @@
-import graphlib from 'graphlibrary'
-import * as d3 from 'd3'
+import graphlib from 'graphlibrary';
+import * as d3 from 'd3';
-import flowDb from './flowDb'
-import flow from './parser/flow'
-import { getConfig } from '../../config'
-import dagreD3 from 'dagre-d3-renderer'
-import addHtmlLabel from 'dagre-d3-renderer/lib/label/add-html-label.js'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
+import flowDb from './flowDb';
+import flow from './parser/flow';
+import { getConfig } from '../../config';
+import dagreD3 from 'dagre-d3-renderer';
+import addHtmlLabel from 'dagre-d3-renderer/lib/label/add-html-label.js';
+import { logger } from '../../logger';
+import { interpolateToCurve } from '../../utils';
-const conf = {
-}
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+const conf = {};
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
for (let i = 0; i < keys.length; i++) {
- conf[keys[i]] = cnf[keys[i]]
+ conf[keys[i]] = cnf[keys[i]];
}
-}
+};
/**
* Function that adds the vertices found in the graph definition to the graph to be rendered.
* @param vert Object containing the vertices.
* @param g The graph that is to be drawn.
*/
-export const addVertices = function (vert, g, svgId) {
- const svg = d3.select(`[id="${svgId}"]`)
- const keys = Object.keys(vert)
+export const addVertices = function(vert, g, svgId) {
+ const svg = d3.select(`[id="${svgId}"]`);
+ const keys = Object.keys(vert);
- const styleFromStyleArr = function (styleStr, arr, { label }) {
+ const styleFromStyleArr = function(styleStr, arr, { label }) {
if (!label) {
- // Create a compound style definition from the style definitions found for the node in the graph definition
+ // Create a compound style definition from the style definitions found for the node in the graph definition
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] !== 'undefined') {
- styleStr = styleStr + arr[i] + ';'
+ styleStr = styleStr + arr[i] + ';';
}
}
} else {
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] !== 'undefined') {
- if (arr[i].match('^color:')) styleStr = styleStr + arr[i] + ';'
+ if (arr[i].match('^color:')) styleStr = styleStr + arr[i] + ';';
}
}
}
- return styleStr
- }
+ return styleStr;
+ };
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
- keys.forEach(function (id) {
- const vertex = vert[id]
+ keys.forEach(function(id) {
+ const vertex = vert[id];
/**
* Variable for storing the classes for the vertex
* @type {string}
*/
- let classStr = ''
+ let classStr = '';
if (vertex.classes.length > 0) {
- classStr = vertex.classes.join(' ')
+ classStr = vertex.classes.join(' ');
}
/**
* Variable for storing the extracted style for the vertex
* @type {string}
*/
- let style = ''
+ let style = '';
// Create a compound style definition from the style definitions found for the node in the graph definition
- style = styleFromStyleArr(style, vertex.styles, { label: false })
- let labelStyle = ''
- labelStyle = styleFromStyleArr(labelStyle, vertex.styles, { label: true })
+ style = styleFromStyleArr(style, vertex.styles, { label: false });
+ let labelStyle = '';
+ labelStyle = styleFromStyleArr(labelStyle, vertex.styles, { label: true });
// Use vertex id as text in the box if no text is provided by the graph definition
- let vertexText = vertex.text !== undefined ? vertex.text : vertex.id
+ let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
// We create a SVG label, either by delegating to addHtmlLabel or manually
- let vertexNode
+ let vertexNode;
if (getConfig().flowchart.htmlLabels) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
- const node = { label: vertexText.replace(/fa[lrsb]?:fa-[\w-]+/g, s => ``) }
- vertexNode = addHtmlLabel(svg, node).node()
- vertexNode.parentNode.removeChild(vertexNode)
+ const node = {
+ label: vertexText.replace(
+ /fa[lrsb]?:fa-[\w-]+/g,
+ s => ``
+ )
+ };
+ vertexNode = addHtmlLabel(svg, node).node();
+ vertexNode.parentNode.removeChild(vertexNode);
} else {
- const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text')
+ const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- const rows = vertexText.split(/
/)
+ const rows = vertexText.split(/
/);
for (let j = 0; j < rows.length; j++) {
- const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')
- tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve')
- tspan.setAttribute('dy', '1em')
- tspan.setAttribute('x', '1')
- tspan.textContent = rows[j]
- svgLabel.appendChild(tspan)
+ const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
+ tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+ tspan.setAttribute('dy', '1em');
+ tspan.setAttribute('x', '1');
+ tspan.textContent = rows[j];
+ svgLabel.appendChild(tspan);
}
- vertexNode = svgLabel
+ vertexNode = svgLabel;
}
// If the node has a link, we wrap it in a SVG link
if (vertex.link) {
- const link = document.createElementNS('http://www.w3.org/2000/svg', 'a')
- link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link)
- link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener')
- link.appendChild(vertexNode)
- vertexNode = link
+ const link = document.createElementNS('http://www.w3.org/2000/svg', 'a');
+ link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
+ link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
+ link.appendChild(vertexNode);
+ vertexNode = link;
}
- let radious = 0
- let _shape = ''
+ let radious = 0;
+ let _shape = '';
// Set the shape based parameters
switch (vertex.type) {
case 'round':
- radious = 5
- _shape = 'rect'
- break
+ radious = 5;
+ _shape = 'rect';
+ break;
case 'square':
- _shape = 'rect'
- break
+ _shape = 'rect';
+ break;
case 'diamond':
- _shape = 'question'
- break
+ _shape = 'question';
+ break;
case 'odd':
- _shape = 'rect_left_inv_arrow'
- break
+ _shape = 'rect_left_inv_arrow';
+ break;
case 'lean_right':
- _shape = 'lean_right'
- break
+ _shape = 'lean_right';
+ break;
case 'lean_left':
- _shape = 'lean_left'
- break
+ _shape = 'lean_left';
+ break;
case 'trapezoid':
- _shape = 'trapezoid'
- break
+ _shape = 'trapezoid';
+ break;
case 'inv_trapezoid':
- _shape = 'inv_trapezoid'
- break
+ _shape = 'inv_trapezoid';
+ break;
case 'odd_right':
- _shape = 'rect_left_inv_arrow'
- break
+ _shape = 'rect_left_inv_arrow';
+ break;
case 'circle':
- _shape = 'circle'
- break
+ _shape = 'circle';
+ break;
case 'ellipse':
- _shape = 'ellipse'
- break
+ _shape = 'ellipse';
+ break;
case 'group':
- _shape = 'rect'
- break
+ _shape = 'rect';
+ break;
default:
- _shape = 'rect'
+ _shape = 'rect';
}
// Add the node
- g.setNode(vertex.id, { labelType: 'svg', labelStyle: labelStyle, shape: _shape, label: vertexNode, rx: radious, ry: radious, 'class': classStr, style: style, id: vertex.id })
- })
-}
+ g.setNode(vertex.id, {
+ labelType: 'svg',
+ labelStyle: labelStyle,
+ shape: _shape,
+ label: vertexNode,
+ rx: radious,
+ ry: radious,
+ class: classStr,
+ style: style,
+ id: vertex.id
+ });
+ });
+};
/**
* Add edges to graph based on parsed graph defninition
* @param {Object} edges The edges to add to the graph
* @param {Object} g The graph object
*/
-export const addEdges = function (edges, g) {
- let cnt = 0
+export const addEdges = function(edges, g) {
+ let cnt = 0;
- let defaultStyle
+ let defaultStyle;
if (typeof edges.defaultStyle !== 'undefined') {
- defaultStyle = edges.defaultStyle.toString().replace(/,/g, ';')
+ defaultStyle = edges.defaultStyle.toString().replace(/,/g, ';');
}
- edges.forEach(function (edge) {
- cnt++
- const edgeData = {}
+ edges.forEach(function(edge) {
+ cnt++;
+ const edgeData = {};
// Set link type for rendering
if (edge.type === 'arrow_open') {
- edgeData.arrowhead = 'none'
+ edgeData.arrowhead = 'none';
} else {
- edgeData.arrowhead = 'normal'
+ edgeData.arrowhead = 'normal';
}
- let style = ''
+ let style = '';
if (typeof edge.style !== 'undefined') {
- edge.style.forEach(function (s) {
- style = style + s + ';'
- })
+ edge.style.forEach(function(s) {
+ style = style + s + ';';
+ });
} else {
switch (edge.stroke) {
case 'normal':
- style = 'fill:none'
+ style = 'fill:none';
if (typeof defaultStyle !== 'undefined') {
- style = defaultStyle
+ style = defaultStyle;
}
- break
+ break;
case 'dotted':
- style = 'stroke: #333; fill:none;stroke-width:2px;stroke-dasharray:3;'
- break
+ style = 'stroke: #333; fill:none;stroke-width:2px;stroke-dasharray:3;';
+ break;
case 'thick':
- style = 'stroke: #333; stroke-width: 3.5px;fill:none'
- break
+ style = 'stroke: #333; stroke-width: 3.5px;fill:none';
+ break;
}
}
- edgeData.style = style
+ edgeData.style = style;
if (typeof edge.interpolate !== 'undefined') {
- edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear)
+ edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear);
} else if (typeof edges.defaultInterpolate !== 'undefined') {
- edgeData.curve = interpolateToCurve(edges.defaultInterpolate, d3.curveLinear)
+ edgeData.curve = interpolateToCurve(edges.defaultInterpolate, d3.curveLinear);
} else {
- edgeData.curve = interpolateToCurve(conf.curve, d3.curveLinear)
+ edgeData.curve = interpolateToCurve(conf.curve, d3.curveLinear);
}
if (typeof edge.text === 'undefined') {
if (typeof edge.style !== 'undefined') {
- edgeData.arrowheadStyle = 'fill: #333'
+ edgeData.arrowheadStyle = 'fill: #333';
}
} else {
- edgeData.arrowheadStyle = 'fill: #333'
+ edgeData.arrowheadStyle = 'fill: #333';
if (typeof edge.style === 'undefined') {
- edgeData.labelpos = 'c'
+ edgeData.labelpos = 'c';
if (getConfig().flowchart.htmlLabels) {
- edgeData.labelType = 'html'
- edgeData.label = '' + edge.text + ''
+ edgeData.labelType = 'html';
+ edgeData.label = '' + edge.text + '';
} else {
- edgeData.labelType = 'text'
- edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none'
- edgeData.label = edge.text.replace(/
/g, '\n')
+ edgeData.labelType = 'text';
+ edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none';
+ edgeData.label = edge.text.replace(/
/g, '\n');
}
} else {
- edgeData.label = edge.text.replace(/
/g, '\n')
+ edgeData.label = edge.text.replace(/
/g, '\n');
}
}
// Add the edge to the graph
- g.setEdge(edge.start, edge.end, edgeData, cnt)
- })
-}
+ g.setEdge(edge.start, edge.end, edgeData, cnt);
+ });
+};
/**
* Returns the all the styles from classDef statements in the graph definition.
* @returns {object} classDef styles
*/
-export const getClasses = function (text) {
- logger.info('Extracting classes')
- flowDb.clear()
- const parser = flow.parser
- parser.yy = flowDb
+export const getClasses = function(text) {
+ logger.info('Extracting classes');
+ flowDb.clear();
+ const parser = flow.parser;
+ parser.yy = flowDb;
// Parse the graph definition
- parser.parse(text)
- return flowDb.getClasses()
-}
+ parser.parse(text);
+ return flowDb.getClasses();
+};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text
* @param id
*/
-export const draw = function (text, id) {
- logger.info('Drawing flowchart')
- flowDb.clear()
- const parser = flow.parser
- parser.yy = flowDb
+export const draw = function(text, id) {
+ logger.info('Drawing flowchart');
+ flowDb.clear();
+ const parser = flow.parser;
+ parser.yy = flowDb;
// Parse the graph definition
try {
- parser.parse(text)
+ parser.parse(text);
} catch (err) {
- logger.debug('Parsing failed')
+ logger.debug('Parsing failed');
}
// Fetch the default direction, use TD if none was found
- let dir = flowDb.getDirection()
+ let dir = flowDb.getDirection();
if (typeof dir === 'undefined') {
- dir = 'TD'
+ dir = 'TD';
}
// Create the input mermaid.graph
@@ -280,196 +294,238 @@ export const draw = function (text, id) {
rankdir: dir,
marginx: 20,
marginy: 20
-
- })
- .setDefaultEdgeLabel(function () {
- return {}
})
+ .setDefaultEdgeLabel(function() {
+ return {};
+ });
- let subG
- const subGraphs = flowDb.getSubGraphs()
+ let subG;
+ const subGraphs = flowDb.getSubGraphs();
for (let i = subGraphs.length - 1; i >= 0; i--) {
- subG = subGraphs[i]
- flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes)
+ subG = subGraphs[i];
+ flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes);
}
// Fetch the verices/nodes and edges/links from the parsed graph definition
- const vert = flowDb.getVertices()
+ const vert = flowDb.getVertices();
- const edges = flowDb.getEdges()
+ const edges = flowDb.getEdges();
- let i = 0
+ let i = 0;
for (i = subGraphs.length - 1; i >= 0; i--) {
- subG = subGraphs[i]
+ subG = subGraphs[i];
- d3.selectAll('cluster').append('text')
+ d3.selectAll('cluster').append('text');
for (let j = 0; j < subG.nodes.length; j++) {
- g.setParent(subG.nodes[j], subG.id)
+ g.setParent(subG.nodes[j], subG.id);
}
}
- addVertices(vert, g, id)
- addEdges(edges, g)
+ addVertices(vert, g, id);
+ addEdges(edges, g);
// Create the renderer
- const Render = dagreD3.render
- const render = new Render()
+ const Render = dagreD3.render;
+ const render = new Render();
// Add custom shape for rhombus type of boc (decision)
- render.shapes().question = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
- const s = (w + h) * 0.9
+ render.shapes().question = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
+ const s = (w + h) * 0.9;
const points = [
{ x: s / 2, y: 0 },
{ x: s, y: -s / 2 },
{ x: s / 2, y: -s },
{ x: 0, y: -s / 2 }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
.attr('rx', 5)
.attr('ry', 5)
- .attr('transform', 'translate(' + (-s / 2) + ',' + (s * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ .attr('transform', 'translate(' + -s / 2 + ',' + (s * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on left side
- render.shapes().rect_left_inv_arrow = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().rect_left_inv_arrow = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
{ x: -h / 2, y: 0 },
{ x: w, y: 0 },
{ x: w, y: -h },
{ x: -h / 2, y: -h },
{ x: 0, y: -h / 2 }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on left side
- render.shapes().lean_right = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().lean_right = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
- { x: -2 * h / 6, y: 0 },
+ { x: (-2 * h) / 6, y: 0 },
{ x: w - h / 6, y: 0 },
- { x: w + 2 * h / 6, y: -h },
+ { x: w + (2 * h) / 6, y: -h },
{ x: h / 6, y: -h }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on left side
- render.shapes().lean_left = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().lean_left = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
- { x: 2 * h / 6, y: 0 },
+ { x: (2 * h) / 6, y: 0 },
{ x: w + h / 6, y: 0 },
- { x: w - 2 * h / 6, y: -h },
+ { x: w - (2 * h) / 6, y: -h },
{ x: -h / 6, y: -h }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on left side
- render.shapes().trapezoid = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().trapezoid = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
- { x: -2 * h / 6, y: 0 },
- { x: w + 2 * h / 6, y: 0 },
+ { x: (-2 * h) / 6, y: 0 },
+ { x: w + (2 * h) / 6, y: 0 },
{ x: w - h / 6, y: -h },
{ x: h / 6, y: -h }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on left side
- render.shapes().inv_trapezoid = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().inv_trapezoid = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
{ x: h / 6, y: 0 },
{ x: w - h / 6, y: 0 },
- { x: w + 2 * h / 6, y: -h },
- { x: -2 * h / 6, y: -h }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ { x: w + (2 * h) / 6, y: -h },
+ { x: (-2 * h) / 6, y: -h }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add custom shape for box with inverted arrow on right side
- render.shapes().rect_right_inv_arrow = function (parent, bbox, node) {
- const w = bbox.width
- const h = bbox.height
+ render.shapes().rect_right_inv_arrow = function(parent, bbox, node) {
+ const w = bbox.width;
+ const h = bbox.height;
const points = [
{ x: 0, y: 0 },
{ x: w + h / 2, y: 0 },
{ x: w, y: -h / 2 },
{ x: w + h / 2, y: -h },
{ x: 0, y: -h }
- ]
- const shapeSvg = parent.insert('polygon', ':first-child')
- .attr('points', points.map(function (d) {
- return d.x + ',' + d.y
- }).join(' '))
- .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
- node.intersect = function (point) {
- return dagreD3.intersect.polygon(node, points, point)
- }
- return shapeSvg
- }
+ ];
+ const shapeSvg = parent
+ .insert('polygon', ':first-child')
+ .attr(
+ 'points',
+ points
+ .map(function(d) {
+ return d.x + ',' + d.y;
+ })
+ .join(' ')
+ )
+ .attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
+ node.intersect = function(point) {
+ return dagreD3.intersect.polygon(node, points, point);
+ };
+ return shapeSvg;
+ };
// Add our custom arrow - an empty arrowhead
- render.arrows().none = function normal (parent, id, edge, type) {
- const marker = parent.append('marker')
+ render.arrows().none = function normal(parent, id, edge, type) {
+ const marker = parent
+ .append('marker')
.attr('id', id)
.attr('viewBox', '0 0 10 10')
.attr('refX', 9)
@@ -477,16 +533,16 @@ export const draw = function (text, id) {
.attr('markerUnits', 'strokeWidth')
.attr('markerWidth', 8)
.attr('markerHeight', 6)
- .attr('orient', 'auto')
+ .attr('orient', 'auto');
- const path = marker.append('path')
- .attr('d', 'M 0 0 L 0 0 L 0 0 z')
- dagreD3.util.applyStyle(path, edge[type + 'Style'])
- }
+ const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z');
+ dagreD3.util.applyStyle(path, edge[type + 'Style']);
+ };
// Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
- render.arrows().normal = function normal (parent, id, edge, type) {
- const marker = parent.append('marker')
+ render.arrows().normal = function normal(parent, id, edge, type) {
+ const marker = parent
+ .append('marker')
.attr('id', id)
.attr('viewBox', '0 0 10 10')
.attr('refX', 9)
@@ -494,76 +550,76 @@ export const draw = function (text, id) {
.attr('markerUnits', 'strokeWidth')
.attr('markerWidth', 8)
.attr('markerHeight', 6)
- .attr('orient', 'auto')
+ .attr('orient', 'auto');
- marker.append('path')
+ marker
+ .append('path')
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
.attr('class', 'arrowheadPath')
.style('stroke-width', 1)
- .style('stroke-dasharray', '1,0')
- }
+ .style('stroke-dasharray', '1,0');
+ };
// Set up an SVG group so that we can translate the final graph.
- const svg = d3.select(`[id="${id}"]`)
+ const svg = d3.select(`[id="${id}"]`);
// Run the renderer. This is what draws the final graph.
- const element = d3.select('#' + id + ' g')
- render(element, g)
+ const element = d3.select('#' + id + ' g');
+ render(element, g);
- element.selectAll('g.node')
- .attr('title', function () {
- return flowDb.getTooltip(this.id)
- })
+ element.selectAll('g.node').attr('title', function() {
+ return flowDb.getTooltip(this.id);
+ });
- const padding = 8
- const width = g.maxX - g.minX + padding * 2
- const height = g.maxY - g.minY + padding * 2
- svg.attr('width', '100%')
- svg.attr('style', `max-width: ${width}px;`)
- svg.attr('viewBox', `0 0 ${width} ${height}`)
- svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`)
+ const padding = 8;
+ const width = g.maxX - g.minX + padding * 2;
+ const height = g.maxY - g.minY + padding * 2;
+ svg.attr('width', '100%');
+ svg.attr('style', `max-width: ${width}px;`);
+ svg.attr('viewBox', `0 0 ${width} ${height}`);
+ svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`);
// Index nodes
- flowDb.indexNodes('subGraph' + i)
+ flowDb.indexNodes('subGraph' + i);
// reposition labels
for (i = 0; i < subGraphs.length; i++) {
- subG = subGraphs[i]
+ subG = subGraphs[i];
if (subG.title !== 'undefined') {
- const clusterRects = document.querySelectorAll('#' + id + ' #' + subG.id + ' rect')
- const clusterEl = document.querySelectorAll('#' + id + ' #' + subG.id)
+ const clusterRects = document.querySelectorAll('#' + id + ' #' + subG.id + ' rect');
+ const clusterEl = document.querySelectorAll('#' + id + ' #' + subG.id);
- const xPos = clusterRects[0].x.baseVal.value
- const yPos = clusterRects[0].y.baseVal.value
- const width = clusterRects[0].width.baseVal.value
- const cluster = d3.select(clusterEl[0])
- const te = cluster.select('.label')
- te.attr('transform', `translate(${xPos + width / 2}, ${yPos + 14})`)
- te.attr('id', id + 'Text')
+ const xPos = clusterRects[0].x.baseVal.value;
+ const yPos = clusterRects[0].y.baseVal.value;
+ const width = clusterRects[0].width.baseVal.value;
+ const cluster = d3.select(clusterEl[0]);
+ const te = cluster.select('.label');
+ te.attr('transform', `translate(${xPos + width / 2}, ${yPos + 14})`);
+ te.attr('id', id + 'Text');
}
}
// Add label rects for non html labels
if (!getConfig().flowchart.htmlLabels) {
- const labels = document.querySelectorAll('#' + id + ' .edgeLabel .label')
+ const labels = document.querySelectorAll('#' + id + ' .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
- const label = labels[k]
+ const label = labels[k];
// Get dimensions of label
- const dim = label.getBBox()
+ const dim = label.getBBox();
- const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
- rect.setAttribute('rx', 0)
- rect.setAttribute('ry', 0)
- rect.setAttribute('width', dim.width)
- rect.setAttribute('height', dim.height)
- rect.setAttribute('style', 'fill:#e8e8e8;')
+ const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ rect.setAttribute('rx', 0);
+ rect.setAttribute('ry', 0);
+ rect.setAttribute('width', dim.width);
+ rect.setAttribute('height', dim.height);
+ rect.setAttribute('style', 'fill:#e8e8e8;');
- label.insertBefore(rect, label.firstChild)
+ label.insertBefore(rect, label.firstChild);
}
}
-}
+};
export default {
setConf,
@@ -571,4 +627,4 @@ export default {
addEdges,
getClasses,
draw
-}
+};
diff --git a/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js b/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js
index e2247418c..db8cfadfe 100644
--- a/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js
+++ b/src/diagrams/flowchart/parser/flow-vertice-chaining.spec.js
@@ -1,38 +1,37 @@
-import flowDb from '../flowDb'
-import flow from './flow'
-import { setConfig } from '../../../config'
+import flowDb from '../flowDb';
+import flow from './flow';
+import { setConfig } from '../../../config';
setConfig({
- securityLevel: 'strict',
-})
+ securityLevel: 'strict'
+});
-describe('when parsing flowcharts', function () {
- beforeEach(function () {
- flow.parser.yy = flowDb
- flow.parser.yy.clear()
- })
+describe('when parsing flowcharts', function() {
+ beforeEach(function() {
+ flow.parser.yy = flowDb;
+ flow.parser.yy.clear();
+ });
- it('should handle chaining of vertices', function () {
+ it('should handle chaining of vertices', function() {
const res = flow.parser.parse(`
graph TD
A-->B-->C;
`);
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(vert['C'].id).toBe('C')
- expect(edges.length).toBe(2)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- expect(edges[1].start).toBe('B')
- expect(edges[1].end).toBe('C')
- expect(edges[1].type).toBe('arrow')
- expect(edges[1].text).toBe('')
- })
-
-})
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(vert['C'].id).toBe('C');
+ expect(edges.length).toBe(2);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ expect(edges[1].start).toBe('B');
+ expect(edges[1].end).toBe('C');
+ expect(edges[1].type).toBe('arrow');
+ expect(edges[1].text).toBe('');
+ });
+});
diff --git a/src/diagrams/flowchart/parser/flow.spec.js b/src/diagrams/flowchart/parser/flow.spec.js
index 8cb91f21d..5b99fcc3d 100644
--- a/src/diagrams/flowchart/parser/flow.spec.js
+++ b/src/diagrams/flowchart/parser/flow.spec.js
@@ -1,361 +1,366 @@
-import flowDb from '../flowDb'
-import flow from './flow'
-import { setConfig } from '../../../config'
+import flowDb from '../flowDb';
+import flow from './flow';
+import { setConfig } from '../../../config';
setConfig({
- securityLevel: 'strict',
-})
-
-describe('when parsing ', function () {
- beforeEach(function () {
- flow.parser.yy = flowDb
- flow.parser.yy.clear()
- })
-
- it('should handle a nodes and edges', function () {
- const res = flow.parser.parse('graph TD;\nA-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it("should handle angle bracket ' > ' as direction LR", function () {
- const res = flow.parser.parse('graph >;A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- const direction = flow.parser.yy.getDirection()
-
- expect(direction).toBe('LR')
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it("should handle angle bracket ' < ' as direction RL", function () {
- const res = flow.parser.parse('graph <;A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- const direction = flow.parser.yy.getDirection()
-
- expect(direction).toBe('RL')
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it("should handle caret ' ^ ' as direction BT", function () {
- const res = flow.parser.parse('graph ^;A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- const direction = flow.parser.yy.getDirection()
-
- expect(direction).toBe('BT')
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle lower-case \'v\' as direction TB', function () {
- const res = flow.parser.parse('graph v;A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- const direction = flow.parser.yy.getDirection()
-
- expect(direction).toBe('TB')
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle a nodes and edges and a space between link and node', function () {
- const res = flow.parser.parse('graph TD;A --> B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function () {
- const res = flow.parser.parse('graph TD\nA --> B\n style e red')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle statements ending without semicolon', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nB-->C')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(2)
- expect(edges[1].start).toBe('B')
- expect(edges[1].end).toBe('C')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle a comments', function () {
- const res = flow.parser.parse('graph TD;\n%% CComment\n A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle comments a at the start', function () {
- const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle comments at the end', function () {
- const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the find\n')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle comments at the end no trailing newline', function () {
- const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle comments at the end many trailing newlines', function () {
- const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento\n\n\n')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle no trailing newlines', function () {
- const res = flow.parser.parse('graph TD;\n A-->B')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle many trailing newlines', function () {
- const res = flow.parser.parse('graph TD;\n A-->B\n\n')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
- it('should handle a comments with blank rows in-between', function () {
- const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle a comments mermaid flowchart code in them', function () {
- const res = flow.parser.parse('graph TD;\n\n\n %% Test od>Odd shape]-->|Two line
edge comment|ro;\n A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('it should handle a trailing whitespaces after statememnts', function () {
- const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(2)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('')
- })
-
- it('should handle node names with "end" substring', function () {
- const res = flow.parser.parse('graph TD\nendpoint --> sender')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['endpoint'].id).toBe('endpoint')
- expect(vert['sender'].id).toBe('sender')
- expect(edges[0].start).toBe('endpoint')
- expect(edges[0].end).toBe('sender')
- })
-
- it('should handle node names ending with keywords', function () {
- const res = flow.parser.parse('graph TD\nblend --> monograph')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['blend'].id).toBe('blend')
- expect(vert['monograph'].id).toBe('monograph')
- expect(edges[0].start).toBe('blend')
- expect(edges[0].end).toBe('monograph')
- })
-
- it('should handle open ended edges', function () {
- const res = flow.parser.parse('graph TD;A---B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_open')
- })
-
- it('should handle cross ended edges', function () {
- const res = flow.parser.parse('graph TD;A--xB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle open ended edges', function () {
- const res = flow.parser.parse('graph TD;A--oB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_circle')
- })
- it('should handle classDefs with style in classes', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;')
+ securityLevel: 'strict'
+});
+
+describe('when parsing ', function() {
+ beforeEach(function() {
+ flow.parser.yy = flowDb;
+ flow.parser.yy.clear();
+ });
+
+ it('should handle a nodes and edges', function() {
+ const res = flow.parser.parse('graph TD;\nA-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it("should handle angle bracket ' > ' as direction LR", function() {
+ const res = flow.parser.parse('graph >;A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ const direction = flow.parser.yy.getDirection();
+
+ expect(direction).toBe('LR');
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it("should handle angle bracket ' < ' as direction RL", function() {
+ const res = flow.parser.parse('graph <;A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ const direction = flow.parser.yy.getDirection();
+
+ expect(direction).toBe('RL');
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it("should handle caret ' ^ ' as direction BT", function() {
+ const res = flow.parser.parse('graph ^;A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ const direction = flow.parser.yy.getDirection();
+
+ expect(direction).toBe('BT');
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it("should handle lower-case 'v' as direction TB", function() {
+ const res = flow.parser.parse('graph v;A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ const direction = flow.parser.yy.getDirection();
+
+ expect(direction).toBe('TB');
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('should handle a nodes and edges and a space between link and node', function() {
+ const res = flow.parser.parse('graph TD;A --> B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function() {
+ const res = flow.parser.parse('graph TD\nA --> B\n style e red');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle statements ending without semicolon', function() {
+ const res = flow.parser.parse('graph TD\nA-->B\nB-->C');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(2);
+ expect(edges[1].start).toBe('B');
+ expect(edges[1].end).toBe('C');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('should handle a comments', function() {
+ const res = flow.parser.parse('graph TD;\n%% CComment\n A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle comments a at the start', function() {
+ const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle comments at the end', function() {
+ const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the find\n');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle comments at the end no trailing newline', function() {
+ const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle comments at the end many trailing newlines', function() {
+ const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento\n\n\n');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle no trailing newlines', function() {
+ const res = flow.parser.parse('graph TD;\n A-->B');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle many trailing newlines', function() {
+ const res = flow.parser.parse('graph TD;\n A-->B\n\n');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle a comments with blank rows in-between', function() {
+ const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('should handle a comments mermaid flowchart code in them', function() {
+ const res = flow.parser.parse(
+ 'graph TD;\n\n\n %% Test od>Odd shape]-->|Two line
edge comment|ro;\n A-->B;'
+ );
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('it should handle a trailing whitespaces after statememnts', function() {
+ const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(2);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('');
+ });
+
+ it('should handle node names with "end" substring', function() {
+ const res = flow.parser.parse('graph TD\nendpoint --> sender');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['endpoint'].id).toBe('endpoint');
+ expect(vert['sender'].id).toBe('sender');
+ expect(edges[0].start).toBe('endpoint');
+ expect(edges[0].end).toBe('sender');
+ });
+
+ it('should handle node names ending with keywords', function() {
+ const res = flow.parser.parse('graph TD\nblend --> monograph');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['blend'].id).toBe('blend');
+ expect(vert['monograph'].id).toBe('monograph');
+ expect(edges[0].start).toBe('blend');
+ expect(edges[0].end).toBe('monograph');
+ });
+
+ it('should handle open ended edges', function() {
+ const res = flow.parser.parse('graph TD;A---B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_open');
+ });
+
+ it('should handle cross ended edges', function() {
+ const res = flow.parser.parse('graph TD;A--xB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle open ended edges', function() {
+ const res = flow.parser.parse('graph TD;A--oB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_circle');
+ });
+ it('should handle classDefs with style in classes', function() {
+ const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(edges[0].type).toBe('arrow');
+ });
- expect(edges[0].type).toBe('arrow')
- })
+ it('should handle classDefs with % in classes', function() {
+ const res = flow.parser.parse(
+ 'graph TD\nA-->B\nclassDef exClass fill:#f96,stroke:#333,stroke-width:4px,font-size:50%,font-style:bold;'
+ );
- it('should handle classDefs with % in classes', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass fill:#f96,stroke:#333,stroke-width:4px,font-size:50%,font-style:bold;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(edges[0].type).toBe('arrow');
+ });
- expect(edges[0].type).toBe('arrow')
- })
-
- it('should handle style definitions with more then 1 digit in a row', function () {
- const res = flow.parser.parse('graph TD\n' +
+ it('should handle style definitions with more then 1 digit in a row', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' +
'A-->B1\n' +
'A-->B2\n' +
'A-->B3\n' +
@@ -367,16 +372,18 @@ describe('when parsing ', function () {
'A-->B9\n' +
'A-->B10\n' +
'A-->B11\n' +
- 'linkStyle 10 stroke-width:1px;')
+ 'linkStyle 10 stroke-width:1px;'
+ );
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
+ expect(edges[0].type).toBe('arrow');
+ });
- it('should handle multi-numbered style definitons with more then 1 digit in a row', function () {
- const res = flow.parser.parse('graph TD\n' +
+ it('should handle multi-numbered style definitons with more then 1 digit in a row', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' +
'A-->B1\n' +
'A-->B2\n' +
'A-->B3\n' +
@@ -389,1360 +396,1372 @@ describe('when parsing ', function () {
'A-->B10\n' +
'A-->B11\n' +
'A-->B12\n' +
- 'linkStyle 10,11 stroke-width:1px;')
+ 'linkStyle 10,11 stroke-width:1px;'
+ );
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
+ expect(edges[0].type).toBe('arrow');
+ });
- it('should handle line interpolation default definitions', function () {
- const res = flow.parser.parse('graph TD\n' +
- 'A-->B\n' +
- 'linkStyle default interpolate basis')
+ it('should handle line interpolation default definitions', function() {
+ const res = flow.parser.parse('graph TD\n' + 'A-->B\n' + 'linkStyle default interpolate basis');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.defaultInterpolate).toBe('basis')
- })
+ expect(edges.defaultInterpolate).toBe('basis');
+ });
- it('should handle line interpolation numbered definitions', function () {
- const res = flow.parser.parse('graph TD\n' +
+ it('should handle line interpolation numbered definitions', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' +
'A-->B\n' +
'A-->C\n' +
'linkStyle 0 interpolate basis\n' +
- 'linkStyle 1 interpolate cardinal')
+ 'linkStyle 1 interpolate cardinal'
+ );
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].interpolate).toBe('basis')
- expect(edges[1].interpolate).toBe('cardinal')
- })
+ expect(edges[0].interpolate).toBe('basis');
+ expect(edges[1].interpolate).toBe('cardinal');
+ });
- it('should handle line interpolation multi-numbered definitions', function () {
- const res = flow.parser.parse('graph TD\n' +
- 'A-->B\n' +
- 'A-->C\n' +
- 'linkStyle 0,1 interpolate basis')
+ it('should handle line interpolation multi-numbered definitions', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' + 'A-->B\n' + 'A-->C\n' + 'linkStyle 0,1 interpolate basis'
+ );
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].interpolate).toBe('basis')
- expect(edges[1].interpolate).toBe('basis')
- })
+ expect(edges[0].interpolate).toBe('basis');
+ expect(edges[1].interpolate).toBe('basis');
+ });
- it('should handle line interpolation default with style', function () {
- const res = flow.parser.parse('graph TD\n' +
- 'A-->B\n' +
- 'linkStyle default interpolate basis stroke-width:1px;')
+ it('should handle line interpolation default with style', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' + 'A-->B\n' + 'linkStyle default interpolate basis stroke-width:1px;'
+ );
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.defaultInterpolate).toBe('basis')
- })
+ expect(edges.defaultInterpolate).toBe('basis');
+ });
- it('should handle line interpolation numbered with style', function () {
- const res = flow.parser.parse('graph TD\n' +
+ it('should handle line interpolation numbered with style', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' +
'A-->B\n' +
'A-->C\n' +
'linkStyle 0 interpolate basis stroke-width:1px;\n' +
- 'linkStyle 1 interpolate cardinal stroke-width:1px;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].interpolate).toBe('basis')
- expect(edges[1].interpolate).toBe('cardinal')
- })
-
- it('should handle line interpolation multi-numbered with style', function () {
- const res = flow.parser.parse('graph TD\n' +
- 'A-->B\n' +
- 'A-->C\n' +
- 'linkStyle 0,1 interpolate basis stroke-width:1px;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].interpolate).toBe('basis')
- expect(edges[1].interpolate).toBe('basis')
- })
-
- describe('it should handle interaction, ', function () {
- it('it should be possible to use click to a callback', function () {
- spyOn(flowDb, 'setClickEvent')
- const res = flow.parser.parse('graph TD\nA-->B\nclick A callback')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined)
- })
-
- it('it should be possible to use click to a callback with toolip', function () {
- spyOn(flowDb, 'setClickEvent')
- const res = flow.parser.parse('graph TD\nA-->B\nclick A callback "tooltip"')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', 'tooltip')
- })
-
- it('should handle interaction - click to a link', function () {
- spyOn(flowDb, 'setLink')
- const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html"')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined)
- })
- it('should handle interaction - click to a link with tooltip', function () {
- spyOn(flowDb, 'setLink')
- const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip"')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip')
- })
- })
-
- describe('it should multi directional arrows', function () {
- describe('point', function () {
- it('should handle double edged nodes and edges', function () {
- const res = flow.parser.parse('graph TD;\nA<-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text', function () {
- const res = flow.parser.parse('graph TD;\nA<-- text -->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].stroke).toBe('normal')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA<==>B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA<== text ==>B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA<-.->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA<-. text .->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_point')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('text')
- })
- })
- describe('cross', function () {
- it('should handle double edged nodes and edges', function () {
- const res = flow.parser.parse('graph TD;\nA x--x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text', function () {
- const res = flow.parser.parse('graph TD;\nA x-- text --x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].stroke).toBe('normal')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA x==x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA x== text ==x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA x-.-x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA x-. text .-x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_cross')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('text')
- })
- })
- describe('circle', function () {
- it('should handle double edged nodes and edges', function () {
- const res = flow.parser.parse('graph TD;\nA o--o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text', function () {
- const res = flow.parser.parse('graph TD;\nA o-- text --o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].stroke).toBe('normal')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA o==o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on thick arrows', function () {
- const res = flow.parser.parse('graph TD;\nA o== text ==o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].stroke).toBe('thick')
- expect(edges[0].text).toBe('text')
- })
- it('should handle double edged nodes and edges on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA o-.-o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('')
- })
- it('should handle double edged nodes with text on dotted arrows', function () {
- const res = flow.parser.parse('graph TD;\nA o-. text .-o B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(1)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].type).toBe('double_arrow_circle')
- expect(edges[0].stroke).toBe('dotted')
- expect(edges[0].text).toBe('text')
- })
- })
-
- })
- describe('it should handle text on edges', function () {
- it('it should handle text without space', function () {
- const res = flow.parser.parse('graph TD;A--x|textNoSpace|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle with space', function () {
- const res = flow.parser.parse('graph TD;A--x|text including space|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('it should handle text with /', function () {
- const res = flow.parser.parse('graph TD;A--x|text with / should work|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].text).toBe('text with / should work')
- })
-
- it('it should handle space and space between vertices and link', function () {
- const res = flow.parser.parse('graph TD;A --x|textNoSpace| B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle space and CAPS', function () {
- const res = flow.parser.parse('graph TD;A--x|text including CAPS space|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle space and dir', function () {
- const res = flow.parser.parse('graph TD;A--x|text including URL space|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(edges[0].text).toBe('text including URL space')
- })
-
- it('should handle space and send', function () {
- const res = flow.parser.parse('graph TD;A--text including URL space and send-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('text including URL space and send')
- })
- it('should handle space and send', function () {
- const res = flow.parser.parse('graph TD;A-- text including URL space and send -->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- expect(edges[0].text).toBe('text including URL space and send')
- })
-
- it('should handle space and dir (TD)', function () {
- const res = flow.parser.parse('graph TD;A--x|text including R TD space|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(edges[0].text).toBe('text including R TD space')
- })
- it('should handle `', function () {
- const res = flow.parser.parse('graph TD;A--x|text including `|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(edges[0].text).toBe('text including `')
- })
- it('should handle v in node ids only v', function () {
- // only v
- const res = flow.parser.parse('graph TD;A--xv(my text);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(vert['v'].text).toBe('my text')
- })
- it('should handle v in node ids v at end', function () {
- // v at end
- const res = flow.parser.parse('graph TD;A--xcsv(my text);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(vert['csv'].text).toBe('my text')
- })
- it('should handle v in node ids v in middle', function () {
- // v in middle
- const res = flow.parser.parse('graph TD;A--xava(my text);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(vert['ava'].text).toBe('my text')
- })
- it('should handle v in node ids, v at start', function () {
- // v at start
- const res = flow.parser.parse('graph TD;A--xva(my text);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- expect(vert['va'].text).toBe('my text')
- })
- it('should handle keywords', function () {
- const res = flow.parser.parse('graph TD;A--x|text including graph space|B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].text).toBe('text including graph space')
- })
- it('should handle keywords', function () {
- const res = flow.parser.parse('graph TD;V-->a[v]')
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- expect(vert['a'].text).toBe('v')
- })
- it('should handle keywords', function () {
- const res = flow.parser.parse('graph TD;V-->a[v]')
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- expect(vert['a'].text).toBe('v')
- })
- it('should handle quoted text', function () {
- const res = flow.parser.parse('graph TD;V-- "test string()" -->a[v]')
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
- expect(edges[0].text).toBe('test string()')
- })
- })
-
- describe('it should handle new line type notation', function () {
- it('it should handle regular lines', function () {
- const res = flow.parser.parse('graph TD;A-->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].stroke).toBe('normal')
- })
- it('it should handle dotted lines', function () {
- const res = flow.parser.parse('graph TD;A-.->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].stroke).toBe('dotted')
- })
- it('it should handle dotted lines', function () {
- const res = flow.parser.parse('graph TD;A==>B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].stroke).toBe('thick')
- })
- it('it should handle text on lines', function () {
- const res = flow.parser.parse('graph TD;A-- test text with == -->B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].stroke).toBe('normal')
- })
- it('it should handle text on lines', function () {
- const res = flow.parser.parse('graph TD;A-. test text with == .->B;')
+ 'linkStyle 1 interpolate cardinal stroke-width:1px;'
+ );
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].interpolate).toBe('basis');
+ expect(edges[1].interpolate).toBe('cardinal');
+ });
+
+ it('should handle line interpolation multi-numbered with style', function() {
+ const res = flow.parser.parse(
+ 'graph TD\n' + 'A-->B\n' + 'A-->C\n' + 'linkStyle 0,1 interpolate basis stroke-width:1px;'
+ );
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].interpolate).toBe('basis');
+ expect(edges[1].interpolate).toBe('basis');
+ });
+
+ describe('it should handle interaction, ', function() {
+ it('it should be possible to use click to a callback', function() {
+ spyOn(flowDb, 'setClickEvent');
+ const res = flow.parser.parse('graph TD\nA-->B\nclick A callback');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined);
+ });
+
+ it('it should be possible to use click to a callback with toolip', function() {
+ spyOn(flowDb, 'setClickEvent');
+ const res = flow.parser.parse('graph TD\nA-->B\nclick A callback "tooltip"');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', 'tooltip');
+ });
+
+ it('should handle interaction - click to a link', function() {
+ spyOn(flowDb, 'setLink');
+ const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html"');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined);
+ });
+ it('should handle interaction - click to a link with tooltip', function() {
+ spyOn(flowDb, 'setLink');
+ const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip"');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip');
+ });
+ });
+
+ describe('it should multi directional arrows', function() {
+ describe('point', function() {
+ it('should handle double edged nodes and edges', function() {
+ const res = flow.parser.parse('graph TD;\nA<-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text', function() {
+ const res = flow.parser.parse('graph TD;\nA<-- text -->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].stroke).toBe('normal');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA<==>B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA<== text ==>B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA<-.->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA<-. text .->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_point');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('text');
+ });
+ });
+ describe('cross', function() {
+ it('should handle double edged nodes and edges', function() {
+ const res = flow.parser.parse('graph TD;\nA x--x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text', function() {
+ const res = flow.parser.parse('graph TD;\nA x-- text --x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].stroke).toBe('normal');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA x==x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA x== text ==x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA x-.-x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA x-. text .-x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_cross');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('text');
+ });
+ });
+ describe('circle', function() {
+ it('should handle double edged nodes and edges', function() {
+ const res = flow.parser.parse('graph TD;\nA o--o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text', function() {
+ const res = flow.parser.parse('graph TD;\nA o-- text --o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].stroke).toBe('normal');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA o==o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on thick arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA o== text ==o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].stroke).toBe('thick');
+ expect(edges[0].text).toBe('text');
+ });
+ it('should handle double edged nodes and edges on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA o-.-o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('');
+ });
+ it('should handle double edged nodes with text on dotted arrows', function() {
+ const res = flow.parser.parse('graph TD;\nA o-. text .-o B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(1);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].type).toBe('double_arrow_circle');
+ expect(edges[0].stroke).toBe('dotted');
+ expect(edges[0].text).toBe('text');
+ });
+ });
+ });
+ describe('it should handle text on edges', function() {
+ it('it should handle text without space', function() {
+ const res = flow.parser.parse('graph TD;A--x|textNoSpace|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle with space', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including space|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('it should handle text with /', function() {
+ const res = flow.parser.parse('graph TD;A--x|text with / should work|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].text).toBe('text with / should work');
+ });
+
+ it('it should handle space and space between vertices and link', function() {
+ const res = flow.parser.parse('graph TD;A --x|textNoSpace| B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle space and CAPS', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including CAPS space|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle space and dir', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including URL space|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(edges[0].text).toBe('text including URL space');
+ });
+
+ it('should handle space and send', function() {
+ const res = flow.parser.parse('graph TD;A--text including URL space and send-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('text including URL space and send');
+ });
+ it('should handle space and send', function() {
+ const res = flow.parser.parse('graph TD;A-- text including URL space and send -->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow');
+ expect(edges[0].text).toBe('text including URL space and send');
+ });
+
+ it('should handle space and dir (TD)', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including R TD space|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(edges[0].text).toBe('text including R TD space');
+ });
+ it('should handle `', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including `|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(edges[0].text).toBe('text including `');
+ });
+ it('should handle v in node ids only v', function() {
+ // only v
+ const res = flow.parser.parse('graph TD;A--xv(my text);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(vert['v'].text).toBe('my text');
+ });
+ it('should handle v in node ids v at end', function() {
+ // v at end
+ const res = flow.parser.parse('graph TD;A--xcsv(my text);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(vert['csv'].text).toBe('my text');
+ });
+ it('should handle v in node ids v in middle', function() {
+ // v in middle
+ const res = flow.parser.parse('graph TD;A--xava(my text);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(vert['ava'].text).toBe('my text');
+ });
+ it('should handle v in node ids, v at start', function() {
+ // v at start
+ const res = flow.parser.parse('graph TD;A--xva(my text);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(vert['va'].text).toBe('my text');
+ });
+ it('should handle keywords', function() {
+ const res = flow.parser.parse('graph TD;A--x|text including graph space|B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].text).toBe('text including graph space');
+ });
+ it('should handle keywords', function() {
+ const res = flow.parser.parse('graph TD;V-->a[v]');
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ expect(vert['a'].text).toBe('v');
+ });
+ it('should handle keywords', function() {
+ const res = flow.parser.parse('graph TD;V-->a[v]');
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ expect(vert['a'].text).toBe('v');
+ });
+ it('should handle quoted text', function() {
+ const res = flow.parser.parse('graph TD;V-- "test string()" -->a[v]');
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+ expect(edges[0].text).toBe('test string()');
+ });
+ });
+
+ describe('it should handle new line type notation', function() {
+ it('it should handle regular lines', function() {
+ const res = flow.parser.parse('graph TD;A-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].stroke).toBe('normal');
+ });
+ it('it should handle dotted lines', function() {
+ const res = flow.parser.parse('graph TD;A-.->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].stroke).toBe('dotted');
+ });
+ it('it should handle dotted lines', function() {
+ const res = flow.parser.parse('graph TD;A==>B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].stroke).toBe('thick');
+ });
+ it('it should handle text on lines', function() {
+ const res = flow.parser.parse('graph TD;A-- test text with == -->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].stroke).toBe('normal');
+ });
+ it('it should handle text on lines', function() {
+ const res = flow.parser.parse('graph TD;A-. test text with == .->B;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].stroke).toBe('dotted')
- })
- it('it should handle text on lines', function () {
- const res = flow.parser.parse('graph TD;A== test text with - ==>B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].stroke).toBe('thick')
- })
- })
-
- describe('it should handle text on edges using the new notation', function () {
- it('it should handle text without space', function () {
- const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('it should handle text with multiple leading space', function () {
- const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle with space', function () {
- const res = flow.parser.parse('graph TD;A-- text including space --xB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('it should handle text with /', function () {
- const res = flow.parser.parse('graph TD;A -- text with / should work --x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].text).toBe('text with / should work')
- })
-
- it('it should handle space and space between vertices and link', function () {
- const res = flow.parser.parse('graph TD;A -- textNoSpace --x B;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow_cross')
- })
-
- it('should handle space and CAPS', function () {
- const res = flow.parser.parse('graph TD;A-- text including CAPS space --xB;')
+ expect(edges[0].stroke).toBe('dotted');
+ });
+ it('it should handle text on lines', function() {
+ const res = flow.parser.parse('graph TD;A== test text with - ==>B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].stroke).toBe('thick');
+ });
+ });
+
+ describe('it should handle text on edges using the new notation', function() {
+ it('it should handle text without space', function() {
+ const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('it should handle text with multiple leading space', function() {
+ const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle with space', function() {
+ const res = flow.parser.parse('graph TD;A-- text including space --xB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('it should handle text with /', function() {
+ const res = flow.parser.parse('graph TD;A -- text with / should work --x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].text).toBe('text with / should work');
+ });
+
+ it('it should handle space and space between vertices and link', function() {
+ const res = flow.parser.parse('graph TD;A -- textNoSpace --x B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges[0].type).toBe('arrow_cross');
+ });
+
+ it('should handle space and CAPS', function() {
+ const res = flow.parser.parse('graph TD;A-- text including CAPS space --xB;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow_cross')
- })
+ expect(edges[0].type).toBe('arrow_cross');
+ });
- it('should handle space and dir', function () {
- const res = flow.parser.parse('graph TD;A-- text including URL space --xB;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('should handle space and dir', function() {
+ const res = flow.parser.parse('graph TD;A-- text including URL space --xB;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow_cross')
- expect(edges[0].text).toBe('text including URL space')
- })
-
- it('should handle space and dir (TD)', function () {
- const res = flow.parser.parse('graph TD;A-- text including R TD space --xB;')
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(edges[0].text).toBe('text including URL space');
+ });
+
+ it('should handle space and dir (TD)', function() {
+ const res = flow.parser.parse('graph TD;A-- text including R TD space --xB;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow_cross')
- expect(edges[0].text).toBe('text including R TD space')
- })
- it('should handle keywords', function () {
- const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB;')
+ expect(edges[0].type).toBe('arrow_cross');
+ expect(edges[0].text).toBe('text including R TD space');
+ });
+ it('should handle keywords', function() {
+ const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].text).toBe('text including graph space and v')
- })
- it('should handle keywords', function () {
- const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB[blav]')
+ expect(edges[0].text).toBe('text including graph space and v');
+ });
+ it('should handle keywords', function() {
+ const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB[blav]');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].text).toBe('text including graph space and v')
- })
- // xit('should handle text on open links',function(){
- // const res = flow.parser.parse('graph TD;A-- text including graph space --B');
- //
- // const vert = flow.parser.yy.getVertices();
- // const edges = flow.parser.yy.getEdges();
- //
- // expect(edges[0].text).toBe('text including graph space');
- //
- // });
- })
+ expect(edges[0].text).toBe('text including graph space and v');
+ });
+ // xit('should handle text on open links',function(){
+ // const res = flow.parser.parse('graph TD;A-- text including graph space --B');
+ //
+ // const vert = flow.parser.yy.getVertices();
+ // const edges = flow.parser.yy.getEdges();
+ //
+ // expect(edges[0].text).toBe('text including graph space');
+ //
+ // });
+ });
- it('should handle multi-line text', function () {
- const res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;')
+ it('should handle multi-line text', function() {
+ const res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow_circle')
- expect(edges[1].type).toBe('arrow')
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(vert['C'].id).toBe('C')
- expect(edges.length).toBe(2)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- // expect(edges[0].text).toBe('text space');
- expect(edges[1].start).toBe('B')
- expect(edges[1].end).toBe('C')
- expect(edges[1].text).toBe('more text with space')
- })
+ expect(edges[0].type).toBe('arrow_circle');
+ expect(edges[1].type).toBe('arrow');
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(vert['C'].id).toBe('C');
+ expect(edges.length).toBe(2);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ // expect(edges[0].text).toBe('text space');
+ expect(edges[1].start).toBe('B');
+ expect(edges[1].end).toBe('C');
+ expect(edges[1].text).toBe('more text with space');
+ });
- it('should handle multiple edges', function () {
- const res = flow.parser.parse('graph TD;A---|This is the 123 s text|B;\nA---|This is the second edge|B;')
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('should handle multiple edges', function() {
+ const res = flow.parser.parse(
+ 'graph TD;A---|This is the 123 s text|B;\nA---|This is the second edge|B;'
+ );
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- expect(edges.length).toBe(2)
- expect(edges[0].start).toBe('A')
- expect(edges[0].end).toBe('B')
- expect(edges[0].text).toBe('This is the 123 s text')
- expect(edges[1].start).toBe('A')
- expect(edges[1].end).toBe('B')
- expect(edges[1].text).toBe('This is the second edge')
- })
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ expect(edges.length).toBe(2);
+ expect(edges[0].start).toBe('A');
+ expect(edges[0].end).toBe('B');
+ expect(edges[0].text).toBe('This is the 123 s text');
+ expect(edges[1].start).toBe('A');
+ expect(edges[1].end).toBe('B');
+ expect(edges[1].text).toBe('This is the second edge');
+ });
+
+ it('should handle text in vertices with space', function() {
+ const res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('square');
+ expect(vert['A'].text).toBe('chimpansen hoppar');
+ });
+
+ it('should handle text in vertices with space with spaces between vertices and link', function() {
+ const res = flow.parser.parse('graph TD;A[chimpansen hoppar] --> C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('square');
+ expect(vert['A'].text).toBe('chimpansen hoppar');
+ });
+ it('should handle text including _ in vertices', function() {
+ const res = flow.parser.parse('graph TD;A[chimpansen_hoppar] --> C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('square');
+ expect(vert['A'].text).toBe('chimpansen_hoppar');
+ });
+
+ it('should handle quoted text in vertices ', function() {
+ const res = flow.parser.parse('graph TD;A["chimpansen hoppar ()[]"] --> C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('square');
+ expect(vert['A'].text).toBe('chimpansen hoppar ()[]');
+ });
+
+ it('should handle text in circle vertices with space', function() {
+ const res = flow.parser.parse('graph TD;A((chimpansen hoppar))-->C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('circle');
+ expect(vert['A'].text).toBe('chimpansen hoppar');
+ });
+
+ it('should handle text in ellipse vertices', function() {
+ const res = flow.parser.parse('graph TD\nA(-this is an ellipse-)-->B');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('ellipse');
+ expect(vert['A'].text).toBe('this is an ellipse');
+ });
+
+ it('should handle text in diamond vertices with space', function() {
+ const res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].type).toBe('round');
+ expect(vert['A'].text).toBe('chimpansen hoppar');
+ });
+
+ it('should handle text in with ?', function() {
+ const res = flow.parser.parse('graph TD;A(?)-->|?|C;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].text).toBe('?');
+ expect(edges[0].text).toBe('?');
+ });
+ it('should handle text in with éèêàçô', function() {
+ const res = flow.parser.parse('graph TD;A(éèêàçô)-->|éèêàçô|C;');
- it('should handle text in vertices with space', function () {
- const res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].text).toBe('éèêàçô');
+ expect(edges[0].text).toBe('éèêàçô');
+ });
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('should handle text in with ,.?!+-*', function() {
+ const res = flow.parser.parse('graph TD;A(,.?!+-*)-->|,.?!+-*|C;');
- expect(vert['A'].type).toBe('square')
- expect(vert['A'].text).toBe('chimpansen hoppar')
- })
-
- it('should handle text in vertices with space with spaces between vertices and link', function () {
- const res = flow.parser.parse('graph TD;A[chimpansen hoppar] --> C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('square')
- expect(vert['A'].text).toBe('chimpansen hoppar')
- })
- it('should handle text including _ in vertices', function () {
- const res = flow.parser.parse('graph TD;A[chimpansen_hoppar] --> C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('square')
- expect(vert['A'].text).toBe('chimpansen_hoppar')
- })
-
- it('should handle quoted text in vertices ', function () {
- const res = flow.parser.parse('graph TD;A["chimpansen hoppar ()[]"] --> C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('square')
- expect(vert['A'].text).toBe('chimpansen hoppar ()[]')
- })
-
- it('should handle text in circle vertices with space', function () {
- const res = flow.parser.parse('graph TD;A((chimpansen hoppar))-->C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('circle')
- expect(vert['A'].text).toBe('chimpansen hoppar')
- })
-
- it('should handle text in ellipse vertices', function () {
- const res = flow.parser.parse('graph TD\nA(-this is an ellipse-)-->B')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('ellipse')
- expect(vert['A'].text).toBe('this is an ellipse')
- })
-
- it('should handle text in diamond vertices with space', function () {
- const res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].type).toBe('round')
- expect(vert['A'].text).toBe('chimpansen hoppar')
- })
-
- it('should handle text in with ?', function () {
- const res = flow.parser.parse('graph TD;A(?)-->|?|C;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['A'].text).toBe('?')
- expect(edges[0].text).toBe('?')
- })
- it('should handle text in with éèêàçô', function () {
- const res = flow.parser.parse('graph TD;A(éèêàçô)-->|éèêàçô|C;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(vert['A'].text).toBe(',.?!+-*');
+ expect(edges[0].text).toBe(',.?!+-*');
+ });
- expect(vert['A'].text).toBe('éèêàçô')
- expect(edges[0].text).toBe('éèêàçô')
- })
+ describe('it should handle text in vertices, ', function() {
+ it('it should handle space', function() {
+ const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar);');
- it('should handle text in with ,.?!+-*', function () {
- const res = flow.parser.parse('graph TD;A(,.?!+-*)-->|,.?!+-*|C;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(vert['C'].type).toBe('round');
+ expect(vert['C'].text).toBe('Chimpansen hoppar');
+ });
+ it('it should handle åäö and minus', function() {
+ const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};');
- expect(vert['A'].text).toBe(',.?!+-*')
- expect(edges[0].text).toBe(',.?!+-*')
- })
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- describe('it should handle text in vertices, ', function () {
- it('it should handle space', function () {
- const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar);')
+ expect(vert['C'].type).toBe('diamond');
+ expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ');
+ });
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('it should handle with åäö, minus and space and br', function() {
+ const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar åäö
- ÅÄÖ);');
- expect(vert['C'].type).toBe('round')
- expect(vert['C'].text).toBe('Chimpansen hoppar')
- })
- it('it should handle åäö and minus', function () {
- const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['C'].type).toBe('diamond')
- expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ')
- })
-
- it('it should handle with åäö, minus and space and br', function () {
- const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar åäö
- ÅÄÖ);')
+ expect(vert['C'].type).toBe('round');
+ expect(vert['C'].text).toBe('Chimpansen hoppar åäö
- ÅÄÖ');
+ });
+ // xit('it should handle åäö, minus and space and br',function(){
+ // const res = flow.parser.parse('graph TD; A[Object(foo,bar)]-->B(Thing);');
+ //
+ // const vert = flow.parser.yy.getVertices();
+ // const edges = flow.parser.yy.getEdges();
+ //
+ // expect(vert['C'].type).toBe('round');
+ // expect(vert['C'].text).toBe(' A[Object(foo,bar)]-->B(Thing);');
+ // });
+ it('it should handle unicode chars', function() {
+ const res = flow.parser.parse('graph TD;A-->C(Начало);');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['C'].type).toBe('round')
- expect(vert['C'].text).toBe('Chimpansen hoppar åäö
- ÅÄÖ')
- })
- // xit('it should handle åäö, minus and space and br',function(){
- // const res = flow.parser.parse('graph TD; A[Object(foo,bar)]-->B(Thing);');
- //
- // const vert = flow.parser.yy.getVertices();
- // const edges = flow.parser.yy.getEdges();
- //
- // expect(vert['C'].type).toBe('round');
- // expect(vert['C'].text).toBe(' A[Object(foo,bar)]-->B(Thing);');
- // });
- it('it should handle unicode chars', function () {
- const res = flow.parser.parse('graph TD;A-->C(Начало);')
-
- const vert = flow.parser.yy.getVertices()
-
- expect(vert['C'].text).toBe('Начало')
- })
- it('it should handle backslask', function () {
- const res = flow.parser.parse('graph TD;A-->C(c:\\windows);')
-
- const vert = flow.parser.yy.getVertices()
-
- expect(vert['C'].text).toBe('c:\\windows')
- })
- it('it should handle CAPS', function () {
- const res = flow.parser.parse('graph TD;A-->C(some CAPS);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['C'].type).toBe('round')
- expect(vert['C'].text).toBe('some CAPS')
- })
- it('it should handle directions', function () {
- const res = flow.parser.parse('graph TD;A-->C(some URL);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(vert['C'].type).toBe('round')
- expect(vert['C'].text).toBe('some URL')
- })
- })
-
- it('should handle a single node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;A;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['A'].styles.length).toBe(0)
- })
-
- it('should handle a single square node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a[A];')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].styles.length).toBe(0)
- expect(vert['a'].type).toBe('square')
- })
- it('should handle a single round square node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a[A];')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].styles.length).toBe(0)
- expect(vert['a'].type).toBe('square')
- })
- it('should handle a single circle node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a((A));')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('circle')
- })
- it('should handle a single round node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a(A);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('round')
- })
- it('should handle a single odd node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a>A];')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('odd')
- })
- it('should handle a single diamond node', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a{A};')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('diamond')
- })
- it('should handle a single diamond node with html in it', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a{A
end};')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('diamond')
- expect(vert['a'].text).toBe('A
end')
- })
- it('should handle a single round node with html in it', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;a(A
end);')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['a'].type).toBe('round')
- expect(vert['a'].text).toBe('A
end')
- })
- it('should handle a single node with alphanumerics starting on a char', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;id1;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['id1'].styles.length).toBe(0)
- })
- it('should handle a single node with a single digit', function () {
+ const vert = flow.parser.yy.getVertices();
+
+ expect(vert['C'].text).toBe('Начало');
+ });
+ it('it should handle backslask', function() {
+ const res = flow.parser.parse('graph TD;A-->C(c:\\windows);');
+
+ const vert = flow.parser.yy.getVertices();
+
+ expect(vert['C'].text).toBe('c:\\windows');
+ });
+ it('it should handle CAPS', function() {
+ const res = flow.parser.parse('graph TD;A-->C(some CAPS);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['C'].type).toBe('round');
+ expect(vert['C'].text).toBe('some CAPS');
+ });
+ it('it should handle directions', function() {
+ const res = flow.parser.parse('graph TD;A-->C(some URL);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['C'].type).toBe('round');
+ expect(vert['C'].text).toBe('some URL');
+ });
+ });
+
+ it('should handle a single node', function() {
// Silly but syntactically correct
- const res = flow.parser.parse('graph TD;1;')
+ const res = flow.parser.parse('graph TD;A;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.length).toBe(0)
- expect(vert['s1'].text).toBe('1')
- })
- it('should handle a single node with a single digit in a subgraph', function () {
+ expect(edges.length).toBe(0);
+ expect(vert['A'].styles.length).toBe(0);
+ });
+
+ it('should handle a single square node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a[A];');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].styles.length).toBe(0);
+ expect(vert['a'].type).toBe('square');
+ });
+ it('should handle a single round square node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a[A];');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].styles.length).toBe(0);
+ expect(vert['a'].type).toBe('square');
+ });
+ it('should handle a single circle node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a((A));');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('circle');
+ });
+ it('should handle a single round node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a(A);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('round');
+ });
+ it('should handle a single odd node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a>A];');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('odd');
+ });
+ it('should handle a single diamond node', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a{A};');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('diamond');
+ });
+ it('should handle a single diamond node with html in it', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a{A
end};');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('diamond');
+ expect(vert['a'].text).toBe('A
end');
+ });
+ it('should handle a single round node with html in it', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;a(A
end);');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['a'].type).toBe('round');
+ expect(vert['a'].text).toBe('A
end');
+ });
+ it('should handle a single node with alphanumerics starting on a char', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;id1;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['id1'].styles.length).toBe(0);
+ });
+ it('should handle a single node with a single digit', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;1;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(edges.length).toBe(0);
+ expect(vert['s1'].text).toBe('1');
+ });
+ it('should handle a single node with a single digit in a subgraph', function() {
// Silly but syntactically correct
- const res = flow.parser.parse('graph TD;subgraph "hello";1;end;')
+ const res = flow.parser.parse('graph TD;subgraph "hello";1;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.length).toBe(0)
- expect(vert['s1'].text).toBe('1')
- })
- it('should handle a single node with alphanumerics starting on a num', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;1id;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['s1id'].styles.length).toBe(0)
- })
- it('should handle a single node with alphanumerics containing a minus sign', function () {
- // Silly but syntactically correct
- const res = flow.parser.parse('graph TD;i-d;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges.length).toBe(0)
- expect(vert['i-d'].styles.length).toBe(0)
- })
- it('should handle a single node with alphanumerics containing a underscore sign', function () {
+ expect(edges.length).toBe(0);
+ expect(vert['s1'].text).toBe('1');
+ });
+ it('should handle a single node with alphanumerics starting on a num', function() {
// Silly but syntactically correct
- const res = flow.parser.parse('graph TD;i_d;')
+ const res = flow.parser.parse('graph TD;1id;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.length).toBe(0)
- expect(vert['i_d'].styles.length).toBe(0)
- })
+ expect(edges.length).toBe(0);
+ expect(vert['s1id'].styles.length).toBe(0);
+ });
+ it('should handle a single node with alphanumerics containing a minus sign', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;i-d;');
- // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
- it('should handle styles for vertices', function () {
- const res = flow.parser.parse('graph TD;style Q background:#fff;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(edges.length).toBe(0);
+ expect(vert['i-d'].styles.length).toBe(0);
+ });
+ it('should handle a single node with alphanumerics containing a underscore sign', function() {
+ // Silly but syntactically correct
+ const res = flow.parser.parse('graph TD;i_d;');
- const style = vert['Q'].styles[0]
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(vert['Q'].styles.length).toBe(1)
- expect(vert['Q'].styles[0]).toBe('background:#fff')
- })
+ expect(edges.length).toBe(0);
+ expect(vert['i_d'].styles.length).toBe(0);
+ });
- // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
- it('should handle styles for edges', function () {
- const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;')
+ // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
+ it('should handle styles for vertices', function() {
+ const res = flow.parser.parse('graph TD;style Q background:#fff;');
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges.length).toBe(1)
- })
+ const style = vert['Q'].styles[0];
- it('should handle multiple styles for a vortex', function () {
- const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;')
+ expect(vert['Q'].styles.length).toBe(1);
+ expect(vert['Q'].styles[0]).toBe('background:#fff');
+ });
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
+ it('should handle styles for edges', function() {
+ const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;');
- expect(vert['R'].styles.length).toBe(2)
- expect(vert['R'].styles[0]).toBe('background:#fff')
- expect(vert['R'].styles[1]).toBe('border:1px solid red')
- })
+ const edges = flow.parser.yy.getEdges();
- it('should handle multiple styles in a graph', function () {
- const res = flow.parser.parse('graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
+ expect(edges.length).toBe(1);
+ });
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('should handle multiple styles for a vortex', function() {
+ const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;');
- expect(vert['S'].styles.length).toBe(1)
- expect(vert['T'].styles.length).toBe(2)
- expect(vert['S'].styles[0]).toBe('background:#aaa')
- expect(vert['T'].styles[0]).toBe('background:#bbb')
- expect(vert['T'].styles[1]).toBe('border:1px solid red')
- })
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- it('should handle styles and graph definitons in a graph', function () {
- const res = flow.parser.parse('graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
+ expect(vert['R'].styles.length).toBe(2);
+ expect(vert['R'].styles[0]).toBe('background:#fff');
+ expect(vert['R'].styles[1]).toBe('border:1px solid red');
+ });
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ it('should handle multiple styles in a graph', function() {
+ const res = flow.parser.parse(
+ 'graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'
+ );
- expect(vert['S'].styles.length).toBe(1)
- expect(vert['T'].styles.length).toBe(2)
- expect(vert['S'].styles[0]).toBe('background:#aaa')
- expect(vert['T'].styles[0]).toBe('background:#bbb')
- expect(vert['T'].styles[1]).toBe('border:1px solid red')
- })
- it('should handle styles and graph definitons in a graph', function () {
- const res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;')
- // const res = flow.parser.parse('graph TD;style T background: #bbb;');
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
+ expect(vert['S'].styles.length).toBe(1);
+ expect(vert['T'].styles.length).toBe(2);
+ expect(vert['S'].styles[0]).toBe('background:#aaa');
+ expect(vert['T'].styles[0]).toBe('background:#bbb');
+ expect(vert['T'].styles[1]).toBe('border:1px solid red');
+ });
- expect(vert['T'].styles.length).toBe(2)
- expect(vert['T'].styles[0]).toBe('background:#bbb')
- expect(vert['T'].styles[1]).toBe('border:1px solid red')
- })
+ it('should handle styles and graph definitons in a graph', function() {
+ const res = flow.parser.parse(
+ 'graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'
+ );
- describe('special characters should be be handled.', function () {
- const charTest = function (char, result) {
- const res = flow.parser.parse('graph TD;A(' + char + ')-->B;')
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ expect(vert['S'].styles.length).toBe(1);
+ expect(vert['T'].styles.length).toBe(2);
+ expect(vert['S'].styles[0]).toBe('background:#aaa');
+ expect(vert['T'].styles[0]).toBe('background:#bbb');
+ expect(vert['T'].styles[1]).toBe('border:1px solid red');
+ });
+ it('should handle styles and graph definitons in a graph', function() {
+ const res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;');
+ // const res = flow.parser.parse('graph TD;style T background: #bbb;');
- expect(vert['A'].id).toBe('A')
- expect(vert['B'].id).toBe('B')
- if(result){
- expect(vert['A'].text).toBe(result)
- }else{
- expect(vert['A'].text).toBe(char)
+ const vert = flow.parser.yy.getVertices();
+
+ expect(vert['T'].styles.length).toBe(2);
+ expect(vert['T'].styles[0]).toBe('background:#bbb');
+ expect(vert['T'].styles[1]).toBe('border:1px solid red');
+ });
+
+ describe('special characters should be be handled.', function() {
+ const charTest = function(char, result) {
+ const res = flow.parser.parse('graph TD;A(' + char + ')-->B;');
+
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
+
+ expect(vert['A'].id).toBe('A');
+ expect(vert['B'].id).toBe('B');
+ if (result) {
+ expect(vert['A'].text).toBe(result);
+ } else {
+ expect(vert['A'].text).toBe(char);
}
- }
+ };
- it('it should be able to parse a \'.\'', function () {
- charTest('.')
- charTest('Start 103a.a1')
- })
+ it("it should be able to parse a '.'", function() {
+ charTest('.');
+ charTest('Start 103a.a1');
+ });
// it('it should be able to parse text containing \'_\'', function () {
// charTest('_')
// })
- it('it should be able to parse a \':\'', function () {
- charTest(':')
- })
+ it("it should be able to parse a ':'", function() {
+ charTest(':');
+ });
- it('it should be able to parse a \',\'', function () {
- charTest(',')
- })
+ it("it should be able to parse a ','", function() {
+ charTest(',');
+ });
- it('it should be able to parse text containing \'-\'', function () {
- charTest('a-b')
- })
+ it("it should be able to parse text containing '-'", function() {
+ charTest('a-b');
+ });
- it('it should be able to parse a \'+\'', function () {
- charTest('+')
- })
+ it("it should be able to parse a '+'", function() {
+ charTest('+');
+ });
- it('it should be able to parse a \'*\'', function () {
- charTest('*')
- })
+ it("it should be able to parse a '*'", function() {
+ charTest('*');
+ });
- it('it should be able to parse a \'<\'', function () {
- charTest('<','<')
- })
+ it("it should be able to parse a '<'", function() {
+ charTest('<', '<');
+ });
- it('it should be able to parse a \'>\'', function () {
- charTest('>','>')
- })
+ it("it should be able to parse a '>'", function() {
+ charTest('>', '>');
+ });
- it('it should be able to parse a \'=\'', function () {
- charTest('=','=')
- })
- it('it should be able to parse a \'&\'', function () {
- charTest('&')
- })
- })
+ it("it should be able to parse a '='", function() {
+ charTest('=', '=');
+ });
+ it("it should be able to parse a '&'", function() {
+ charTest('&');
+ });
+ });
- it('should be possible to declare a class', function () {
- const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1px solid red;')
- // const res = flow.parser.parse('graph TD;style T background: #bbb;');
+ it('should be possible to declare a class', function() {
+ const res = flow.parser.parse(
+ 'graph TD;classDef exClass background:#bbb,border:1px solid red;'
+ );
+ // const res = flow.parser.parse('graph TD;style T background: #bbb;');
- const classes = flow.parser.yy.getClasses()
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
- it('should be possible to declare a class with a dot in the style', function () {
- const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1.5px solid red;')
- // const res = flow.parser.parse('graph TD;style T background: #bbb;');
+ it('should be possible to declare a class with a dot in the style', function() {
+ const res = flow.parser.parse(
+ 'graph TD;classDef exClass background:#bbb,border:1.5px solid red;'
+ );
+ // const res = flow.parser.parse('graph TD;style T background: #bbb;');
- const classes = flow.parser.yy.getClasses()
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
- })
- it('should be possible to declare a class with a space in the style', function () {
- const res = flow.parser.parse('graph TD;classDef exClass background: #bbb,border:1.5px solid red;')
- // const res = flow.parser.parse('graph TD;style T background : #bbb;');
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red');
+ });
+ it('should be possible to declare a class with a space in the style', function() {
+ const res = flow.parser.parse(
+ 'graph TD;classDef exClass background: #bbb,border:1.5px solid red;'
+ );
+ // const res = flow.parser.parse('graph TD;style T background : #bbb;');
- const classes = flow.parser.yy.getClasses()
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background: #bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
- })
- it('should be possible to apply a class to a vertex', function () {
- let statement = ''
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background: #bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red');
+ });
+ it('should be possible to apply a class to a vertex', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'a-->b;' + '\n'
- statement = statement + 'class a exClass;'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'a-->b;' + '\n';
+ statement = statement + 'class a exClass;';
- const res = flow.parser.parse(statement)
+ const res = flow.parser.parse(statement);
- const classes = flow.parser.yy.getClasses()
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
- it('should be possible to apply a class to a vertex with an id containing _', function () {
- let statement = ''
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
+ it('should be possible to apply a class to a vertex with an id containing _', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'a_a-->b_b;' + '\n'
- statement = statement + 'class a_a exClass;'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'a_a-->b_b;' + '\n';
+ statement = statement + 'class a_a exClass;';
- const res = flow.parser.parse(statement)
+ const res = flow.parser.parse(statement);
- const classes = flow.parser.yy.getClasses()
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
- it('should be possible to apply a class to a vertex directly', function () {
- let statement = ''
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
+ it('should be possible to apply a class to a vertex directly', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'a-->b[test]:::exClass;' + '\n'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'a-->b[test]:::exClass;' + '\n';
- const res = flow.parser.parse(statement)
- const vertices = flow.parser.yy.getVertices()
- const classes = flow.parser.yy.getClasses()
+ const res = flow.parser.parse(statement);
+ const vertices = flow.parser.yy.getVertices();
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(vertices['b'].classes[0]).toBe('exClass')
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(vertices['b'].classes[0]).toBe('exClass');
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
- it('should be possible to apply a class to a vertex directly : usecase A[text].class ', function () {
- let statement = ''
+ it('should be possible to apply a class to a vertex directly : usecase A[text].class ', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'b[test]:::exClass;' + '\n'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'b[test]:::exClass;' + '\n';
- const res = flow.parser.parse(statement)
- const vertices = flow.parser.yy.getVertices()
- const classes = flow.parser.yy.getClasses()
+ const res = flow.parser.parse(statement);
+ const vertices = flow.parser.yy.getVertices();
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(vertices['b'].classes[0]).toBe('exClass')
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(vertices['b'].classes[0]).toBe('exClass');
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
- it('should be possible to apply a class to a vertex directly : usecase A[text].class-->B[test2] ', function () {
- let statement = ''
+ it('should be possible to apply a class to a vertex directly : usecase A[text].class-->B[test2] ', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'A[test]:::exClass-->B[test2];' + '\n'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'A[test]:::exClass-->B[test2];' + '\n';
- const res = flow.parser.parse(statement)
- const vertices = flow.parser.yy.getVertices()
- const classes = flow.parser.yy.getClasses()
+ const res = flow.parser.parse(statement);
+ const vertices = flow.parser.yy.getVertices();
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(vertices['A'].classes[0]).toBe('exClass')
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(vertices['A'].classes[0]).toBe('exClass');
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
- it('should be possible to apply a class to a vertex directly 2', function () {
- let statement = ''
+ it('should be possible to apply a class to a vertex directly 2', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'a-->b[1 a a text!.]:::exClass;' + '\n'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'a-->b[1 a a text!.]:::exClass;' + '\n';
- const res = flow.parser.parse(statement)
- const vertices = flow.parser.yy.getVertices()
- const classes = flow.parser.yy.getClasses()
+ const res = flow.parser.parse(statement);
+ const vertices = flow.parser.yy.getVertices();
+ const classes = flow.parser.yy.getClasses();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(vertices['b'].classes[0]).toBe('exClass')
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- })
- it('should be possible to apply a class to a comma separated list of vertices', function () {
- let statement = ''
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(vertices['b'].classes[0]).toBe('exClass');
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ });
+ it('should be possible to apply a class to a comma separated list of vertices', function() {
+ let statement = '';
- statement = statement + 'graph TD;' + '\n'
- statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
- statement = statement + 'a-->b;' + '\n'
- statement = statement + 'class a,b exClass;'
+ statement = statement + 'graph TD;' + '\n';
+ statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n';
+ statement = statement + 'a-->b;' + '\n';
+ statement = statement + 'class a,b exClass;';
- const res = flow.parser.parse(statement)
+ const res = flow.parser.parse(statement);
- const classes = flow.parser.yy.getClasses()
- const vertices = flow.parser.yy.getVertices()
+ const classes = flow.parser.yy.getClasses();
+ const vertices = flow.parser.yy.getVertices();
- expect(classes['exClass'].styles.length).toBe(2)
- expect(classes['exClass'].styles[0]).toBe('background:#bbb')
- expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
- expect(vertices['a'].classes[0]).toBe('exClass')
- expect(vertices['b'].classes[0]).toBe('exClass')
- })
-})
+ expect(classes['exClass'].styles.length).toBe(2);
+ expect(classes['exClass'].styles[0]).toBe('background:#bbb');
+ expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
+ expect(vertices['a'].classes[0]).toBe('exClass');
+ expect(vertices['b'].classes[0]).toBe('exClass');
+ });
+});
diff --git a/src/diagrams/flowchart/parser/subgraph.spec.js b/src/diagrams/flowchart/parser/subgraph.spec.js
index 6a33c30be..0bf3e63d6 100644
--- a/src/diagrams/flowchart/parser/subgraph.spec.js
+++ b/src/diagrams/flowchart/parser/subgraph.spec.js
@@ -1,223 +1,223 @@
-import flowDb from '../flowDb'
-import flow from './flow'
-import { setConfig } from '../../../config'
+import flowDb from '../flowDb';
+import flow from './flow';
+import { setConfig } from '../../../config';
setConfig({
- securityLevel: 'strict',
-})
+ securityLevel: 'strict'
+});
-describe('when parsing subgraphs', function () {
- beforeEach(function () {
- flow.parser.yy = flowDb
- flow.parser.yy.clear()
- })
- it('should handle subgraph with tab indentation', function () {
- const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a2')
- expect(subgraph.nodes[1]).toBe('a1')
- expect(subgraph.title).toBe('One')
- expect(subgraph.id).toBe('One')
- })
- it('should handle subgraph with chaining nodes indentation', function () {
- const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2-->a3\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(3)
- expect(subgraph.nodes[0]).toBe('a3')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.nodes[2]).toBe('a1')
- expect(subgraph.title).toBe('One')
- expect(subgraph.id).toBe('One')
- })
-
- it('should handle subgraph with multiple words in title', function () {
- const res = flow.parser.parse('graph TB\nsubgraph "Some Title"\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a2')
- expect(subgraph.nodes[1]).toBe('a1')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('subGraph0')
+describe('when parsing subgraphs', function() {
+ beforeEach(function() {
+ flow.parser.yy = flowDb;
+ flow.parser.yy.clear();
+ });
+ it('should handle subgraph with tab indentation', function() {
+ const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend');
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(2);
+ expect(subgraph.nodes[0]).toBe('a2');
+ expect(subgraph.nodes[1]).toBe('a1');
+ expect(subgraph.title).toBe('One');
+ expect(subgraph.id).toBe('One');
+ });
+ it('should handle subgraph with chaining nodes indentation', function() {
+ const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2-->a3\nend');
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(3);
+ expect(subgraph.nodes[0]).toBe('a3');
+ expect(subgraph.nodes[1]).toBe('a2');
+ expect(subgraph.nodes[2]).toBe('a1');
+ expect(subgraph.title).toBe('One');
+ expect(subgraph.id).toBe('One');
});
- it('should handle subgraph with id and title notation', function () {
- const res = flow.parser.parse('graph TB\nsubgraph some-id[Some Title]\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a2')
- expect(subgraph.nodes[1]).toBe('a1')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('some-id')
+ it('should handle subgraph with multiple words in title', function() {
+ const res = flow.parser.parse('graph TB\nsubgraph "Some Title"\n\ta1-->a2\nend');
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(2);
+ expect(subgraph.nodes[0]).toBe('a2');
+ expect(subgraph.nodes[1]).toBe('a1');
+ expect(subgraph.title).toBe('Some Title');
+ expect(subgraph.id).toBe('subGraph0');
});
- xit('should handle subgraph without id and space in title', function () {
- const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a1')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('some-id')
+ it('should handle subgraph with id and title notation', function() {
+ const res = flow.parser.parse('graph TB\nsubgraph some-id[Some Title]\n\ta1-->a2\nend');
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(2);
+ expect(subgraph.nodes[0]).toBe('a2');
+ expect(subgraph.nodes[1]).toBe('a1');
+ expect(subgraph.title).toBe('Some Title');
+ expect(subgraph.id).toBe('some-id');
});
- it('should handle subgraph id starting with a number', function () {
+ xit('should handle subgraph without id and space in title', function() {
+ const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend');
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(2);
+ expect(subgraph.nodes[0]).toBe('a1');
+ expect(subgraph.nodes[1]).toBe('a2');
+ expect(subgraph.title).toBe('Some Title');
+ expect(subgraph.id).toBe('some-id');
+ });
+
+ it('should handle subgraph id starting with a number', function() {
const res = flow.parser.parse(`graph TD
A[Christmas] -->|Get money| B(Go shopping)
subgraph 1test
A
- end`)
+ end`);
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(1)
- expect(subgraph.nodes[0]).toBe('A')
- expect(subgraph.id).toBe('s1test')
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
+ expect(subgraph.nodes.length).toBe(1);
+ expect(subgraph.nodes[0]).toBe('A');
+ expect(subgraph.id).toBe('s1test');
});
- it('should handle subgraphs1', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;')
+ it('should handle subgraphs1', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs with title in quotes', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph "title in quotes";c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs with title in quotes', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph "title in quotes";c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('title in quotes')
+ expect(subgraph.title).toBe('title in quotes');
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs in old style that was broken', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph old style that is broken;c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs in old style that was broken', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph old style that is broken;c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('old style that is broken')
+ expect(subgraph.title).toBe('old style that is broken');
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs with dashes in the title', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph a-b-c;c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs with dashes in the title', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph a-b-c;c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('a-b-c')
+ expect(subgraph.title).toBe('a-b-c');
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs with id and title in brackets', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph uid1[text of doom];c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs with id and title in brackets', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph uid1[text of doom];c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('text of doom')
- expect(subgraph.id).toBe('uid1')
+ expect(subgraph.title).toBe('text of doom');
+ expect(subgraph.id).toBe('uid1');
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs with id and title in brackets and quotes', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph uid2["text of doom"];c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs with id and title in brackets and quotes', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph uid2["text of doom"];c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('text of doom')
- expect(subgraph.id).toBe('uid2')
+ expect(subgraph.title).toBe('text of doom');
+ expect(subgraph.id).toBe('uid2');
- expect(edges[0].type).toBe('arrow')
- })
- it('should handle subgraphs with id and title in brackets without spaces', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph uid2[textofdoom];c-->d;end;')
+ expect(edges[0].type).toBe('arrow');
+ });
+ it('should handle subgraphs with id and title in brackets without spaces', function() {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph uid2[textofdoom];c-->d;end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
+ const subgraphs = flow.parser.yy.getSubGraphs();
+ expect(subgraphs.length).toBe(1);
+ const subgraph = subgraphs[0];
- expect(subgraph.title).toBe('textofdoom')
- expect(subgraph.id).toBe('uid2')
+ expect(subgraph.title).toBe('textofdoom');
+ expect(subgraph.id).toBe('uid2');
- expect(edges[0].type).toBe('arrow')
- })
+ expect(edges[0].type).toBe('arrow');
+ });
- it('should handle subgraphs2', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n')
+ it('should handle subgraphs2', function() {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
+ expect(edges[0].type).toBe('arrow');
+ });
- it('should handle nested subgraphs', function () {
- const str = 'graph TD\n' +
- 'A-->B\n' +
- 'subgraph myTitle\n\n' +
- ' c-->d \n\n' +
- ' subgraph inner\n\n e-->f \n end \n\n' +
- ' subgraph inner\n\n h-->i \n end \n\n' +
- 'end\n'
- const res = flow.parser.parse(str)
- })
+ it('should handle nested subgraphs', function() {
+ const str =
+ 'graph TD\n' +
+ 'A-->B\n' +
+ 'subgraph myTitle\n\n' +
+ ' c-->d \n\n' +
+ ' subgraph inner\n\n e-->f \n end \n\n' +
+ ' subgraph inner\n\n h-->i \n end \n\n' +
+ 'end\n';
+ const res = flow.parser.parse(str);
+ });
- it('should handle subgraphs4', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;')
+ it('should handle subgraphs4', function() {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
+ expect(edges[0].type).toBe('arrow');
+ });
- it('should handle subgraphs5', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;')
+ it('should handle subgraphs5', function() {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;');
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
+ const vert = flow.parser.yy.getVertices();
+ const edges = flow.parser.yy.getEdges();
- expect(edges[0].type).toBe('arrow')
- })
-
-})
+ expect(edges[0].type).toBe('arrow');
+ });
+});
diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js
index 46ba09e04..9eb2b8c38 100644
--- a/src/diagrams/gantt/ganttDb.js
+++ b/src/diagrams/gantt/ganttDb.js
@@ -1,217 +1,214 @@
-import moment from 'moment-mini'
-import { sanitizeUrl } from '@braintree/sanitize-url'
-import { logger } from '../../logger'
-import { getConfig } from '../../config'
+import moment from 'moment-mini';
+import { sanitizeUrl } from '@braintree/sanitize-url';
+import { logger } from '../../logger';
+import { getConfig } from '../../config';
-const config = getConfig()
-let dateFormat = ''
-let axisFormat = ''
-let excludes = []
-let title = ''
-let sections = []
-let tasks = []
-let currentSection = ''
-const tags = ['active', 'done', 'crit', 'milestone']
-let funs = []
-let inclusiveEndDates = false
+const config = getConfig();
+let dateFormat = '';
+let axisFormat = '';
+let excludes = [];
+let title = '';
+let sections = [];
+let tasks = [];
+let currentSection = '';
+const tags = ['active', 'done', 'crit', 'milestone'];
+let funs = [];
+let inclusiveEndDates = false;
-export const clear = function () {
- sections = []
- tasks = []
- currentSection = ''
- funs = []
- title = ''
- taskCnt = 0
- lastTask = undefined
- lastTaskID = undefined
- rawTasks = []
- dateFormat = ''
- axisFormat = ''
- excludes = []
- inclusiveEndDates = false
-}
+export const clear = function() {
+ sections = [];
+ tasks = [];
+ currentSection = '';
+ funs = [];
+ title = '';
+ taskCnt = 0;
+ lastTask = undefined;
+ lastTaskID = undefined;
+ rawTasks = [];
+ dateFormat = '';
+ axisFormat = '';
+ excludes = [];
+ inclusiveEndDates = false;
+};
-export const setAxisFormat = function (txt) {
- axisFormat = txt
-}
+export const setAxisFormat = function(txt) {
+ axisFormat = txt;
+};
-export const getAxisFormat = function () {
- return axisFormat
-}
+export const getAxisFormat = function() {
+ return axisFormat;
+};
-export const setDateFormat = function (txt) {
- dateFormat = txt
-}
+export const setDateFormat = function(txt) {
+ dateFormat = txt;
+};
-export const enableInclusiveEndDates = function () {
- inclusiveEndDates = true
-}
+export const enableInclusiveEndDates = function() {
+ inclusiveEndDates = true;
+};
-export const endDatesAreInclusive = function () {
- return inclusiveEndDates
-}
+export const endDatesAreInclusive = function() {
+ return inclusiveEndDates;
+};
-export const getDateFormat = function () {
- return dateFormat
-}
+export const getDateFormat = function() {
+ return dateFormat;
+};
-export const setExcludes = function (txt) {
- excludes = txt.toLowerCase().split(/[\s,]+/)
-}
+export const setExcludes = function(txt) {
+ excludes = txt.toLowerCase().split(/[\s,]+/);
+};
-export const getExcludes = function () {
- return excludes
-}
+export const getExcludes = function() {
+ return excludes;
+};
-export const setTitle = function (txt) {
- title = txt
-}
+export const setTitle = function(txt) {
+ title = txt;
+};
-export const getTitle = function () {
- return title
-}
+export const getTitle = function() {
+ return title;
+};
-export const addSection = function (txt) {
- currentSection = txt
- sections.push(txt)
-}
+export const addSection = function(txt) {
+ currentSection = txt;
+ sections.push(txt);
+};
-export const getSections = function () {
- return sections
-}
+export const getSections = function() {
+ return sections;
+};
-export const getTasks = function () {
- let allItemsPricessed = compileTasks()
- const maxDepth = 10
- let iterationCount = 0
- while (!allItemsPricessed && (iterationCount < maxDepth)) {
- allItemsPricessed = compileTasks()
- iterationCount++
+export const getTasks = function() {
+ let allItemsPricessed = compileTasks();
+ const maxDepth = 10;
+ let iterationCount = 0;
+ while (!allItemsPricessed && iterationCount < maxDepth) {
+ allItemsPricessed = compileTasks();
+ iterationCount++;
}
- tasks = rawTasks
+ tasks = rawTasks;
- return tasks
-}
+ return tasks;
+};
-const isInvalidDate = function (date, dateFormat, excludes) {
+const isInvalidDate = function(date, dateFormat, excludes) {
if (date.isoWeekday() >= 6 && excludes.indexOf('weekends') >= 0) {
- return true
+ return true;
}
if (excludes.indexOf(date.format('dddd').toLowerCase()) >= 0) {
- return true
+ return true;
}
- return excludes.indexOf(date.format(dateFormat.trim())) >= 0
-}
+ return excludes.indexOf(date.format(dateFormat.trim())) >= 0;
+};
-const checkTaskDates = function (task, dateFormat, excludes) {
- if (!excludes.length || task.manualEndTime) return
- let startTime = moment(task.startTime, dateFormat, true)
- startTime.add(1, 'd')
- let endTime = moment(task.endTime, dateFormat, true)
- let renderEndTime = fixTaskDates(startTime, endTime, dateFormat, excludes)
- task.endTime = endTime.toDate()
- task.renderEndTime = renderEndTime
-}
+const checkTaskDates = function(task, dateFormat, excludes) {
+ if (!excludes.length || task.manualEndTime) return;
+ let startTime = moment(task.startTime, dateFormat, true);
+ startTime.add(1, 'd');
+ let endTime = moment(task.endTime, dateFormat, true);
+ let renderEndTime = fixTaskDates(startTime, endTime, dateFormat, excludes);
+ task.endTime = endTime.toDate();
+ task.renderEndTime = renderEndTime;
+};
-const fixTaskDates = function (startTime, endTime, dateFormat, excludes) {
- let invalid = false
- let renderEndTime = null
+const fixTaskDates = function(startTime, endTime, dateFormat, excludes) {
+ let invalid = false;
+ let renderEndTime = null;
while (startTime.date() <= endTime.date()) {
if (!invalid) {
- renderEndTime = endTime.toDate()
+ renderEndTime = endTime.toDate();
}
- invalid = isInvalidDate(startTime, dateFormat, excludes)
+ invalid = isInvalidDate(startTime, dateFormat, excludes);
if (invalid) {
- endTime.add(1, 'd')
+ endTime.add(1, 'd');
}
- startTime.add(1, 'd')
+ startTime.add(1, 'd');
}
- return renderEndTime
-}
+ return renderEndTime;
+};
-const getStartDate = function (prevTime, dateFormat, str) {
- str = str.trim()
+const getStartDate = function(prevTime, dateFormat, str) {
+ str = str.trim();
// Test for after
- const re = /^after\s+([\d\w-]+)/
- const afterStatement = re.exec(str.trim())
+ const re = /^after\s+([\d\w-]+)/;
+ const afterStatement = re.exec(str.trim());
if (afterStatement !== null) {
- const task = findTaskById(afterStatement[1])
+ const task = findTaskById(afterStatement[1]);
if (typeof task === 'undefined') {
- const dt = new Date()
- dt.setHours(0, 0, 0, 0)
- return dt
+ const dt = new Date();
+ dt.setHours(0, 0, 0, 0);
+ return dt;
}
- return task.endTime
+ return task.endTime;
}
// Check for actual date set
- let mDate = moment(str, dateFormat.trim(), true)
+ let mDate = moment(str, dateFormat.trim(), true);
if (mDate.isValid()) {
- return mDate.toDate()
+ return mDate.toDate();
} else {
- logger.debug('Invalid date:' + str)
- logger.debug('With date format:' + dateFormat.trim())
+ logger.debug('Invalid date:' + str);
+ logger.debug('With date format:' + dateFormat.trim());
}
// Default date - now
- return new Date()
-}
+ return new Date();
+};
-const durationToDate = function (durationStatement, relativeTime) {
+const durationToDate = function(durationStatement, relativeTime) {
if (durationStatement !== null) {
switch (durationStatement[2]) {
case 's':
- relativeTime.add(durationStatement[1], 'seconds')
- break
+ relativeTime.add(durationStatement[1], 'seconds');
+ break;
case 'm':
- relativeTime.add(durationStatement[1], 'minutes')
- break
+ relativeTime.add(durationStatement[1], 'minutes');
+ break;
case 'h':
- relativeTime.add(durationStatement[1], 'hours')
- break
+ relativeTime.add(durationStatement[1], 'hours');
+ break;
case 'd':
- relativeTime.add(durationStatement[1], 'days')
- break
+ relativeTime.add(durationStatement[1], 'days');
+ break;
case 'w':
- relativeTime.add(durationStatement[1], 'weeks')
- break
+ relativeTime.add(durationStatement[1], 'weeks');
+ break;
}
}
// Default date - now
- return relativeTime.toDate()
-}
+ return relativeTime.toDate();
+};
-const getEndDate = function (prevTime, dateFormat, str, inclusive) {
- inclusive = inclusive || false
- str = str.trim()
+const getEndDate = function(prevTime, dateFormat, str, inclusive) {
+ inclusive = inclusive || false;
+ str = str.trim();
// Check for actual date
- let mDate = moment(str, dateFormat.trim(), true)
+ let mDate = moment(str, dateFormat.trim(), true);
if (mDate.isValid()) {
if (inclusive) {
- mDate.add(1, 'd')
+ mDate.add(1, 'd');
}
- return mDate.toDate()
+ return mDate.toDate();
}
- return durationToDate(
- /^([\d]+)([wdhms])/.exec(str.trim()),
- moment(prevTime)
- )
-}
+ return durationToDate(/^([\d]+)([wdhms])/.exec(str.trim()), moment(prevTime));
+};
-let taskCnt = 0
-const parseId = function (idStr) {
+let taskCnt = 0;
+const parseId = function(idStr) {
if (typeof idStr === 'undefined') {
- taskCnt = taskCnt + 1
- return 'task' + taskCnt
+ taskCnt = taskCnt + 1;
+ return 'task' + taskCnt;
}
- return idStr
-}
+ return idStr;
+};
// id, startDate, endDate
// id, startDate, length
// id, after x, endDate
@@ -223,116 +220,116 @@ const parseId = function (idStr) {
// endDate
// length
-const compileData = function (prevTask, dataStr) {
- let ds
+const compileData = function(prevTask, dataStr) {
+ let ds;
if (dataStr.substr(0, 1) === ':') {
- ds = dataStr.substr(1, dataStr.length)
+ ds = dataStr.substr(1, dataStr.length);
} else {
- ds = dataStr
+ ds = dataStr;
}
- const data = ds.split(',')
+ const data = ds.split(',');
- const task = {}
+ const task = {};
// Get tags like active, done, crit and milestone
- getTaskTags(data, task, tags)
+ getTaskTags(data, task, tags);
for (let i = 0; i < data.length; i++) {
- data[i] = data[i].trim()
+ data[i] = data[i].trim();
}
- let endTimeData = ''
+ let endTimeData = '';
switch (data.length) {
case 1:
- task.id = parseId()
- task.startTime = prevTask.endTime
- endTimeData = data[0]
- break
+ task.id = parseId();
+ task.startTime = prevTask.endTime;
+ endTimeData = data[0];
+ break;
case 2:
- task.id = parseId()
- task.startTime = getStartDate(undefined, dateFormat, data[0])
- endTimeData = data[1]
- break
+ task.id = parseId();
+ task.startTime = getStartDate(undefined, dateFormat, data[0]);
+ endTimeData = data[1];
+ break;
case 3:
- task.id = parseId(data[0])
- task.startTime = getStartDate(undefined, dateFormat, data[1])
- endTimeData = data[2]
- break
+ task.id = parseId(data[0]);
+ task.startTime = getStartDate(undefined, dateFormat, data[1]);
+ endTimeData = data[2];
+ break;
default:
}
if (endTimeData) {
- task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates)
- task.manualEndTime = moment(endTimeData, 'YYYY-MM-DD', true).isValid()
- checkTaskDates(task, dateFormat, excludes)
+ task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates);
+ task.manualEndTime = moment(endTimeData, 'YYYY-MM-DD', true).isValid();
+ checkTaskDates(task, dateFormat, excludes);
}
- return task
-}
+ return task;
+};
-const parseData = function (prevTaskId, dataStr) {
- let ds
+const parseData = function(prevTaskId, dataStr) {
+ let ds;
if (dataStr.substr(0, 1) === ':') {
- ds = dataStr.substr(1, dataStr.length)
+ ds = dataStr.substr(1, dataStr.length);
} else {
- ds = dataStr
+ ds = dataStr;
}
- const data = ds.split(',')
+ const data = ds.split(',');
- const task = {}
+ const task = {};
// Get tags like active, done, crit and milestone
- getTaskTags(data, task, tags)
+ getTaskTags(data, task, tags);
for (let i = 0; i < data.length; i++) {
- data[i] = data[i].trim()
+ data[i] = data[i].trim();
}
switch (data.length) {
case 1:
- task.id = parseId()
+ task.id = parseId();
task.startTime = {
type: 'prevTaskEnd',
id: prevTaskId
- }
+ };
task.endTime = {
data: data[0]
- }
- break
+ };
+ break;
case 2:
- task.id = parseId()
+ task.id = parseId();
task.startTime = {
type: 'getStartDate',
startData: data[0]
- }
+ };
task.endTime = {
data: data[1]
- }
- break
+ };
+ break;
case 3:
- task.id = parseId(data[0])
+ task.id = parseId(data[0]);
task.startTime = {
type: 'getStartDate',
startData: data[1]
- }
+ };
task.endTime = {
data: data[2]
- }
- break
+ };
+ break;
default:
}
- return task
-}
+ return task;
+};
-let lastTask
-let lastTaskID
-let rawTasks = []
-const taskDb = {}
-export const addTask = function (descr, data) {
+let lastTask;
+let lastTaskID;
+let rawTasks = [];
+const taskDb = {};
+export const addTask = function(descr, data) {
const rawTask = {
section: currentSection,
type: currentSection,
@@ -342,174 +339,187 @@ export const addTask = function (descr, data) {
raw: { data: data },
task: descr,
classes: []
- }
- const taskInfo = parseData(lastTaskID, data)
- rawTask.raw.startTime = taskInfo.startTime
- rawTask.raw.endTime = taskInfo.endTime
- rawTask.id = taskInfo.id
- rawTask.prevTaskId = lastTaskID
- rawTask.active = taskInfo.active
- rawTask.done = taskInfo.done
- rawTask.crit = taskInfo.crit
- rawTask.milestone = taskInfo.milestone
+ };
+ const taskInfo = parseData(lastTaskID, data);
+ rawTask.raw.startTime = taskInfo.startTime;
+ rawTask.raw.endTime = taskInfo.endTime;
+ rawTask.id = taskInfo.id;
+ rawTask.prevTaskId = lastTaskID;
+ rawTask.active = taskInfo.active;
+ rawTask.done = taskInfo.done;
+ rawTask.crit = taskInfo.crit;
+ rawTask.milestone = taskInfo.milestone;
- const pos = rawTasks.push(rawTask)
+ const pos = rawTasks.push(rawTask);
- lastTaskID = rawTask.id
+ lastTaskID = rawTask.id;
// Store cross ref
- taskDb[rawTask.id] = pos - 1
-}
+ taskDb[rawTask.id] = pos - 1;
+};
-export const findTaskById = function (id) {
- const pos = taskDb[id]
- return rawTasks[pos]
-}
+export const findTaskById = function(id) {
+ const pos = taskDb[id];
+ return rawTasks[pos];
+};
-export const addTaskOrg = function (descr, data) {
+export const addTaskOrg = function(descr, data) {
const newTask = {
section: currentSection,
type: currentSection,
description: descr,
task: descr,
classes: []
- }
- const taskInfo = compileData(lastTask, data)
- newTask.startTime = taskInfo.startTime
- newTask.endTime = taskInfo.endTime
- newTask.id = taskInfo.id
- newTask.active = taskInfo.active
- newTask.done = taskInfo.done
- newTask.crit = taskInfo.crit
- newTask.milestone = taskInfo.milestone
- lastTask = newTask
- tasks.push(newTask)
-}
+ };
+ const taskInfo = compileData(lastTask, data);
+ newTask.startTime = taskInfo.startTime;
+ newTask.endTime = taskInfo.endTime;
+ newTask.id = taskInfo.id;
+ newTask.active = taskInfo.active;
+ newTask.done = taskInfo.done;
+ newTask.crit = taskInfo.crit;
+ newTask.milestone = taskInfo.milestone;
+ lastTask = newTask;
+ tasks.push(newTask);
+};
-const compileTasks = function () {
- const compileTask = function (pos) {
- const task = rawTasks[pos]
- let startTime = ''
+const compileTasks = function() {
+ const compileTask = function(pos) {
+ const task = rawTasks[pos];
+ let startTime = '';
switch (rawTasks[pos].raw.startTime.type) {
case 'prevTaskEnd':
- const prevTask = findTaskById(task.prevTaskId)
- task.startTime = prevTask.endTime
- break
+ const prevTask = findTaskById(task.prevTaskId);
+ task.startTime = prevTask.endTime;
+ break;
case 'getStartDate':
- startTime = getStartDate(undefined, dateFormat, rawTasks[pos].raw.startTime.startData)
+ startTime = getStartDate(undefined, dateFormat, rawTasks[pos].raw.startTime.startData);
if (startTime) {
- rawTasks[pos].startTime = startTime
+ rawTasks[pos].startTime = startTime;
}
- break
+ break;
}
if (rawTasks[pos].startTime) {
- rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, rawTasks[pos].raw.endTime.data, inclusiveEndDates)
+ rawTasks[pos].endTime = getEndDate(
+ rawTasks[pos].startTime,
+ dateFormat,
+ rawTasks[pos].raw.endTime.data,
+ inclusiveEndDates
+ );
if (rawTasks[pos].endTime) {
- rawTasks[pos].processed = true
- rawTasks[pos].manualEndTime = moment(rawTasks[pos].raw.endTime.data, 'YYYY-MM-DD', true).isValid()
- checkTaskDates(rawTasks[pos], dateFormat, excludes)
+ rawTasks[pos].processed = true;
+ rawTasks[pos].manualEndTime = moment(
+ rawTasks[pos].raw.endTime.data,
+ 'YYYY-MM-DD',
+ true
+ ).isValid();
+ checkTaskDates(rawTasks[pos], dateFormat, excludes);
}
}
- return rawTasks[pos].processed
- }
+ return rawTasks[pos].processed;
+ };
- let allProcessed = true
+ let allProcessed = true;
for (let i = 0; i < rawTasks.length; i++) {
- compileTask(i)
+ compileTask(i);
- allProcessed = allProcessed && rawTasks[i].processed
+ allProcessed = allProcessed && rawTasks[i].processed;
}
- return allProcessed
-}
+ return allProcessed;
+};
/**
* Called by parser when a link is found. Adds the URL to the vertex data.
* @param ids Comma separated list of ids
* @param linkStr URL to create a link for
*/
-export const setLink = function (ids, _linkStr) {
- let linkStr = _linkStr
+export const setLink = function(ids, _linkStr) {
+ let linkStr = _linkStr;
if (config.securityLevel !== 'loose') {
- linkStr = sanitizeUrl(_linkStr)
+ linkStr = sanitizeUrl(_linkStr);
}
- ids.split(',').forEach(function (id) {
- let rawTask = findTaskById(id)
+ ids.split(',').forEach(function(id) {
+ let rawTask = findTaskById(id);
if (typeof rawTask !== 'undefined') {
- pushFun(id, () => { window.open(linkStr, '_self') })
+ pushFun(id, () => {
+ window.open(linkStr, '_self');
+ });
}
- })
- setClass(ids, 'clickable')
-}
+ });
+ setClass(ids, 'clickable');
+};
/**
* Called by parser when a special node is found, e.g. a clickable element.
* @param ids Comma separated list of ids
* @param className Class to add
*/
-export const setClass = function (ids, className) {
- ids.split(',').forEach(function (id) {
- let rawTask = findTaskById(id)
+export const setClass = function(ids, className) {
+ ids.split(',').forEach(function(id) {
+ let rawTask = findTaskById(id);
if (typeof rawTask !== 'undefined') {
- rawTask.classes.push(className)
+ rawTask.classes.push(className);
}
- })
-}
+ });
+};
-const setClickFun = function (id, functionName, functionArgs) {
+const setClickFun = function(id, functionName, functionArgs) {
if (config.securityLevel !== 'loose') {
- return
+ return;
}
if (typeof functionName === 'undefined') {
- return
+ return;
}
- let argList = []
+ let argList = [];
if (typeof functionArgs === 'string') {
/* Splits functionArgs by ',', ignoring all ',' in double quoted strings */
- argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/)
+ argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
for (let i = 0; i < argList.length; i++) {
- let item = argList[i].trim()
+ let item = argList[i].trim();
/* Removes all double quotes at the start and end of an argument */
/* This preserves all starting and ending whitespace inside */
if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
- item = item.substr(1, item.length - 2)
+ item = item.substr(1, item.length - 2);
}
- argList[i] = item
+ argList[i] = item;
}
}
- let rawTask = findTaskById(id)
+ let rawTask = findTaskById(id);
if (typeof rawTask !== 'undefined') {
- pushFun(id, () => { window[functionName](...argList) })
+ pushFun(id, () => {
+ window[functionName](...argList);
+ });
}
-}
+};
/**
* The callbackFunction is executed in a click event bound to the task with the specified id or the task's assigned text
* @param id The task's id
* @param callbackFunction A function to be executed when clicked on the task or the task's text
*/
-const pushFun = function (id, callbackFunction) {
- funs.push(function (element) {
+const pushFun = function(id, callbackFunction) {
+ funs.push(function(element) {
// const elem = d3.select(element).select(`[id="${id}"]`)
- const elem = document.querySelector(`[id="${id}"]`)
+ const elem = document.querySelector(`[id="${id}"]`);
if (elem !== null) {
- elem.addEventListener('click', function () {
- callbackFunction()
- })
+ elem.addEventListener('click', function() {
+ callbackFunction();
+ });
}
- })
- funs.push(function (element) {
+ });
+ funs.push(function(element) {
// const elem = d3.select(element).select(`[id="${id}-text"]`)
- const elem = document.querySelector(`[id="${id}-text"]`)
+ const elem = document.querySelector(`[id="${id}-text"]`);
if (elem !== null) {
- elem.addEventListener('click', function () {
- callbackFunction()
- })
+ elem.addEventListener('click', function() {
+ callbackFunction();
+ });
}
- })
-}
+ });
+};
/**
* Called by parser when a click definition is found. Registers an event handler.
@@ -517,22 +527,22 @@ const pushFun = function (id, callbackFunction) {
* @param functionName Function to be called on click
* @param functionArgs Function args the function should be called with
*/
-export const setClickEvent = function (ids, functionName, functionArgs) {
- ids.split(',').forEach(function (id) {
- setClickFun(id, functionName, functionArgs)
- })
- setClass(ids, 'clickable')
-}
+export const setClickEvent = function(ids, functionName, functionArgs) {
+ ids.split(',').forEach(function(id) {
+ setClickFun(id, functionName, functionArgs);
+ });
+ setClass(ids, 'clickable');
+};
/**
* Binds all functions previously added to fun (specified through click) to the element
* @param element
*/
-export const bindFunctions = function (element) {
- funs.forEach(function (fun) {
- fun(element)
- })
-}
+export const bindFunctions = function(element) {
+ funs.forEach(function(fun) {
+ fun(element);
+ });
+};
export default {
clear,
@@ -556,20 +566,20 @@ export default {
setLink,
bindFunctions,
durationToDate
-}
+};
-function getTaskTags (data, task, tags) {
- let matchFound = true
+function getTaskTags(data, task, tags) {
+ let matchFound = true;
while (matchFound) {
- matchFound = false
- tags.forEach(function (t) {
- const pattern = '^\\s*' + t + '\\s*$'
- const regex = new RegExp(pattern)
+ matchFound = false;
+ tags.forEach(function(t) {
+ const pattern = '^\\s*' + t + '\\s*$';
+ const regex = new RegExp(pattern);
if (data[0].match(regex)) {
- task[t] = true
- data.shift(1)
- matchFound = true
+ task[t] = true;
+ data.shift(1);
+ matchFound = true;
}
- })
+ });
}
}
diff --git a/src/diagrams/gantt/ganttDb.spec.js b/src/diagrams/gantt/ganttDb.spec.js
index 1dad71ad6..433e3a495 100644
--- a/src/diagrams/gantt/ganttDb.spec.js
+++ b/src/diagrams/gantt/ganttDb.spec.js
@@ -1,32 +1,32 @@
/* eslint-env jasmine */
-import moment from 'moment-mini'
-import ganttDb from './ganttDb'
+import moment from 'moment-mini';
+import ganttDb from './ganttDb';
-describe('when using the ganttDb', function () {
- beforeEach(function () {
- ganttDb.clear()
- })
+describe('when using the ganttDb', function() {
+ beforeEach(function() {
+ ganttDb.clear();
+ });
- describe('when using relative times', function () {
+ describe('when using relative times', function() {
it.each`
- diff | date | expected
- ${' 1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()}
- ${' 1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()}
+ diff | date | expected
+ ${' 1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()}
+ ${' 1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()}
`('should add $diff to $date resulting in $expected', ({ diff, date, expected }) => {
- expect(ganttDb.durationToDate(diff, date)).toEqual(expected)
-})
- })
+ expect(ganttDb.durationToDate(diff, date)).toEqual(expected);
+ });
+ });
- describe('when calling the clear function', function () {
- beforeEach(function () {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.enableInclusiveEndDates()
- ganttDb.setExcludes('weekends 2019-02-06,friday')
- ganttDb.addSection('weekends skip test')
- ganttDb.addTask('test1', 'id1,2019-02-01,1d')
- ganttDb.addTask('test2', 'id2,after id1,2d')
- ganttDb.clear()
- })
+ describe('when calling the clear function', function() {
+ beforeEach(function() {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.enableInclusiveEndDates();
+ ganttDb.setExcludes('weekends 2019-02-06,friday');
+ ganttDb.addSection('weekends skip test');
+ ganttDb.addTask('test1', 'id1,2019-02-01,1d');
+ ganttDb.addTask('test2', 'id2,after id1,2d');
+ ganttDb.clear();
+ });
it.each`
fn | expected
@@ -38,9 +38,9 @@ describe('when using the ganttDb', function () {
${'getSections'} | ${[]}
${'endDatesAreInclusive'} | ${false}
`('should clear $fn', ({ fn, expected }) => {
- expect(ganttDb[ fn ]()).toEqual(expected)
-})
- })
+ expect(ganttDb[fn]()).toEqual(expected);
+ });
+ });
it.each`
testName | section | taskName | taskData | expStartDate | expEndDate | expId | expTask
@@ -52,135 +52,148 @@ describe('when using the ganttDb', function () {
${'should handle duration (weeks) instead of fixed date to determine end date'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2w'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 15)} | ${'id1'} | ${'test1'}
${'should handle fixed dates without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'task1'} | ${'test1'}
${'should handle duration instead of a fixed date to determine end date without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,4d'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 5)} | ${'task1'} | ${'test1'}
-`('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.addSection(section)
- ganttDb.addTask(taskName, taskData)
- const tasks = ganttDb.getTasks()
- expect(tasks[0].startTime).toEqual(expStartDate)
- expect(tasks[0].endTime).toEqual(expEndDate)
- expect(tasks[0].id).toEqual(expId)
- expect(tasks[0].task).toEqual(expTask)
-})
+ `('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.addSection(section);
+ ganttDb.addTask(taskName, taskData);
+ const tasks = ganttDb.getTasks();
+ expect(tasks[0].startTime).toEqual(expStartDate);
+ expect(tasks[0].endTime).toEqual(expEndDate);
+ expect(tasks[0].id).toEqual(expId);
+ expect(tasks[0].task).toEqual(expTask);
+ });
it.each`
- section | taskName1 | taskName2 | taskData1 | taskData2 | expStartDate2 | expEndDate2 | expId2 | expTask2
- ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'id2'} | ${'test2'}
- ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id3,1d'} | ${new Date((new Date()).setHours(0, 0, 0, 0))} | ${undefined} | ${'id2'} | ${'test2'}
- ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'task1'} | ${'test2'}
- ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2013-01-26'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 26)} | ${'task1'} | ${'test2'}
- ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2d'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 17)} | ${'task1'} | ${'test2'}
-`('$testName', ({ section, taskName1, taskName2, taskData1, taskData2, expStartDate2, expEndDate2, expId2, expTask2 }) => {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.addSection(section)
- ganttDb.addTask(taskName1, taskData1)
- ganttDb.addTask(taskName2, taskData2)
- const tasks = ganttDb.getTasks()
- expect(tasks[1].startTime).toEqual(expStartDate2)
- if (!expEndDate2 === undefined) {
- expect(tasks[1].endTime).toEqual(expEndDate2)
- }
- expect(tasks[1].id).toEqual(expId2)
- expect(tasks[1].task).toEqual(expTask2)
-})
+ section | taskName1 | taskName2 | taskData1 | taskData2 | expStartDate2 | expEndDate2 | expId2 | expTask2
+ ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'id2'} | ${'test2'}
+ ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id3,1d'} | ${new Date(new Date().setHours(0, 0, 0, 0))} | ${undefined} | ${'id2'} | ${'test2'}
+ ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'task1'} | ${'test2'}
+ ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2013-01-26'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 26)} | ${'task1'} | ${'test2'}
+ ${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2d'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 17)} | ${'task1'} | ${'test2'}
+ `(
+ '$testName',
+ ({
+ section,
+ taskName1,
+ taskName2,
+ taskData1,
+ taskData2,
+ expStartDate2,
+ expEndDate2,
+ expId2,
+ expTask2
+ }) => {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.addSection(section);
+ ganttDb.addTask(taskName1, taskData1);
+ ganttDb.addTask(taskName2, taskData2);
+ const tasks = ganttDb.getTasks();
+ expect(tasks[1].startTime).toEqual(expStartDate2);
+ if (!expEndDate2 === undefined) {
+ expect(tasks[1].endTime).toEqual(expEndDate2);
+ }
+ expect(tasks[1].id).toEqual(expId2);
+ expect(tasks[1].task).toEqual(expTask2);
+ }
+ );
- it('should handle relative start date based on id regardless of sections', function () {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.addSection('testa1')
- ganttDb.addTask('test1', 'id1,2013-01-01,2w')
- ganttDb.addTask('test2', 'id2,after id3,1d')
- ganttDb.addSection('testa2')
- ganttDb.addTask('test3', 'id3,after id1,2d')
+ it('should handle relative start date based on id regardless of sections', function() {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.addSection('testa1');
+ ganttDb.addTask('test1', 'id1,2013-01-01,2w');
+ ganttDb.addTask('test2', 'id2,after id3,1d');
+ ganttDb.addSection('testa2');
+ ganttDb.addTask('test3', 'id3,after id1,2d');
- const tasks = ganttDb.getTasks()
+ const tasks = ganttDb.getTasks();
- expect(tasks[1].startTime).toEqual(new Date(2013, 0, 17))
- expect(tasks[1].endTime).toEqual(new Date(2013, 0, 18))
- expect(tasks[1].id).toEqual('id2')
- expect(tasks[1].task).toEqual('test2')
+ expect(tasks[1].startTime).toEqual(new Date(2013, 0, 17));
+ expect(tasks[1].endTime).toEqual(new Date(2013, 0, 18));
+ expect(tasks[1].id).toEqual('id2');
+ expect(tasks[1].task).toEqual('test2');
- expect(tasks[2].id).toEqual('id3')
- expect(tasks[2].task).toEqual('test3')
- expect(tasks[2].startTime).toEqual(new Date(2013, 0, 15))
- expect(tasks[2].endTime).toEqual(new Date(2013, 0, 17))
- })
- it('should ignore weekends', function () {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.setExcludes('weekends 2019-02-06,friday')
- ganttDb.addSection('weekends skip test')
- ganttDb.addTask('test1', 'id1,2019-02-01,1d')
- ganttDb.addTask('test2', 'id2,after id1,2d')
- ganttDb.addTask('test3', 'id3,after id2,7d')
- ganttDb.addTask('test4', 'id4,2019-02-01,2019-02-20') // Fixed endTime
- ganttDb.addTask('test5', 'id5,after id4,1d')
- ganttDb.addSection('full ending taks on last day')
- ganttDb.addTask('test6', 'id6,2019-02-13,2d')
- ganttDb.addTask('test7', 'id7,after id6,1d')
+ expect(tasks[2].id).toEqual('id3');
+ expect(tasks[2].task).toEqual('test3');
+ expect(tasks[2].startTime).toEqual(new Date(2013, 0, 15));
+ expect(tasks[2].endTime).toEqual(new Date(2013, 0, 17));
+ });
+ it('should ignore weekends', function() {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.setExcludes('weekends 2019-02-06,friday');
+ ganttDb.addSection('weekends skip test');
+ ganttDb.addTask('test1', 'id1,2019-02-01,1d');
+ ganttDb.addTask('test2', 'id2,after id1,2d');
+ ganttDb.addTask('test3', 'id3,after id2,7d');
+ ganttDb.addTask('test4', 'id4,2019-02-01,2019-02-20'); // Fixed endTime
+ ganttDb.addTask('test5', 'id5,after id4,1d');
+ ganttDb.addSection('full ending taks on last day');
+ ganttDb.addTask('test6', 'id6,2019-02-13,2d');
+ ganttDb.addTask('test7', 'id7,after id6,1d');
- const tasks = ganttDb.getTasks()
+ const tasks = ganttDb.getTasks();
- expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
- expect(tasks[0].endTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate())
- expect(tasks[0].renderEndTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate())
- expect(tasks[0].id).toEqual('id1')
- expect(tasks[0].task).toEqual('test1')
+ expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate());
+ expect(tasks[0].endTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate());
+ expect(tasks[0].renderEndTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate());
+ expect(tasks[0].id).toEqual('id1');
+ expect(tasks[0].task).toEqual('test1');
- expect(tasks[1].startTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate())
- expect(tasks[1].endTime).toEqual(moment('2019-02-07', 'YYYY-MM-DD').toDate())
- expect(tasks[1].renderEndTime).toEqual(moment('2019-02-06', 'YYYY-MM-DD').toDate())
- expect(tasks[1].id).toEqual('id2')
- expect(tasks[1].task).toEqual('test2')
+ expect(tasks[1].startTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate());
+ expect(tasks[1].endTime).toEqual(moment('2019-02-07', 'YYYY-MM-DD').toDate());
+ expect(tasks[1].renderEndTime).toEqual(moment('2019-02-06', 'YYYY-MM-DD').toDate());
+ expect(tasks[1].id).toEqual('id2');
+ expect(tasks[1].task).toEqual('test2');
- expect(tasks[2].startTime).toEqual(moment('2019-02-07', 'YYYY-MM-DD').toDate())
- expect(tasks[2].endTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate())
- expect(tasks[2].renderEndTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate())
- expect(tasks[2].id).toEqual('id3')
- expect(tasks[2].task).toEqual('test3')
+ expect(tasks[2].startTime).toEqual(moment('2019-02-07', 'YYYY-MM-DD').toDate());
+ expect(tasks[2].endTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate());
+ expect(tasks[2].renderEndTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate());
+ expect(tasks[2].id).toEqual('id3');
+ expect(tasks[2].task).toEqual('test3');
- expect(tasks[3].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
- expect(tasks[3].endTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate())
- expect(tasks[3].renderEndTime).toBeNull() // Fixed end
- expect(tasks[3].id).toEqual('id4')
- expect(tasks[3].task).toEqual('test4')
+ expect(tasks[3].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate());
+ expect(tasks[3].endTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate());
+ expect(tasks[3].renderEndTime).toBeNull(); // Fixed end
+ expect(tasks[3].id).toEqual('id4');
+ expect(tasks[3].task).toEqual('test4');
- expect(tasks[4].startTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate())
- expect(tasks[4].endTime).toEqual(moment('2019-02-21', 'YYYY-MM-DD').toDate())
- expect(tasks[4].renderEndTime).toEqual(moment('2019-02-21', 'YYYY-MM-DD').toDate())
- expect(tasks[4].id).toEqual('id5')
- expect(tasks[4].task).toEqual('test5')
+ expect(tasks[4].startTime).toEqual(moment('2019-02-20', 'YYYY-MM-DD').toDate());
+ expect(tasks[4].endTime).toEqual(moment('2019-02-21', 'YYYY-MM-DD').toDate());
+ expect(tasks[4].renderEndTime).toEqual(moment('2019-02-21', 'YYYY-MM-DD').toDate());
+ expect(tasks[4].id).toEqual('id5');
+ expect(tasks[4].task).toEqual('test5');
- expect(tasks[5].startTime).toEqual(moment('2019-02-13', 'YYYY-MM-DD').toDate())
- expect(tasks[5].endTime).toEqual(moment('2019-02-18', 'YYYY-MM-DD').toDate())
- expect(tasks[5].renderEndTime).toEqual(moment('2019-02-15', 'YYYY-MM-DD').toDate())
- expect(tasks[5].id).toEqual('id6')
- expect(tasks[5].task).toEqual('test6')
+ expect(tasks[5].startTime).toEqual(moment('2019-02-13', 'YYYY-MM-DD').toDate());
+ expect(tasks[5].endTime).toEqual(moment('2019-02-18', 'YYYY-MM-DD').toDate());
+ expect(tasks[5].renderEndTime).toEqual(moment('2019-02-15', 'YYYY-MM-DD').toDate());
+ expect(tasks[5].id).toEqual('id6');
+ expect(tasks[5].task).toEqual('test6');
- expect(tasks[6].startTime).toEqual(moment('2019-02-18', 'YYYY-MM-DD').toDate())
- expect(tasks[6].endTime).toEqual(moment('2019-02-19', 'YYYY-MM-DD').toDate())
- expect(tasks[6].id).toEqual('id7')
- expect(tasks[6].task).toEqual('test7')
- })
+ expect(tasks[6].startTime).toEqual(moment('2019-02-18', 'YYYY-MM-DD').toDate());
+ expect(tasks[6].endTime).toEqual(moment('2019-02-19', 'YYYY-MM-DD').toDate());
+ expect(tasks[6].id).toEqual('id7');
+ expect(tasks[6].task).toEqual('test7');
+ });
- describe('when setting inclusive end dates', function () {
- beforeEach(function () {
- ganttDb.setDateFormat('YYYY-MM-DD')
- ganttDb.enableInclusiveEndDates()
- ganttDb.addTask('test1', 'id1,2019-02-01,1d')
- ganttDb.addTask('test2', 'id2,2019-02-01,2019-02-03')
- })
- it('should automatically add one day to all end dates', function () {
- const tasks = ganttDb.getTasks()
- expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
- expect(tasks[0].endTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate())
- expect(tasks[0].id).toEqual('id1')
- expect(tasks[0].task).toEqual('test1')
+ describe('when setting inclusive end dates', function() {
+ beforeEach(function() {
+ ganttDb.setDateFormat('YYYY-MM-DD');
+ ganttDb.enableInclusiveEndDates();
+ ganttDb.addTask('test1', 'id1,2019-02-01,1d');
+ ganttDb.addTask('test2', 'id2,2019-02-01,2019-02-03');
+ });
+ it('should automatically add one day to all end dates', function() {
+ const tasks = ganttDb.getTasks();
+ expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate());
+ expect(tasks[0].endTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate());
+ expect(tasks[0].id).toEqual('id1');
+ expect(tasks[0].task).toEqual('test1');
- expect(tasks[1].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
- expect(tasks[1].endTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate())
- expect(tasks[1].renderEndTime).toBeNull() // Fixed end
- expect(tasks[1].manualEndTime).toBeTruthy()
- expect(tasks[1].id).toEqual('id2')
- expect(tasks[1].task).toEqual('test2')
- })
- })
-})
+ expect(tasks[1].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate());
+ expect(tasks[1].endTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate());
+ expect(tasks[1].renderEndTime).toBeNull(); // Fixed end
+ expect(tasks[1].manualEndTime).toBeTruthy();
+ expect(tasks[1].id).toEqual('id2');
+ expect(tasks[1].task).toEqual('test2');
+ });
+ });
+});
diff --git a/src/diagrams/gantt/ganttRenderer.js b/src/diagrams/gantt/ganttRenderer.js
index c9349f483..beee82e17 100644
--- a/src/diagrams/gantt/ganttRenderer.js
+++ b/src/diagrams/gantt/ganttRenderer.js
@@ -1,9 +1,9 @@
-import * as d3 from 'd3'
+import * as d3 from 'd3';
-import { parser } from './parser/gantt'
-import ganttDb from './ganttDb'
+import { parser } from './parser/gantt';
+import ganttDb from './ganttDb';
-parser.yy = ganttDb
+parser.yy = ganttDb;
const conf = {
titleTopMargin: 25,
@@ -15,287 +15,316 @@ const conf = {
gridLineStartPadding: 35,
fontSize: 11,
fontFamily: '"Open-Sans", "sans-serif"'
-}
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+};
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
- keys.forEach(function (key) {
- conf[key] = cnf[key]
- })
-}
-let w
-export const draw = function (text, id) {
- parser.yy.clear()
- parser.parse(text)
+ keys.forEach(function(key) {
+ conf[key] = cnf[key];
+ });
+};
+let w;
+export const draw = function(text, id) {
+ parser.yy.clear();
+ parser.parse(text);
- const elem = document.getElementById(id)
- w = elem.parentElement.offsetWidth
+ const elem = document.getElementById(id);
+ w = elem.parentElement.offsetWidth;
if (typeof w === 'undefined') {
- w = 1200
+ w = 1200;
}
if (typeof conf.useWidth !== 'undefined') {
- w = conf.useWidth
+ w = conf.useWidth;
}
- const taskArray = parser.yy.getTasks()
+ const taskArray = parser.yy.getTasks();
// Set height based on number of tasks
- const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding
+ const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding;
- elem.setAttribute('height', '100%')
+ elem.setAttribute('height', '100%');
// Set viewBox
- elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
- const svg = d3.select(`[id="${id}"]`)
+ elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
+ const svg = d3.select(`[id="${id}"]`);
// Set timescale
- const timeScale = d3.scaleTime()
- .domain([d3.min(taskArray, function (d) {
- return d.startTime
- }),
- d3.max(taskArray, function (d) {
- return d.endTime
- })])
- .rangeRound([0, w - conf.leftPadding - conf.rightPadding])
+ const timeScale = d3
+ .scaleTime()
+ .domain([
+ d3.min(taskArray, function(d) {
+ return d.startTime;
+ }),
+ d3.max(taskArray, function(d) {
+ return d.endTime;
+ })
+ ])
+ .rangeRound([0, w - conf.leftPadding - conf.rightPadding]);
- let categories = []
+ let categories = [];
for (let i = 0; i < taskArray.length; i++) {
- categories.push(taskArray[i].type)
+ categories.push(taskArray[i].type);
}
- const catsUnfiltered = categories // for vert labels
+ const catsUnfiltered = categories; // for vert labels
- categories = checkUnique(categories)
+ categories = checkUnique(categories);
- makeGant(taskArray, w, h)
+ makeGant(taskArray, w, h);
if (typeof conf.useWidth !== 'undefined') {
- elem.setAttribute('width', w)
+ elem.setAttribute('width', w);
}
- svg.append('text')
+ svg
+ .append('text')
.text(parser.yy.getTitle())
.attr('x', w / 2)
.attr('y', conf.titleTopMargin)
- .attr('class', 'titleText')
+ .attr('class', 'titleText');
- function makeGant (tasks, pageWidth, pageHeight) {
- const barHeight = conf.barHeight
- const gap = barHeight + conf.barGap
- const topPadding = conf.topPadding
- const leftPadding = conf.leftPadding
+ function makeGant(tasks, pageWidth, pageHeight) {
+ const barHeight = conf.barHeight;
+ const gap = barHeight + conf.barGap;
+ const topPadding = conf.topPadding;
+ const leftPadding = conf.leftPadding;
- const colorScale = d3.scaleLinear()
+ const colorScale = d3
+ .scaleLinear()
.domain([0, categories.length])
.range(['#00B9FA', '#F95002'])
- .interpolate(d3.interpolateHcl)
+ .interpolate(d3.interpolateHcl);
- makeGrid(leftPadding, topPadding, pageWidth, pageHeight)
- drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight)
- vertLabels(gap, topPadding, leftPadding, barHeight, colorScale)
- drawToday(leftPadding, topPadding, pageWidth, pageHeight)
+ makeGrid(leftPadding, topPadding, pageWidth, pageHeight);
+ drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight);
+ vertLabels(gap, topPadding, leftPadding, barHeight, colorScale);
+ drawToday(leftPadding, topPadding, pageWidth, pageHeight);
}
- function drawRects (theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
+ function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
// Draw background rects covering the entire width of the graph, these form the section rows.
- svg.append('g')
+ svg
+ .append('g')
.selectAll('rect')
.data(theArray)
.enter()
.append('rect')
.attr('x', 0)
- .attr('y', function (d, i) {
- return i * theGap + theTopPad - 2
+ .attr('y', function(d, i) {
+ return i * theGap + theTopPad - 2;
})
- .attr('width', function () {
- return w - conf.rightPadding / 2
+ .attr('width', function() {
+ return w - conf.rightPadding / 2;
})
.attr('height', theGap)
- .attr('class', function (d) {
+ .attr('class', function(d) {
for (let i = 0; i < categories.length; i++) {
if (d.type === categories[i]) {
- return 'section section' + (i % conf.numberSectionStyles)
+ return 'section section' + (i % conf.numberSectionStyles);
}
}
- return 'section section0'
- })
+ return 'section section0';
+ });
// Draw the rects representing the tasks
- const rectangles = svg.append('g')
+ const rectangles = svg
+ .append('g')
.selectAll('rect')
.data(theArray)
- .enter()
+ .enter();
- rectangles.append('rect')
- .attr('id', function (d) { return d.id })
+ rectangles
+ .append('rect')
+ .attr('id', function(d) {
+ return d.id;
+ })
.attr('rx', 3)
.attr('ry', 3)
- .attr('x', function (d) {
+ .attr('x', function(d) {
if (d.milestone) {
- return timeScale(d.startTime) + theSidePad + (0.5 * (timeScale(d.endTime) - timeScale(d.startTime))) - (0.5 * theBarHeight)
+ return (
+ timeScale(d.startTime) +
+ theSidePad +
+ 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) -
+ 0.5 * theBarHeight
+ );
}
- return timeScale(d.startTime) + theSidePad
+ return timeScale(d.startTime) + theSidePad;
})
- .attr('y', function (d, i) {
- return i * theGap + theTopPad
+ .attr('y', function(d, i) {
+ return i * theGap + theTopPad;
})
- .attr('width', function (d) {
+ .attr('width', function(d) {
if (d.milestone) {
- return theBarHeight
+ return theBarHeight;
}
- return (timeScale(d.renderEndTime || d.endTime) - timeScale(d.startTime))
+ return timeScale(d.renderEndTime || d.endTime) - timeScale(d.startTime);
})
.attr('height', theBarHeight)
- .attr('transform-origin', function (d, i) {
- return (timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))).toString() + 'px ' + (i * theGap + theTopPad + 0.5 * theBarHeight).toString() + 'px'
+ .attr('transform-origin', function(d, i) {
+ return (
+ (
+ timeScale(d.startTime) +
+ theSidePad +
+ 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))
+ ).toString() +
+ 'px ' +
+ (i * theGap + theTopPad + 0.5 * theBarHeight).toString() +
+ 'px'
+ );
})
- .attr('class', function (d) {
- const res = 'task'
+ .attr('class', function(d) {
+ const res = 'task';
- let classStr = ''
+ let classStr = '';
if (d.classes.length > 0) {
- classStr = d.classes.join(' ')
+ classStr = d.classes.join(' ');
}
- let secNum = 0
+ let secNum = 0;
for (let i = 0; i < categories.length; i++) {
if (d.type === categories[i]) {
- secNum = (i % conf.numberSectionStyles)
+ secNum = i % conf.numberSectionStyles;
}
}
- let taskClass = ''
+ let taskClass = '';
if (d.active) {
if (d.crit) {
- taskClass += ' activeCrit'
+ taskClass += ' activeCrit';
} else {
- taskClass = ' active'
+ taskClass = ' active';
}
} else if (d.done) {
if (d.crit) {
- taskClass = ' doneCrit'
+ taskClass = ' doneCrit';
} else {
- taskClass = ' done'
+ taskClass = ' done';
}
} else {
if (d.crit) {
- taskClass += ' crit'
+ taskClass += ' crit';
}
}
if (taskClass.length === 0) {
- taskClass = ' task'
+ taskClass = ' task';
}
if (d.milestone) {
- taskClass = ' milestone ' + taskClass
+ taskClass = ' milestone ' + taskClass;
}
- taskClass += secNum
+ taskClass += secNum;
- taskClass += ' ' + classStr
+ taskClass += ' ' + classStr;
- return res + taskClass
- })
+ return res + taskClass;
+ });
// Append task labels
- rectangles.append('text')
- .attr('id', function (d) { return d.id + '-text' })
- .text(function (d) {
- return d.task
+ rectangles
+ .append('text')
+ .attr('id', function(d) {
+ return d.id + '-text';
+ })
+ .text(function(d) {
+ return d.task;
})
.attr('font-size', conf.fontSize)
- .attr('x', function (d) {
- let startX = timeScale(d.startTime)
- let endX = timeScale(d.renderEndTime || d.endTime)
+ .attr('x', function(d) {
+ let startX = timeScale(d.startTime);
+ let endX = timeScale(d.renderEndTime || d.endTime);
if (d.milestone) {
- startX += (0.5 * (timeScale(d.endTime) - timeScale(d.startTime))) - (0.5 * theBarHeight)
+ startX += 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight;
}
if (d.milestone) {
- endX = startX + theBarHeight
+ endX = startX + theBarHeight;
}
- const textWidth = this.getBBox().width
+ const textWidth = this.getBBox().width;
// Check id text width > width of rectangle
- if (textWidth > (endX - startX)) {
+ if (textWidth > endX - startX) {
if (endX + textWidth + 1.5 * conf.leftPadding > w) {
- return startX + theSidePad - 5
+ return startX + theSidePad - 5;
} else {
- return endX + theSidePad + 5
+ return endX + theSidePad + 5;
}
} else {
- return (endX - startX) / 2 + startX + theSidePad
+ return (endX - startX) / 2 + startX + theSidePad;
}
})
- .attr('y', function (d, i) {
- return i * theGap + (conf.barHeight / 2) + (conf.fontSize / 2 - 2) + theTopPad
+ .attr('y', function(d, i) {
+ return i * theGap + conf.barHeight / 2 + (conf.fontSize / 2 - 2) + theTopPad;
})
.attr('text-height', theBarHeight)
- .attr('class', function (d) {
- const startX = timeScale(d.startTime)
- let endX = timeScale(d.endTime)
+ .attr('class', function(d) {
+ const startX = timeScale(d.startTime);
+ let endX = timeScale(d.endTime);
if (d.milestone) {
- endX = startX + theBarHeight
+ endX = startX + theBarHeight;
}
- const textWidth = this.getBBox().width
+ const textWidth = this.getBBox().width;
- let classStr = ''
+ let classStr = '';
if (d.classes.length > 0) {
- classStr = d.classes.join(' ')
+ classStr = d.classes.join(' ');
}
- let secNum = 0
+ let secNum = 0;
for (let i = 0; i < categories.length; i++) {
if (d.type === categories[i]) {
- secNum = (i % conf.numberSectionStyles)
+ secNum = i % conf.numberSectionStyles;
}
}
- let taskType = ''
+ let taskType = '';
if (d.active) {
if (d.crit) {
- taskType = 'activeCritText' + secNum
+ taskType = 'activeCritText' + secNum;
} else {
- taskType = 'activeText' + secNum
+ taskType = 'activeText' + secNum;
}
}
if (d.done) {
if (d.crit) {
- taskType = taskType + ' doneCritText' + secNum
+ taskType = taskType + ' doneCritText' + secNum;
} else {
- taskType = taskType + ' doneText' + secNum
+ taskType = taskType + ' doneText' + secNum;
}
} else {
if (d.crit) {
- taskType = taskType + ' critText' + secNum
+ taskType = taskType + ' critText' + secNum;
}
}
if (d.milestone) {
- taskType += ' milestoneText'
+ taskType += ' milestoneText';
}
// Check id text width > width of rectangle
- if (textWidth > (endX - startX)) {
+ if (textWidth > endX - startX) {
if (endX + textWidth + 1.5 * conf.leftPadding > w) {
- return classStr + ' taskTextOutsideLeft taskTextOutside' + secNum + ' ' + taskType
+ return classStr + ' taskTextOutsideLeft taskTextOutside' + secNum + ' ' + taskType;
} else {
- return classStr + ' taskTextOutsideRight taskTextOutside' + secNum + ' ' + taskType
+ return classStr + ' taskTextOutsideRight taskTextOutside' + secNum + ' ' + taskType;
}
} else {
- return classStr + ' taskText taskText' + secNum + ' ' + taskType
+ return classStr + ' taskText taskText' + secNum + ' ' + taskType;
}
- })
+ });
}
- function makeGrid (theSidePad, theTopPad, w, h) {
- let xAxis = d3.axisBottom(timeScale)
+ function makeGrid(theSidePad, theTopPad, w, h) {
+ let xAxis = d3
+ .axisBottom(timeScale)
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
- .tickFormat(d3.timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'))
+ .tickFormat(d3.timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
- svg.append('g')
+ svg
+ .append('g')
.attr('class', 'grid')
.attr('transform', 'translate(' + theSidePad + ', ' + (h - 50) + ')')
.call(xAxis)
@@ -304,90 +333,92 @@ export const draw = function (text, id) {
.attr('fill', '#000')
.attr('stroke', 'none')
.attr('font-size', 10)
- .attr('dy', '1em')
+ .attr('dy', '1em');
}
- function vertLabels (theGap, theTopPad) {
- const numOccurances = []
- let prevGap = 0
+ function vertLabels(theGap, theTopPad) {
+ const numOccurances = [];
+ let prevGap = 0;
for (let i = 0; i < categories.length; i++) {
- numOccurances[i] = [categories[i], getCount(categories[i], catsUnfiltered)]
+ numOccurances[i] = [categories[i], getCount(categories[i], catsUnfiltered)];
}
- svg.append('g') // without doing this, impossible to put grid lines behind text
+ svg
+ .append('g') // without doing this, impossible to put grid lines behind text
.selectAll('text')
.data(numOccurances)
.enter()
.append('text')
- .text(function (d) {
- return d[0]
+ .text(function(d) {
+ return d[0];
})
.attr('x', 10)
- .attr('y', function (d, i) {
+ .attr('y', function(d, i) {
if (i > 0) {
for (let j = 0; j < i; j++) {
- prevGap += numOccurances[i - 1][1]
- return d[1] * theGap / 2 + prevGap * theGap + theTopPad
+ prevGap += numOccurances[i - 1][1];
+ return (d[1] * theGap) / 2 + prevGap * theGap + theTopPad;
}
} else {
- return d[1] * theGap / 2 + theTopPad
+ return (d[1] * theGap) / 2 + theTopPad;
}
})
- .attr('class', function (d) {
+ .attr('class', function(d) {
for (let i = 0; i < categories.length; i++) {
if (d[0] === categories[i]) {
- return 'sectionTitle sectionTitle' + (i % conf.numberSectionStyles)
+ return 'sectionTitle sectionTitle' + (i % conf.numberSectionStyles);
}
}
- return 'sectionTitle'
- })
+ return 'sectionTitle';
+ });
}
- function drawToday (theSidePad, theTopPad, w, h) {
- const todayG = svg.append('g')
- .attr('class', 'today')
+ function drawToday(theSidePad, theTopPad, w, h) {
+ const todayG = svg.append('g').attr('class', 'today');
- const today = new Date()
+ const today = new Date();
- todayG.append('line')
+ todayG
+ .append('line')
.attr('x1', timeScale(today) + theSidePad)
.attr('x2', timeScale(today) + theSidePad)
.attr('y1', conf.titleTopMargin)
.attr('y2', h - conf.titleTopMargin)
- .attr('class', 'today')
+ .attr('class', 'today');
}
// from this stackexchange question: http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript
- function checkUnique (arr) {
- const hash = {}
- const result = []
+ function checkUnique(arr) {
+ const hash = {};
+ const result = [];
for (let i = 0, l = arr.length; i < l; ++i) {
- if (!hash.hasOwnProperty(arr[i])) { // it works with objects! in FF, at least
- hash[arr[i]] = true
- result.push(arr[i])
+ if (!hash.hasOwnProperty(arr[i])) {
+ // it works with objects! in FF, at least
+ hash[arr[i]] = true;
+ result.push(arr[i]);
}
}
- return result
+ return result;
}
// from this stackexchange question: http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array
- function getCounts (arr) {
- let i = arr.length // const to loop over
- const obj = {} // obj to store results
+ function getCounts(arr) {
+ let i = arr.length; // const to loop over
+ const obj = {}; // obj to store results
while (i) {
- obj[arr[--i]] = (obj[arr[i]] || 0) + 1 // count occurrences
+ obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
}
- return obj
+ return obj;
}
// get specific from everything
- function getCount (word, arr) {
- return getCounts(arr)[word] || 0
+ function getCount(word, arr) {
+ return getCounts(arr)[word] || 0;
}
-}
+};
export default {
setConf,
draw
-}
+};
diff --git a/src/diagrams/gantt/parser/gantt.spec.js b/src/diagrams/gantt/parser/gantt.spec.js
index 7a28aeb6c..51d2c0884 100644
--- a/src/diagrams/gantt/parser/gantt.spec.js
+++ b/src/diagrams/gantt/parser/gantt.spec.js
@@ -1,50 +1,52 @@
/* eslint-env jasmine */
/* eslint-disable no-eval */
-import { parser } from './gantt'
-import ganttDb from '../ganttDb'
+import { parser } from './gantt';
+import ganttDb from '../ganttDb';
-const parserFnConstructor = (str) => {
+const parserFnConstructor = str => {
return () => {
- parser.parse(str)
- }
-}
+ parser.parse(str);
+ };
+};
-describe('when parsing a gantt diagram it', function () {
- beforeEach(function () {
- parser.yy = ganttDb
- parser.yy.clear()
- })
+describe('when parsing a gantt diagram it', function() {
+ beforeEach(function() {
+ parser.yy = ganttDb;
+ parser.yy.clear();
+ });
- it('should handle a dateFormat definition', function () {
- const str = 'gantt\ndateFormat yyyy-mm-dd'
+ it('should handle a dateFormat definition', function() {
+ const str = 'gantt\ndateFormat yyyy-mm-dd';
- expect(parserFnConstructor(str)).not.toThrow()
- })
+ expect(parserFnConstructor(str)).not.toThrow();
+ });
- it('should handle a inclusive end date definition', function () {
- const str = 'gantt\ndateFormat yyyy-mm-dd\ninclusiveEndDates'
+ it('should handle a inclusive end date definition', function() {
+ const str = 'gantt\ndateFormat yyyy-mm-dd\ninclusiveEndDates';
- expect(parserFnConstructor(str)).not.toThrow()
- })
- it('should handle a title definition', function () {
- const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid'
+ expect(parserFnConstructor(str)).not.toThrow();
+ });
+ it('should handle a title definition', function() {
+ const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid';
- expect(parserFnConstructor(str)).not.toThrow()
- })
- it('should handle an excludes definition', function () {
- const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid\nexcludes weekdays 2019-02-01'
+ expect(parserFnConstructor(str)).not.toThrow();
+ });
+ it('should handle an excludes definition', function() {
+ const str =
+ 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid\nexcludes weekdays 2019-02-01';
- expect(parserFnConstructor(str)).not.toThrow()
- })
- it('should handle a section definition', function () {
- const str = 'gantt\n' +
+ expect(parserFnConstructor(str)).not.toThrow();
+ });
+ it('should handle a section definition', function() {
+ const str =
+ 'gantt\n' +
'dateFormat yyyy-mm-dd\n' +
'title Adding gantt diagram functionality to mermaid\n' +
'excludes weekdays 2019-02-01\n' +
- 'section Documentation'
+ 'section Documentation';
- expect(parserFnConstructor(str)).not.toThrow()
- })
+ expect(parserFnConstructor(str)).not.toThrow();
+ });
/**
* Beslutsflöde inligt nedan. Obs bla bla bla
* ```
@@ -56,22 +58,23 @@ describe('when parsing a gantt diagram it', function () {
```
* params bapa - a unique bapap
*/
- it('should handle a task definition', function () {
- const str = 'gantt\n' +
+ it('should handle a task definition', function() {
+ const str =
+ 'gantt\n' +
'dateFormat YYYY-MM-DD\n' +
'title Adding gantt diagram functionality to mermaid\n' +
'section Documentation\n' +
- 'Design jison grammar:des1, 2014-01-01, 2014-01-04'
+ 'Design jison grammar:des1, 2014-01-01, 2014-01-04';
- expect(parserFnConstructor(str)).not.toThrow()
+ expect(parserFnConstructor(str)).not.toThrow();
- const tasks = parser.yy.getTasks()
+ const tasks = parser.yy.getTasks();
- expect(tasks[0].startTime).toEqual(new Date(2014, 0, 1))
- expect(tasks[0].endTime).toEqual(new Date(2014, 0, 4))
- expect(tasks[0].id).toEqual('des1')
- expect(tasks[0].task).toEqual('Design jison grammar')
- })
+ expect(tasks[0].startTime).toEqual(new Date(2014, 0, 1));
+ expect(tasks[0].endTime).toEqual(new Date(2014, 0, 4));
+ expect(tasks[0].id).toEqual('des1');
+ expect(tasks[0].task).toEqual('Design jison grammar');
+ });
it.each`
tags | milestone | done | crit | active
${'milestone'} | ${true} | ${false} | ${false} | ${false}
@@ -79,25 +82,28 @@ describe('when parsing a gantt diagram it', function () {
${'crit'} | ${false} | ${false} | ${true} | ${false}
${'active'} | ${false} | ${false} | ${false} | ${true}
${'crit,milestone,done'} | ${true} | ${true} | ${true} | ${false}
- `('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
- const str = 'gantt\n' +
- 'dateFormat YYYY-MM-DD\n' +
- 'title Adding gantt diagram functionality to mermaid\n' +
- 'section Documentation\n' +
- 'test task:' + tags + ', 2014-01-01, 2014-01-04'
+ `('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
+ const str =
+ 'gantt\n' +
+ 'dateFormat YYYY-MM-DD\n' +
+ 'title Adding gantt diagram functionality to mermaid\n' +
+ 'section Documentation\n' +
+ 'test task:' +
+ tags +
+ ', 2014-01-01, 2014-01-04';
- const allowedTags = ['active', 'done', 'crit', 'milestone']
+ const allowedTags = ['active', 'done', 'crit', 'milestone'];
- expect(parserFnConstructor(str)).not.toThrow()
+ expect(parserFnConstructor(str)).not.toThrow();
- const tasks = parser.yy.getTasks()
+ const tasks = parser.yy.getTasks();
- allowedTags.forEach(function (t) {
- if (eval(t)) {
- expect(tasks[0][t]).toBeTruthy()
- } else {
- expect(tasks[0][t]).toBeFalsy()
- }
- })
-})
-})
+ allowedTags.forEach(function(t) {
+ if (eval(t)) {
+ expect(tasks[0][t]).toBeTruthy();
+ } else {
+ expect(tasks[0][t]).toBeFalsy();
+ }
+ });
+ });
+});
diff --git a/src/diagrams/git/gitGraphAst.js b/src/diagrams/git/gitGraphAst.js
index f7338c5ed..85e8f7905 100644
--- a/src/diagrams/git/gitGraphAst.js
+++ b/src/diagrams/git/gitGraphAst.js
@@ -1,98 +1,100 @@
-import _ from 'lodash'
+import _ from 'lodash';
-import { logger } from '../../logger'
+import { logger } from '../../logger';
-let commits = {}
-let head = null
-let branches = { 'master': head }
-let curBranch = 'master'
-let direction = 'LR'
-let seq = 0
+let commits = {};
+let head = null;
+let branches = { master: head };
+let curBranch = 'master';
+let direction = 'LR';
+let seq = 0;
-function getRandomInt (min, max) {
- return Math.floor(Math.random() * (max - min)) + min
+function getRandomInt(min, max) {
+ return Math.floor(Math.random() * (max - min)) + min;
}
-function getId () {
- const pool = '0123456789abcdef'
- let id = ''
+function getId() {
+ const pool = '0123456789abcdef';
+ let id = '';
for (let i = 0; i < 7; i++) {
- id += pool[getRandomInt(0, 16)]
+ id += pool[getRandomInt(0, 16)];
}
- return id
+ return id;
}
-function isfastforwardable (currentCommit, otherCommit) {
- logger.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id)
+function isfastforwardable(currentCommit, otherCommit) {
+ logger.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id);
while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit) {
// only if other branch has more commits
- if (otherCommit.parent == null) break
+ if (otherCommit.parent == null) break;
if (Array.isArray(otherCommit.parent)) {
- logger.debug('In merge commit:', otherCommit.parent)
- return isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
+ logger.debug('In merge commit:', otherCommit.parent);
+ return (
+ isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
+ );
} else {
- otherCommit = commits[otherCommit.parent]
+ otherCommit = commits[otherCommit.parent];
}
}
- logger.debug(currentCommit.id, otherCommit.id)
- return currentCommit.id === otherCommit.id
+ logger.debug(currentCommit.id, otherCommit.id);
+ return currentCommit.id === otherCommit.id;
}
-function isReachableFrom (currentCommit, otherCommit) {
- const currentSeq = currentCommit.seq
- const otherSeq = otherCommit.seq
- if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit)
- return false
+function isReachableFrom(currentCommit, otherCommit) {
+ const currentSeq = currentCommit.seq;
+ const otherSeq = otherCommit.seq;
+ if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit);
+ return false;
}
-export const setDirection = function (dir) {
- direction = dir
-}
-let options = {}
-export const setOptions = function (rawOptString) {
- logger.debug('options str', rawOptString)
- rawOptString = rawOptString && rawOptString.trim()
- rawOptString = rawOptString || '{}'
+export const setDirection = function(dir) {
+ direction = dir;
+};
+let options = {};
+export const setOptions = function(rawOptString) {
+ logger.debug('options str', rawOptString);
+ rawOptString = rawOptString && rawOptString.trim();
+ rawOptString = rawOptString || '{}';
try {
- options = JSON.parse(rawOptString)
+ options = JSON.parse(rawOptString);
} catch (e) {
- logger.error('error while parsing gitGraph options', e.message)
+ logger.error('error while parsing gitGraph options', e.message);
}
-}
+};
-export const getOptions = function () {
- return options
-}
+export const getOptions = function() {
+ return options;
+};
-export const commit = function (msg) {
+export const commit = function(msg) {
const commit = {
id: getId(),
message: msg,
seq: seq++,
parent: head == null ? null : head.id
- }
- head = commit
- commits[commit.id] = commit
- branches[curBranch] = commit.id
- logger.debug('in pushCommit ' + commit.id)
-}
+ };
+ head = commit;
+ commits[commit.id] = commit;
+ branches[curBranch] = commit.id;
+ logger.debug('in pushCommit ' + commit.id);
+};
-export const branch = function (name) {
- branches[name] = head != null ? head.id : null
- logger.debug('in createBranch')
-}
+export const branch = function(name) {
+ branches[name] = head != null ? head.id : null;
+ logger.debug('in createBranch');
+};
-export const merge = function (otherBranch) {
- const currentCommit = commits[branches[curBranch]]
- const otherCommit = commits[branches[otherBranch]]
+export const merge = function(otherBranch) {
+ const currentCommit = commits[branches[curBranch]];
+ const otherCommit = commits[branches[otherBranch]];
if (isReachableFrom(currentCommit, otherCommit)) {
- logger.debug('Already merged')
- return
+ logger.debug('Already merged');
+ return;
}
if (isfastforwardable(currentCommit, otherCommit)) {
- branches[curBranch] = branches[otherBranch]
- head = commits[branches[curBranch]]
+ branches[curBranch] = branches[otherBranch];
+ head = commits[branches[curBranch]];
} else {
// create merge commit
const commit = {
@@ -100,113 +102,125 @@ export const merge = function (otherBranch) {
message: 'merged branch ' + otherBranch + ' into ' + curBranch,
seq: seq++,
parent: [head == null ? null : head.id, branches[otherBranch]]
- }
- head = commit
- commits[commit.id] = commit
- branches[curBranch] = commit.id
+ };
+ head = commit;
+ commits[commit.id] = commit;
+ branches[curBranch] = commit.id;
}
- logger.debug(branches)
- logger.debug('in mergeBranch')
-}
+ logger.debug(branches);
+ logger.debug('in mergeBranch');
+};
-export const checkout = function (branch) {
- logger.debug('in checkout')
- curBranch = branch
- const id = branches[curBranch]
- head = commits[id]
-}
+export const checkout = function(branch) {
+ logger.debug('in checkout');
+ curBranch = branch;
+ const id = branches[curBranch];
+ head = commits[id];
+};
-export const reset = function (commitRef) {
- logger.debug('in reset', commitRef)
- const ref = commitRef.split(':')[0]
- let parentCount = parseInt(commitRef.split(':')[1])
- let commit = ref === 'HEAD' ? head : commits[branches[ref]]
- logger.debug(commit, parentCount)
+export const reset = function(commitRef) {
+ logger.debug('in reset', commitRef);
+ const ref = commitRef.split(':')[0];
+ let parentCount = parseInt(commitRef.split(':')[1]);
+ let commit = ref === 'HEAD' ? head : commits[branches[ref]];
+ logger.debug(commit, parentCount);
while (parentCount > 0) {
- commit = commits[commit.parent]
- parentCount--
+ commit = commits[commit.parent];
+ parentCount--;
if (!commit) {
- const err = 'Critical error - unique parent commit not found during reset'
- logger.error(err)
- throw err
+ const err = 'Critical error - unique parent commit not found during reset';
+ logger.error(err);
+ throw err;
}
}
- head = commit
- branches[curBranch] = commit.id
-}
+ head = commit;
+ branches[curBranch] = commit.id;
+};
-function upsert (arr, key, newval) {
- const index = arr.indexOf(key)
+function upsert(arr, key, newval) {
+ const index = arr.indexOf(key);
if (index === -1) {
- arr.push(newval)
+ arr.push(newval);
} else {
- arr.splice(index, 1, newval)
+ arr.splice(index, 1, newval);
}
}
-function prettyPrintCommitHistory (commitArr) {
- const commit = _.maxBy(commitArr, 'seq')
- let line = ''
- commitArr.forEach(function (c) {
+function prettyPrintCommitHistory(commitArr) {
+ const commit = _.maxBy(commitArr, 'seq');
+ let line = '';
+ commitArr.forEach(function(c) {
if (c === commit) {
- line += '\t*'
+ line += '\t*';
} else {
- line += '\t|'
+ line += '\t|';
}
- })
- const label = [line, commit.id, commit.seq]
+ });
+ const label = [line, commit.id, commit.seq];
for (let branch in branches) {
- if (branches[branch] === commit.id) label.push(branch)
+ if (branches[branch] === commit.id) label.push(branch);
}
- logger.debug(label.join(' '))
+ logger.debug(label.join(' '));
if (Array.isArray(commit.parent)) {
- const newCommit = commits[commit.parent[0]]
- upsert(commitArr, commit, newCommit)
- commitArr.push(commits[commit.parent[1]])
+ const newCommit = commits[commit.parent[0]];
+ upsert(commitArr, commit, newCommit);
+ commitArr.push(commits[commit.parent[1]]);
} else if (commit.parent == null) {
- return
+ return;
} else {
- const nextCommit = commits[commit.parent]
- upsert(commitArr, commit, nextCommit)
+ const nextCommit = commits[commit.parent];
+ upsert(commitArr, commit, nextCommit);
}
- commitArr = _.uniqBy(commitArr, 'id')
- prettyPrintCommitHistory(commitArr)
+ commitArr = _.uniqBy(commitArr, 'id');
+ prettyPrintCommitHistory(commitArr);
}
-export const prettyPrint = function () {
- logger.debug(commits)
- const node = getCommitsArray()[0]
- prettyPrintCommitHistory([node])
-}
+export const prettyPrint = function() {
+ logger.debug(commits);
+ const node = getCommitsArray()[0];
+ prettyPrintCommitHistory([node]);
+};
-export const clear = function () {
- commits = {}
- head = null
- branches = { 'master': head }
- curBranch = 'master'
- seq = 0
-}
+export const clear = function() {
+ commits = {};
+ head = null;
+ branches = { master: head };
+ curBranch = 'master';
+ seq = 0;
+};
-export const getBranchesAsObjArray = function () {
- const branchArr = []
+export const getBranchesAsObjArray = function() {
+ const branchArr = [];
for (let branch in branches) {
- branchArr.push({ name: branch, commit: commits[branches[branch]] })
+ branchArr.push({ name: branch, commit: commits[branches[branch]] });
}
- return branchArr
-}
+ return branchArr;
+};
-export const getBranches = function () { return branches }
-export const getCommits = function () { return commits }
-export const getCommitsArray = function () {
- const commitArr = Object.keys(commits).map(function (key) {
- return commits[key]
- })
- commitArr.forEach(function (o) { logger.debug(o.id) })
- return _.orderBy(commitArr, ['seq'], ['desc'])
-}
-export const getCurrentBranch = function () { return curBranch }
-export const getDirection = function () { return direction }
-export const getHead = function () { return head }
+export const getBranches = function() {
+ return branches;
+};
+export const getCommits = function() {
+ return commits;
+};
+export const getCommitsArray = function() {
+ const commitArr = Object.keys(commits).map(function(key) {
+ return commits[key];
+ });
+ commitArr.forEach(function(o) {
+ logger.debug(o.id);
+ });
+ return _.orderBy(commitArr, ['seq'], ['desc']);
+};
+export const getCurrentBranch = function() {
+ return curBranch;
+};
+export const getDirection = function() {
+ return direction;
+};
+export const getHead = function() {
+ return head;
+};
export default {
setDirection,
@@ -226,4 +240,4 @@ export default {
getCurrentBranch,
getDirection,
getHead
-}
+};
diff --git a/src/diagrams/git/gitGraphParser.spec.js b/src/diagrams/git/gitGraphParser.spec.js
index aba2812d9..6afd7f876 100644
--- a/src/diagrams/git/gitGraphParser.spec.js
+++ b/src/diagrams/git/gitGraphParser.spec.js
@@ -1,201 +1,186 @@
/* eslint-env jasmine */
-import gitGraphAst from './gitGraphAst'
-import { parser } from './parser/gitGraph'
+import gitGraphAst from './gitGraphAst';
+import { parser } from './parser/gitGraph';
-describe('when parsing a gitGraph', function () {
- beforeEach(function () {
- parser.yy = gitGraphAst
- parser.yy.clear()
- })
- it('should handle a gitGraph defintion', function () {
- const str = 'gitGraph:\n' +
- 'commit\n'
+describe('when parsing a gitGraph', function() {
+ beforeEach(function() {
+ parser.yy = gitGraphAst;
+ parser.yy.clear();
+ });
+ it('should handle a gitGraph defintion', function() {
+ const str = 'gitGraph:\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(Object.keys(commits).length).toBe(1)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getDirection()).toBe('LR')
- expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
- })
+ expect(Object.keys(commits).length).toBe(1);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getDirection()).toBe('LR');
+ expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
+ });
- it('should handle a gitGraph defintion with empty options', function () {
- const str = 'gitGraph:\n' +
- 'options\n' +
- 'end\n' +
- 'commit\n'
+ it('should handle a gitGraph defintion with empty options', function() {
+ const str = 'gitGraph:\n' + 'options\n' + 'end\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(parser.yy.getOptions()).toEqual({})
- expect(Object.keys(commits).length).toBe(1)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getDirection()).toBe('LR')
- expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
- })
+ expect(parser.yy.getOptions()).toEqual({});
+ expect(Object.keys(commits).length).toBe(1);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getDirection()).toBe('LR');
+ expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
+ });
- it('should handle a gitGraph defintion with valid options', function () {
- const str = 'gitGraph:\n' +
- 'options\n' +
- '{"key": "value"}\n' +
- 'end\n' +
- 'commit\n'
+ it('should handle a gitGraph defintion with valid options', function() {
+ const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"}\n' + 'end\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
- expect(parser.yy.getOptions()['key']).toBe('value')
- expect(Object.keys(commits).length).toBe(1)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getDirection()).toBe('LR')
- expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
- })
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
+ expect(parser.yy.getOptions()['key']).toBe('value');
+ expect(Object.keys(commits).length).toBe(1);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getDirection()).toBe('LR');
+ expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
+ });
- it('should not fail on a gitGraph with malformed json', function () {
- const str = 'gitGraph:\n' +
- 'options\n' +
- '{"key": "value"\n' +
- 'end\n' +
- 'commit\n'
+ it('should not fail on a gitGraph with malformed json', function() {
+ const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"\n' + 'end\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(1)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getDirection()).toBe('LR')
- expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
- })
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(1);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getDirection()).toBe('LR');
+ expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
+ });
- it('should handle set direction', function () {
- const str = 'gitGraph BT:\n' +
- 'commit\n'
+ it('should handle set direction', function() {
+ const str = 'gitGraph BT:\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(Object.keys(commits).length).toBe(1)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getDirection()).toBe('BT')
- expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
- })
+ expect(Object.keys(commits).length).toBe(1);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getDirection()).toBe('BT');
+ expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
+ });
- it('should checkout a branch', function () {
- const str = 'gitGraph:\n' +
- 'branch new\n' +
- 'checkout new\n'
+ it('should checkout a branch', function() {
+ const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(Object.keys(commits).length).toBe(0)
- expect(parser.yy.getCurrentBranch()).toBe('new')
- })
+ expect(Object.keys(commits).length).toBe(0);
+ expect(parser.yy.getCurrentBranch()).toBe('new');
+ });
- it('should add commits to checked out branch', function () {
- const str = 'gitGraph:\n' +
- 'branch new\n' +
- 'checkout new\n' +
- 'commit\n' +
- 'commit\n'
+ it('should add commits to checked out branch', function() {
+ const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n' + 'commit\n' + 'commit\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(Object.keys(commits).length).toBe(2)
- expect(parser.yy.getCurrentBranch()).toBe('new')
- const branchCommit = parser.yy.getBranches()['new']
- expect(branchCommit).not.toBeNull()
- expect(commits[branchCommit].parent).not.toBeNull()
- })
- it('should handle commit with args', function () {
- const str = 'gitGraph:\n' +
- 'commit "a commit"\n'
+ expect(Object.keys(commits).length).toBe(2);
+ expect(parser.yy.getCurrentBranch()).toBe('new');
+ const branchCommit = parser.yy.getBranches()['new'];
+ expect(branchCommit).not.toBeNull();
+ expect(commits[branchCommit].parent).not.toBeNull();
+ });
+ it('should handle commit with args', function() {
+ const str = 'gitGraph:\n' + 'commit "a commit"\n';
- parser.parse(str)
- const commits = parser.yy.getCommits()
+ parser.parse(str);
+ const commits = parser.yy.getCommits();
- expect(Object.keys(commits).length).toBe(1)
- const key = Object.keys(commits)[0]
- expect(commits[key].message).toBe('a commit')
- expect(parser.yy.getCurrentBranch()).toBe('master')
- })
+ expect(Object.keys(commits).length).toBe(1);
+ const key = Object.keys(commits)[0];
+ expect(commits[key].message).toBe('a commit');
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ });
- it('it should reset a branch', function () {
- const str = 'gitGraph:\n' +
+ it('it should reset a branch', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
- 'reset master\n'
+ 'reset master\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(3)
- expect(parser.yy.getCurrentBranch()).toBe('newbranch')
- expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
- expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
- })
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(3);
+ expect(parser.yy.getCurrentBranch()).toBe('newbranch');
+ expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
+ expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
+ });
- it('reset can take an argument', function () {
- const str = 'gitGraph:\n' +
+ it('reset can take an argument', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
- 'reset master^\n'
+ 'reset master^\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(3)
- expect(parser.yy.getCurrentBranch()).toBe('newbranch')
- const master = commits[parser.yy.getBranches()['master']]
- expect(parser.yy.getHead().id).toEqual(master.parent)
- })
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(3);
+ expect(parser.yy.getCurrentBranch()).toBe('newbranch');
+ const master = commits[parser.yy.getBranches()['master']];
+ expect(parser.yy.getHead().id).toEqual(master.parent);
+ });
- it('it should handle fast forwardable merges', function () {
- const str = 'gitGraph:\n' +
+ it('it should handle fast forwardable merges', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
- 'merge newbranch\n'
+ 'merge newbranch\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(3)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
- expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
- })
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(3);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
+ expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
+ });
- it('it should handle cases when merge is a noop', function () {
- const str = 'gitGraph:\n' +
+ it('it should handle cases when merge is a noop', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
- 'merge master\n'
+ 'merge master\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(3)
- expect(parser.yy.getCurrentBranch()).toBe('newbranch')
- expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
- expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
- })
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(3);
+ expect(parser.yy.getCurrentBranch()).toBe('newbranch');
+ expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master']);
+ expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
+ });
- it('it should handle merge with 2 parents', function () {
- const str = 'gitGraph:\n' +
+ it('it should handle merge with 2 parents', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
@@ -203,19 +188,20 @@ describe('when parsing a gitGraph', function () {
'commit\n' +
'checkout master\n' +
'commit\n' +
- 'merge newbranch\n'
+ 'merge newbranch\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(5)
- expect(parser.yy.getCurrentBranch()).toBe('master')
- expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
- expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
- })
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(5);
+ expect(parser.yy.getCurrentBranch()).toBe('master');
+ expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master']);
+ expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master']);
+ });
- it('it should handle ff merge when history walk has two parents (merge commit)', function () {
- const str = 'gitGraph:\n' +
+ it('it should handle ff merge when history walk has two parents (merge commit)', function() {
+ const str =
+ 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
@@ -226,16 +212,16 @@ describe('when parsing a gitGraph', function () {
'merge newbranch\n' +
'commit\n' +
'checkout newbranch\n' +
- 'merge master\n'
+ 'merge master\n';
- parser.parse(str)
+ parser.parse(str);
- const commits = parser.yy.getCommits()
- expect(Object.keys(commits).length).toBe(6)
- expect(parser.yy.getCurrentBranch()).toBe('newbranch')
- expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
- expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
+ const commits = parser.yy.getCommits();
+ expect(Object.keys(commits).length).toBe(6);
+ expect(parser.yy.getCurrentBranch()).toBe('newbranch');
+ expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
+ expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master']);
- parser.yy.prettyPrint()
- })
-})
+ parser.yy.prettyPrint();
+ });
+});
diff --git a/src/diagrams/git/gitGraphRenderer.js b/src/diagrams/git/gitGraphRenderer.js
index 00f56ed1a..9a66141a0 100644
--- a/src/diagrams/git/gitGraphRenderer.js
+++ b/src/diagrams/git/gitGraphRenderer.js
@@ -1,13 +1,13 @@
-import * as d3 from 'd3'
-import _ from 'lodash'
+import * as d3 from 'd3';
+import _ from 'lodash';
-import db from './gitGraphAst'
-import gitGraphParser from './parser/gitGraph'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
+import db from './gitGraphAst';
+import gitGraphParser from './parser/gitGraph';
+import { logger } from '../../logger';
+import { interpolateToCurve } from '../../utils';
-let allCommitsDict = {}
-let branchNum
+let allCommitsDict = {};
+let branchNum;
let config = {
nodeSpacing: 150,
nodeFillColor: 'yellow',
@@ -25,13 +25,13 @@ let config = {
x: -25,
y: 0
}
-}
-let apiConfig = {}
-export const setConf = function (c) {
- apiConfig = c
-}
+};
+let apiConfig = {};
+export const setConf = function(c) {
+ apiConfig = c;
+};
-function svgCreateDefs (svg) {
+function svgCreateDefs(svg) {
svg
.append('defs')
.append('g')
@@ -39,8 +39,9 @@ function svgCreateDefs (svg) {
.append('circle')
.attr('r', config.nodeRadius)
.attr('cx', 0)
- .attr('cy', 0)
- svg.select('#def-commit')
+ .attr('cy', 0);
+ svg
+ .select('#def-commit')
.append('foreignObject')
.attr('width', config.nodeLabel.width)
.attr('height', config.nodeLabel.height)
@@ -49,239 +50,293 @@ function svgCreateDefs (svg) {
.attr('class', 'node-label')
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
.append('p')
- .html('')
+ .html('');
}
-function svgDrawLine (svg, points, colorIdx, interpolate) {
- const curve = interpolateToCurve(interpolate, d3.curveBasis)
- const color = config.branchColors[colorIdx % config.branchColors.length]
- const lineGen = d3.line()
- .x(function (d) {
- return Math.round(d.x)
+function svgDrawLine(svg, points, colorIdx, interpolate) {
+ const curve = interpolateToCurve(interpolate, d3.curveBasis);
+ const color = config.branchColors[colorIdx % config.branchColors.length];
+ const lineGen = d3
+ .line()
+ .x(function(d) {
+ return Math.round(d.x);
})
- .y(function (d) {
- return Math.round(d.y)
+ .y(function(d) {
+ return Math.round(d.y);
})
- .curve(curve)
+ .curve(curve);
svg
.append('svg:path')
.attr('d', lineGen(points))
.style('stroke', color)
.style('stroke-width', config.lineStrokeWidth)
- .style('fill', 'none')
+ .style('fill', 'none');
}
// Pass in the element and its pre-transform coords
-function getElementCoords (element, coords) {
- coords = coords || element.node().getBBox()
- const ctm = element.node().getCTM()
- const xn = ctm.e + coords.x * ctm.a
- const yn = ctm.f + coords.y * ctm.d
+function getElementCoords(element, coords) {
+ coords = coords || element.node().getBBox();
+ const ctm = element.node().getCTM();
+ const xn = ctm.e + coords.x * ctm.a;
+ const yn = ctm.f + coords.y * ctm.d;
return {
left: xn,
top: yn,
width: coords.width,
height: coords.height
- }
+ };
}
-function svgDrawLineForCommits (svg, fromId, toId, direction, color) {
- logger.debug('svgDrawLineForCommits: ', fromId, toId)
- const fromBbox = getElementCoords(svg.select('#node-' + fromId + ' circle'))
- const toBbox = getElementCoords(svg.select('#node-' + toId + ' circle'))
+function svgDrawLineForCommits(svg, fromId, toId, direction, color) {
+ logger.debug('svgDrawLineForCommits: ', fromId, toId);
+ const fromBbox = getElementCoords(svg.select('#node-' + fromId + ' circle'));
+ const toBbox = getElementCoords(svg.select('#node-' + toId + ' circle'));
switch (direction) {
case 'LR':
// (toBbox)
// +--------
// + (fromBbox)
if (fromBbox.left - toBbox.left > config.nodeSpacing) {
- const lineStart = { x: fromBbox.left - config.nodeSpacing, y: toBbox.top + toBbox.height / 2 }
- const lineEnd = { x: toBbox.left + toBbox.width, y: toBbox.top + toBbox.height / 2 }
- svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
- svgDrawLine(svg, [
- { x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2 },
- { x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2 },
- { x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y },
- lineStart], color)
+ const lineStart = {
+ x: fromBbox.left - config.nodeSpacing,
+ y: toBbox.top + toBbox.height / 2
+ };
+ const lineEnd = { x: toBbox.left + toBbox.width, y: toBbox.top + toBbox.height / 2 };
+ svgDrawLine(svg, [lineStart, lineEnd], color, 'linear');
+ svgDrawLine(
+ svg,
+ [
+ { x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2 },
+ { x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2 },
+ { x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y },
+ lineStart
+ ],
+ color
+ );
} else {
- svgDrawLine(svg, [{
- 'x': fromBbox.left,
- 'y': fromBbox.top + fromBbox.height / 2
- }, {
- 'x': fromBbox.left - config.nodeSpacing / 2,
- 'y': fromBbox.top + fromBbox.height / 2
- }, {
- 'x': fromBbox.left - config.nodeSpacing / 2,
- 'y': toBbox.top + toBbox.height / 2
- }, {
- 'x': toBbox.left + toBbox.width,
- 'y': toBbox.top + toBbox.height / 2
- }], color)
+ svgDrawLine(
+ svg,
+ [
+ {
+ x: fromBbox.left,
+ y: fromBbox.top + fromBbox.height / 2
+ },
+ {
+ x: fromBbox.left - config.nodeSpacing / 2,
+ y: fromBbox.top + fromBbox.height / 2
+ },
+ {
+ x: fromBbox.left - config.nodeSpacing / 2,
+ y: toBbox.top + toBbox.height / 2
+ },
+ {
+ x: toBbox.left + toBbox.width,
+ y: toBbox.top + toBbox.height / 2
+ }
+ ],
+ color
+ );
}
- break
+ break;
case 'BT':
// + (fromBbox)
// |
// |
// + (toBbox)
if (toBbox.top - fromBbox.top > config.nodeSpacing) {
- const lineStart = { x: toBbox.left + toBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing }
- const lineEnd = { x: toBbox.left + toBbox.width / 2, y: toBbox.top }
- svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
- svgDrawLine(svg, [
- { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height },
- { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2 },
- { x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2 },
- lineStart], color)
+ const lineStart = {
+ x: toBbox.left + toBbox.width / 2,
+ y: fromBbox.top + fromBbox.height + config.nodeSpacing
+ };
+ const lineEnd = { x: toBbox.left + toBbox.width / 2, y: toBbox.top };
+ svgDrawLine(svg, [lineStart, lineEnd], color, 'linear');
+ svgDrawLine(
+ svg,
+ [
+ { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height },
+ {
+ x: fromBbox.left + fromBbox.width / 2,
+ y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2
+ },
+ { x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2 },
+ lineStart
+ ],
+ color
+ );
} else {
- svgDrawLine(svg, [{
- 'x': fromBbox.left + fromBbox.width / 2,
- 'y': fromBbox.top + fromBbox.height
- }, {
- 'x': fromBbox.left + fromBbox.width / 2,
- 'y': fromBbox.top + config.nodeSpacing / 2
- }, {
- 'x': toBbox.left + toBbox.width / 2,
- 'y': toBbox.top - config.nodeSpacing / 2
- }, {
- 'x': toBbox.left + toBbox.width / 2,
- 'y': toBbox.top
- }], color)
+ svgDrawLine(
+ svg,
+ [
+ {
+ x: fromBbox.left + fromBbox.width / 2,
+ y: fromBbox.top + fromBbox.height
+ },
+ {
+ x: fromBbox.left + fromBbox.width / 2,
+ y: fromBbox.top + config.nodeSpacing / 2
+ },
+ {
+ x: toBbox.left + toBbox.width / 2,
+ y: toBbox.top - config.nodeSpacing / 2
+ },
+ {
+ x: toBbox.left + toBbox.width / 2,
+ y: toBbox.top
+ }
+ ],
+ color
+ );
}
- break
+ break;
}
}
-function cloneNode (svg, selector) {
- return svg.select(selector).node().cloneNode(true)
+function cloneNode(svg, selector) {
+ return svg
+ .select(selector)
+ .node()
+ .cloneNode(true);
}
-function renderCommitHistory (svg, commitid, branches, direction) {
- let commit
- const numCommits = Object.keys(allCommitsDict).length
+function renderCommitHistory(svg, commitid, branches, direction) {
+ let commit;
+ const numCommits = Object.keys(allCommitsDict).length;
if (typeof commitid === 'string') {
do {
- commit = allCommitsDict[commitid]
- logger.debug('in renderCommitHistory', commit.id, commit.seq)
+ commit = allCommitsDict[commitid];
+ logger.debug('in renderCommitHistory', commit.id, commit.seq);
if (svg.select('#node-' + commitid).size() > 0) {
- return
+ return;
}
svg
- .append(function () {
- return cloneNode(svg, '#def-commit')
+ .append(function() {
+ return cloneNode(svg, '#def-commit');
})
.attr('class', 'commit')
- .attr('id', function () {
- return 'node-' + commit.id
+ .attr('id', function() {
+ return 'node-' + commit.id;
})
- .attr('transform', function () {
+ .attr('transform', function() {
switch (direction) {
case 'LR':
- return 'translate(' + (commit.seq * config.nodeSpacing + config.leftMargin) + ', ' +
- (branchNum * config.branchOffset) + ')'
+ return (
+ 'translate(' +
+ (commit.seq * config.nodeSpacing + config.leftMargin) +
+ ', ' +
+ branchNum * config.branchOffset +
+ ')'
+ );
case 'BT':
- return 'translate(' + (branchNum * config.branchOffset + config.leftMargin) + ', ' +
- ((numCommits - commit.seq) * config.nodeSpacing) + ')'
+ return (
+ 'translate(' +
+ (branchNum * config.branchOffset + config.leftMargin) +
+ ', ' +
+ (numCommits - commit.seq) * config.nodeSpacing +
+ ')'
+ );
}
})
.attr('fill', config.nodeFillColor)
.attr('stroke', config.nodeStrokeColor)
- .attr('stroke-width', config.nodeStrokeWidth)
+ .attr('stroke-width', config.nodeStrokeWidth);
- let branch
+ let branch;
for (let branchName in branches) {
if (branches[branchName].commit === commit) {
- branch = branches[branchName]
- break
+ branch = branches[branchName];
+ break;
}
}
if (branch) {
- logger.debug('found branch ', branch.name)
- svg.select('#node-' + commit.id + ' p')
+ logger.debug('found branch ', branch.name);
+ svg
+ .select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'branch-label')
- .text(branch.name + ', ')
+ .text(branch.name + ', ');
}
- svg.select('#node-' + commit.id + ' p')
+ svg
+ .select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'commit-id')
- .text(commit.id)
+ .text(commit.id);
if (commit.message !== '' && direction === 'BT') {
- svg.select('#node-' + commit.id + ' p')
+ svg
+ .select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'commit-msg')
- .text(', ' + commit.message)
+ .text(', ' + commit.message);
}
- commitid = commit.parent
- } while (commitid && allCommitsDict[commitid])
+ commitid = commit.parent;
+ } while (commitid && allCommitsDict[commitid]);
}
if (Array.isArray(commitid)) {
- logger.debug('found merge commmit', commitid)
- renderCommitHistory(svg, commitid[0], branches, direction)
- branchNum++
- renderCommitHistory(svg, commitid[1], branches, direction)
- branchNum--
+ logger.debug('found merge commmit', commitid);
+ renderCommitHistory(svg, commitid[0], branches, direction);
+ branchNum++;
+ renderCommitHistory(svg, commitid[1], branches, direction);
+ branchNum--;
}
}
-function renderLines (svg, commit, direction, branchColor) {
- branchColor = branchColor || 0
+function renderLines(svg, commit, direction, branchColor) {
+ branchColor = branchColor || 0;
while (commit.seq > 0 && !commit.lineDrawn) {
if (typeof commit.parent === 'string') {
- svgDrawLineForCommits(svg, commit.id, commit.parent, direction, branchColor)
- commit.lineDrawn = true
- commit = allCommitsDict[commit.parent]
+ svgDrawLineForCommits(svg, commit.id, commit.parent, direction, branchColor);
+ commit.lineDrawn = true;
+ commit = allCommitsDict[commit.parent];
} else if (Array.isArray(commit.parent)) {
- svgDrawLineForCommits(svg, commit.id, commit.parent[0], direction, branchColor)
- svgDrawLineForCommits(svg, commit.id, commit.parent[1], direction, branchColor + 1)
- renderLines(svg, allCommitsDict[commit.parent[1]], direction, branchColor + 1)
- commit.lineDrawn = true
- commit = allCommitsDict[commit.parent[0]]
+ svgDrawLineForCommits(svg, commit.id, commit.parent[0], direction, branchColor);
+ svgDrawLineForCommits(svg, commit.id, commit.parent[1], direction, branchColor + 1);
+ renderLines(svg, allCommitsDict[commit.parent[1]], direction, branchColor + 1);
+ commit.lineDrawn = true;
+ commit = allCommitsDict[commit.parent[0]];
}
}
}
-export const draw = function (txt, id, ver) {
+export const draw = function(txt, id, ver) {
try {
- const parser = gitGraphParser.parser
- parser.yy = db
+ const parser = gitGraphParser.parser;
+ parser.yy = db;
- logger.debug('in gitgraph renderer', txt, id, ver)
+ logger.debug('in gitgraph renderer', txt, id, ver);
// Parse the graph definition
- parser.parse(txt + '\n')
+ parser.parse(txt + '\n');
- config = _.assign(config, apiConfig, db.getOptions())
- logger.debug('effective options', config)
- const direction = db.getDirection()
- allCommitsDict = db.getCommits()
- const branches = db.getBranchesAsObjArray()
+ config = _.assign(config, apiConfig, db.getOptions());
+ logger.debug('effective options', config);
+ const direction = db.getDirection();
+ allCommitsDict = db.getCommits();
+ const branches = db.getBranchesAsObjArray();
if (direction === 'BT') {
- config.nodeLabel.x = branches.length * config.branchOffset
- config.nodeLabel.width = '100%'
- config.nodeLabel.y = -1 * 2 * config.nodeRadius
+ config.nodeLabel.x = branches.length * config.branchOffset;
+ config.nodeLabel.width = '100%';
+ config.nodeLabel.y = -1 * 2 * config.nodeRadius;
}
- const svg = d3.select(`[id="${id}"]`)
- svgCreateDefs(svg)
- branchNum = 1
+ const svg = d3.select(`[id="${id}"]`);
+ svgCreateDefs(svg);
+ branchNum = 1;
for (let branch in branches) {
- const v = branches[branch]
- renderCommitHistory(svg, v.commit.id, branches, direction)
- renderLines(svg, v.commit, direction)
- branchNum++
+ const v = branches[branch];
+ renderCommitHistory(svg, v.commit.id, branches, direction);
+ renderLines(svg, v.commit, direction);
+ branchNum++;
}
- svg.attr('height', function () {
- if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing
- return (branches.length + 1) * config.branchOffset
- })
+ svg.attr('height', function() {
+ if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing;
+ return (branches.length + 1) * config.branchOffset;
+ });
} catch (e) {
- logger.error('Error while rendering gitgraph')
- logger.error(e.message)
+ logger.error('Error while rendering gitgraph');
+ logger.error(e.message);
}
-}
+};
export default {
setConf,
draw
-}
+};
diff --git a/src/diagrams/info/info.spec.js b/src/diagrams/info/info.spec.js
index 5b7c50577..502e4bdf8 100644
--- a/src/diagrams/info/info.spec.js
+++ b/src/diagrams/info/info.spec.js
@@ -1,15 +1,15 @@
/* eslint-env jasmine */
-describe('when parsing an info graph it', function () {
- var ex
- beforeEach(function () {
- ex = require('./parser/info').parser
- ex.yy = require('./infoDb')
- })
+describe('when parsing an info graph it', function() {
+ var ex;
+ beforeEach(function() {
+ ex = require('./parser/info').parser;
+ ex.yy = require('./infoDb');
+ });
- it('should handle an info definition', function () {
+ it('should handle an info definition', function() {
var str = `info
- showInfo`
+ showInfo`;
- ex.parse(str)
- })
-})
+ ex.parse(str);
+ });
+});
diff --git a/src/diagrams/info/infoDb.js b/src/diagrams/info/infoDb.js
index cd79b024c..2253c819e 100644
--- a/src/diagrams/info/infoDb.js
+++ b/src/diagrams/info/infoDb.js
@@ -1,27 +1,27 @@
/**
* Created by knut on 15-01-14.
*/
-import { logger } from '../../logger'
+import { logger } from '../../logger';
-var message = ''
-var info = false
+var message = '';
+var info = false;
export const setMessage = txt => {
- logger.debug('Setting message to: ' + txt)
- message = txt
-}
+ logger.debug('Setting message to: ' + txt);
+ message = txt;
+};
export const getMessage = () => {
- return message
-}
+ return message;
+};
export const setInfo = inf => {
- info = inf
-}
+ info = inf;
+};
export const getInfo = () => {
- return info
-}
+ return info;
+};
// export const parseError = (err, hash) => {
// global.mermaidAPI.parseError(err, hash)
@@ -33,4 +33,4 @@ export default {
setInfo,
getInfo
// parseError
-}
+};
diff --git a/src/diagrams/info/infoRenderer.js b/src/diagrams/info/infoRenderer.js
index dc4d7066e..8aceffb65 100644
--- a/src/diagrams/info/infoRenderer.js
+++ b/src/diagrams/info/infoRenderer.js
@@ -1,20 +1,19 @@
/**
* Created by knut on 14-12-11.
*/
-import * as d3 from 'd3'
-import db from './infoDb'
-import infoParser from './parser/info'
-import { logger } from '../../logger'
+import * as d3 from 'd3';
+import db from './infoDb';
+import infoParser from './parser/info';
+import { logger } from '../../logger';
-const conf = {
-}
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+const conf = {};
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
- keys.forEach(function (key) {
- conf[key] = cnf[key]
- })
-}
+ keys.forEach(function(key) {
+ conf[key] = cnf[key];
+ });
+};
/**
* Draws a an info picture in the tag with id: id based on the graph definition in text.
@@ -23,16 +22,16 @@ export const setConf = function (cnf) {
*/
export const draw = (txt, id, ver) => {
try {
- const parser = infoParser.parser
- parser.yy = db
- logger.debug('Renering info diagram\n' + txt)
+ const parser = infoParser.parser;
+ parser.yy = db;
+ logger.debug('Renering info diagram\n' + txt);
// Parse the graph definition
- parser.parse(txt)
- logger.debug('Parsed info diagram')
+ parser.parse(txt);
+ logger.debug('Parsed info diagram');
// Fetch the default direction, use TD if none was found
- const svg = d3.select('#' + id)
+ const svg = d3.select('#' + id);
- const g = svg.append('g')
+ const g = svg.append('g');
g.append('text') // text label for the x axis
.attr('x', 100)
@@ -40,18 +39,18 @@ export const draw = (txt, id, ver) => {
.attr('class', 'version')
.attr('font-size', '32px')
.style('text-anchor', 'middle')
- .text('v ' + ver)
+ .text('v ' + ver);
- svg.attr('height', 100)
- svg.attr('width', 400)
+ svg.attr('height', 100);
+ svg.attr('width', 400);
// svg.attr('viewBox', '0 0 300 150');
} catch (e) {
- logger.error('Error while rendering info diagram')
- logger.error(e.message)
+ logger.error('Error while rendering info diagram');
+ logger.error(e.message);
}
-}
+};
export default {
setConf,
draw
-}
+};
diff --git a/src/diagrams/pie/parser/pie.spec.js b/src/diagrams/pie/parser/pie.spec.js
index 0e9b80384..7902ce715 100644
--- a/src/diagrams/pie/parser/pie.spec.js
+++ b/src/diagrams/pie/parser/pie.spec.js
@@ -1,37 +1,36 @@
-
/* eslint-env jasmine */
-import pieDb from '../pieDb'
-import pie from './pie'
-import { setConfig } from '../../../config'
+import pieDb from '../pieDb';
+import pie from './pie';
+import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
-})
+});
-describe('when parsing pie', function () {
- beforeEach(function () {
- pie.parser.yy = pieDb
- pie.parser.yy.clear()
- })
- it('should handle simple pie', function () {
- const res = pie.parser.parse('pie \n"ash" : 60\n"bat" : 40\n')
- const sections = pieDb.getSections()
- console.log('sections: ', sections)
- const section1 = sections['ash']
- expect(section1).toBe(60)
- })
+describe('when parsing pie', function() {
+ beforeEach(function() {
+ pie.parser.yy = pieDb;
+ pie.parser.yy.clear();
+ });
+ it('should handle simple pie', function() {
+ const res = pie.parser.parse('pie \n"ash" : 60\n"bat" : 40\n');
+ const sections = pieDb.getSections();
+ console.log('sections: ', sections);
+ const section1 = sections['ash'];
+ expect(section1).toBe(60);
+ });
- it('should handle simple pie with positive decimal', function () {
- const res = pie.parser.parse('pie \n"ash" : 60.67\n"bat" : 40\n')
- const sections = pieDb.getSections()
- console.log('sections: ', sections)
- const section1 = sections['ash']
- expect(section1).toBe(60.67)
- })
+ it('should handle simple pie with positive decimal', function() {
+ const res = pie.parser.parse('pie \n"ash" : 60.67\n"bat" : 40\n');
+ const sections = pieDb.getSections();
+ console.log('sections: ', sections);
+ const section1 = sections['ash'];
+ expect(section1).toBe(60.67);
+ });
- it('should handle simple pie with negative decimal', function () {
- expect(()=>{
+ it('should handle simple pie with negative decimal', function() {
+ expect(() => {
pie.parser.parse('pie \n"ash" : 60.67\n"bat" : 40..12\n');
- }).toThrowError();
- })
-})
+ }).toThrowError();
+ });
+});
diff --git a/src/diagrams/pie/pieDb.js b/src/diagrams/pie/pieDb.js
index 8c1f294fe..d4572b547 100644
--- a/src/diagrams/pie/pieDb.js
+++ b/src/diagrams/pie/pieDb.js
@@ -1,40 +1,40 @@
/**
*
*/
-import { logger } from '../../logger'
+import { logger } from '../../logger';
-let sections = {}
-let title = ''
+let sections = {};
+let title = '';
-const addSection = function (id, value) {
+const addSection = function(id, value) {
if (typeof sections[id] === 'undefined') {
- sections[id] = value
- logger.debug('Added new section :', id)
+ sections[id] = value;
+ logger.debug('Added new section :', id);
// console.log('Added new section:', id, value)
}
-}
-const getSections = () => sections
+};
+const getSections = () => sections;
-const setTitle = function (txt) {
- title = txt
-}
+const setTitle = function(txt) {
+ title = txt;
+};
-const getTitle = function () {
- return title
-}
-const cleanupValue = function (value) {
+const getTitle = function() {
+ return title;
+};
+const cleanupValue = function(value) {
if (value.substring(0, 1) === ':') {
- value = value.substring(1).trim()
- return Number(value.trim())
+ value = value.substring(1).trim();
+ return Number(value.trim());
} else {
- return Number(value.trim())
+ return Number(value.trim());
}
-}
+};
-const clear = function () {
- sections = {}
- title = ''
-}
+const clear = function() {
+ sections = {};
+ title = '';
+};
// export const parseError = (err, hash) => {
// global.mermaidAPI.parseError(err, hash)
// }
@@ -47,4 +47,4 @@ export default {
setTitle,
getTitle
// parseError
-}
+};
diff --git a/src/diagrams/pie/pieRenderer.js b/src/diagrams/pie/pieRenderer.js
index a1d7ec30f..bdf857480 100644
--- a/src/diagrams/pie/pieRenderer.js
+++ b/src/diagrams/pie/pieRenderer.js
@@ -1,83 +1,87 @@
/**
* Created by AshishJ on 11-09-2019.
*/
-import * as d3 from 'd3'
-import pieData from './pieDb'
-import pieParser from './parser/pie'
-import { logger } from '../../logger'
+import * as d3 from 'd3';
+import pieData from './pieDb';
+import pieParser from './parser/pie';
+import { logger } from '../../logger';
-const conf = {
-}
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+const conf = {};
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
- keys.forEach(function (key) {
- conf[key] = cnf[key]
- })
-}
+ keys.forEach(function(key) {
+ conf[key] = cnf[key];
+ });
+};
/**
* Draws a Pie Chart with the data given in text.
* @param text
* @param id
*/
-let w
+let w;
export const draw = (txt, id, ver) => {
try {
- const parser = pieParser.parser
- parser.yy = pieData
- logger.debug('Rendering info diagram\n' + txt)
+ const parser = pieParser.parser;
+ parser.yy = pieData;
+ logger.debug('Rendering info diagram\n' + txt);
// Parse the Pie Chart definition
- parser.yy.clear()
- parser.parse(txt)
- logger.debug('Parsed info diagram')
- const elem = document.getElementById(id)
- w = elem.parentElement.offsetWidth
+ parser.yy.clear();
+ parser.parse(txt);
+ logger.debug('Parsed info diagram');
+ const elem = document.getElementById(id);
+ w = elem.parentElement.offsetWidth;
if (typeof w === 'undefined') {
- w = 1200
+ w = 1200;
}
if (typeof conf.useWidth !== 'undefined') {
- w = conf.useWidth
+ w = conf.useWidth;
}
- const h = 450
- elem.setAttribute('height', '100%')
+ const h = 450;
+ elem.setAttribute('height', '100%');
// Set viewBox
- elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
+ elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
// Fetch the default direction, use TD if none was found
- var width = w// 450
- var height = 450
- var margin = 40
+ var width = w; // 450
+ var height = 450;
+ var margin = 40;
- var radius = Math.min(width, height) / 2 - margin
+ var radius = Math.min(width, height) / 2 - margin;
- var svg = d3.select('#' + id).append('svg')
+ var svg = d3
+ .select('#' + id)
+ .append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
- .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
+ .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
- var data = pieData.getSections()
- logger.info(data)
+ var data = pieData.getSections();
+ logger.info(data);
// set the color scale
- var color = d3.scaleOrdinal()
+ var color = d3
+ .scaleOrdinal()
.domain(data)
- .range(d3.schemeSet2)
+ .range(d3.schemeSet2);
// Compute the position of each group on the pie:
- var pie = d3.pie()
- .value(function (d) { return d.value })
- var dataReady = pie(d3.entries(data))
+ var pie = d3.pie().value(function(d) {
+ return d.value;
+ });
+ var dataReady = pie(d3.entries(data));
// Now I know that group A goes from 0 degrees to x degrees and so on.
// shape helper to build arcs:
- var arcGenerator = d3.arc()
+ var arcGenerator = d3
+ .arc()
.innerRadius(0)
- .outerRadius(radius)
+ .outerRadius(radius);
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
svg
@@ -86,10 +90,12 @@ export const draw = (txt, id, ver) => {
.enter()
.append('path')
.attr('d', arcGenerator)
- .attr('fill', function (d) { return (color(d.data.key)) })
+ .attr('fill', function(d) {
+ return color(d.data.key);
+ })
.attr('stroke', 'black')
.style('stroke-width', '2px')
- .style('opacity', 0.7)
+ .style('opacity', 0.7);
// Now add the annotation. Use the centroid method to get the best coordinates
svg
@@ -97,23 +103,28 @@ export const draw = (txt, id, ver) => {
.data(dataReady)
.enter()
.append('text')
- .text(function (d) { return d.data.key })
- .attr('transform', function (d) { return 'translate(' + arcGenerator.centroid(d) + ')' })
+ .text(function(d) {
+ return d.data.key;
+ })
+ .attr('transform', function(d) {
+ return 'translate(' + arcGenerator.centroid(d) + ')';
+ })
.style('text-anchor', 'middle')
- .style('font-size', 17)
+ .style('font-size', 17);
- svg.append('text')
+ svg
+ .append('text')
.text(parser.yy.getTitle())
.attr('x', 0)
.attr('y', -(h - 50) / 2)
- .attr('class', 'pieTitleText')
+ .attr('class', 'pieTitleText');
} catch (e) {
- logger.error('Error while rendering info diagram')
- logger.error(e.message)
+ logger.error('Error while rendering info diagram');
+ logger.error(e.message);
}
-}
+};
export default {
setConf,
draw
-}
+};
diff --git a/src/diagrams/sequence/sequenceDb.js b/src/diagrams/sequence/sequenceDb.js
index e531ed2f9..050691a6c 100644
--- a/src/diagrams/sequence/sequenceDb.js
+++ b/src/diagrams/sequence/sequenceDb.js
@@ -1,51 +1,53 @@
-import { logger } from '../../logger'
+import { logger } from '../../logger';
-let actors = {}
-let messages = []
-const notes = []
-let title = ''
+let actors = {};
+let messages = [];
+const notes = [];
+let title = '';
-export const addActor = function (id, name, description) {
+export const addActor = function(id, name, description) {
// Don't allow description nulling
- const old = actors[id]
- if (old && name === old.name && description == null) return
+ const old = actors[id];
+ if (old && name === old.name && description == null) return;
// Don't allow null descriptions, either
- if (description == null) description = name
+ if (description == null) description = name;
- actors[id] = { name: name, description: description }
-}
+ actors[id] = { name: name, description: description };
+};
-export const addMessage = function (idFrom, idTo, message, answer) {
- messages.push({ from: idFrom, to: idTo, message: message, answer: answer })
-}
+export const addMessage = function(idFrom, idTo, message, answer) {
+ messages.push({ from: idFrom, to: idTo, message: message, answer: answer });
+};
-export const addSignal = function (idFrom, idTo, message, messageType) {
- logger.debug('Adding message from=' + idFrom + ' to=' + idTo + ' message=' + message + ' type=' + messageType)
- messages.push({ from: idFrom, to: idTo, message: message, type: messageType })
-}
+export const addSignal = function(idFrom, idTo, message, messageType) {
+ logger.debug(
+ 'Adding message from=' + idFrom + ' to=' + idTo + ' message=' + message + ' type=' + messageType
+ );
+ messages.push({ from: idFrom, to: idTo, message: message, type: messageType });
+};
-export const getMessages = function () {
- return messages
-}
+export const getMessages = function() {
+ return messages;
+};
-export const getActors = function () {
- return actors
-}
-export const getActor = function (id) {
- return actors[id]
-}
-export const getActorKeys = function () {
- return Object.keys(actors)
-}
-export const getTitle = function () {
- return title
-}
+export const getActors = function() {
+ return actors;
+};
+export const getActor = function(id) {
+ return actors[id];
+};
+export const getActorKeys = function() {
+ return Object.keys(actors);
+};
+export const getTitle = function() {
+ return title;
+};
-export const clear = function () {
- actors = {}
- messages = []
-}
+export const clear = function() {
+ actors = {};
+ messages = [];
+};
export const LINETYPE = {
SOLID: 0,
@@ -69,97 +71,103 @@ export const LINETYPE = {
PAR_END: 21,
RECT_START: 22,
RECT_END: 23
-}
+};
export const ARROWTYPE = {
FILLED: 0,
OPEN: 1
-}
+};
export const PLACEMENT = {
LEFTOF: 0,
RIGHTOF: 1,
OVER: 2
-}
+};
-export const addNote = function (actor, placement, message) {
- const note = { actor: actor, placement: placement, message: message }
+export const addNote = function(actor, placement, message) {
+ const note = { actor: actor, placement: placement, message: message };
// Coerce actor into a [to, from, ...] array
- const actors = [].concat(actor, actor)
+ const actors = [].concat(actor, actor);
- notes.push(note)
- messages.push({ from: actors[0], to: actors[1], message: message, type: LINETYPE.NOTE, placement: placement })
-}
+ notes.push(note);
+ messages.push({
+ from: actors[0],
+ to: actors[1],
+ message: message,
+ type: LINETYPE.NOTE,
+ placement: placement
+ });
+};
-export const setTitle = function (titleText) {
- title = titleText
-}
+export const setTitle = function(titleText) {
+ title = titleText;
+};
-export const apply = function (param) {
+export const apply = function(param) {
if (param instanceof Array) {
- param.forEach(function (item) {
- apply(item)
- })
+ param.forEach(function(item) {
+ apply(item);
+ });
} else {
switch (param.type) {
case 'addActor':
- addActor(param.actor, param.actor, param.description)
- break
+ addActor(param.actor, param.actor, param.description);
+ break;
case 'activeStart':
- addSignal(param.actor, undefined, undefined, param.signalType)
- break
+ addSignal(param.actor, undefined, undefined, param.signalType);
+ break;
case 'activeEnd':
- addSignal(param.actor, undefined, undefined, param.signalType)
- break
+ addSignal(param.actor, undefined, undefined, param.signalType);
+ break;
case 'addNote':
- addNote(param.actor, param.placement, param.text)
- break
+ addNote(param.actor, param.placement, param.text);
+ break;
case 'addMessage':
- addSignal(param.from, param.to, param.msg, param.signalType)
- break
+ addSignal(param.from, param.to, param.msg, param.signalType);
+ break;
case 'loopStart':
- addSignal(undefined, undefined, param.loopText, param.signalType)
- break
+ addSignal(undefined, undefined, param.loopText, param.signalType);
+ break;
case 'loopEnd':
- addSignal(undefined, undefined, undefined, param.signalType)
- break
+ addSignal(undefined, undefined, undefined, param.signalType);
+ break;
case 'rectStart':
- addSignal(undefined, undefined, param.color, param.signalType)
- break
+ addSignal(undefined, undefined, param.color, param.signalType);
+ break;
case 'rectEnd':
- addSignal(undefined, undefined, undefined, param.signalType)
- break
+ addSignal(undefined, undefined, undefined, param.signalType);
+ break;
case 'optStart':
- addSignal(undefined, undefined, param.optText, param.signalType)
- break
+ addSignal(undefined, undefined, param.optText, param.signalType);
+ break;
case 'optEnd':
- addSignal(undefined, undefined, undefined, param.signalType)
- break
+ addSignal(undefined, undefined, undefined, param.signalType);
+ break;
case 'altStart':
- addSignal(undefined, undefined, param.altText, param.signalType)
- break
+ addSignal(undefined, undefined, param.altText, param.signalType);
+ break;
case 'else':
- addSignal(undefined, undefined, param.altText, param.signalType)
- break
+ addSignal(undefined, undefined, param.altText, param.signalType);
+ break;
case 'altEnd':
- addSignal(undefined, undefined, undefined, param.signalType)
- break
+ addSignal(undefined, undefined, undefined, param.signalType);
+ break;
case 'setTitle':
- setTitle(param.text)
- break
+ setTitle(param.text);
+ break;
case 'parStart':
- addSignal(undefined, undefined, param.parText, param.signalType)
- break
+ addSignal(undefined, undefined, param.parText, param.signalType);
+ break;
case 'and':
- addSignal(undefined, undefined, param.parText, param.signalType)
- break
+ addSignal(undefined, undefined, param.parText, param.signalType);
+ break;
case 'parEnd':
- addSignal(undefined, undefined, undefined, param.signalType)
- break
+ addSignal(undefined, undefined, undefined, param.signalType);
+ break;
}
}
-}
+};
export default {
addActor,
@@ -177,4 +185,4 @@ export default {
addNote,
setTitle,
apply
-}
+};
diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js
index d9039e6c5..2ed1c411c 100644
--- a/src/diagrams/sequence/sequenceDiagram.spec.js
+++ b/src/diagrams/sequence/sequenceDiagram.spec.js
@@ -1,307 +1,316 @@
/* eslint-env jasmine */
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
-import renderer from './sequenceRenderer'
+import { parser } from './parser/sequenceDiagram';
+import sequenceDb from './sequenceDb';
+import renderer from './sequenceRenderer';
-function addConf (conf, key, value) {
+function addConf(conf, key, value) {
if (value !== undefined) {
- conf[key] = value
+ conf[key] = value;
}
- return conf
+ return conf;
}
-describe('when parsing a sequenceDiagram', function () {
- beforeEach(function () {
- parser.yy = sequenceDb
- parser.yy.clear()
- })
- it('it should handle a sequenceDiagram defintion', function () {
- const str = 'sequenceDiagram\n' +
+describe('when parsing a sequenceDiagram', function() {
+ beforeEach(function() {
+ parser.yy = sequenceDb;
+ parser.yy.clear();
+ });
+ it('it should handle a sequenceDiagram defintion', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle a sequenceDiagram definition with a title', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle a sequenceDiagram definition with a title', function() {
+ const str =
+ 'sequenceDiagram\n' +
'title: Diagram Title\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
- const title = parser.yy.getTitle()
+ const messages = parser.yy.getMessages();
+ const title = parser.yy.getTitle();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- expect(title).toBe('Diagram Title')
- })
- it('it should space in actor names', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ expect(title).toBe('Diagram Title');
+ });
+ it('it should space in actor names', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob:Hello Bob, how are - you?\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(2)
- expect(messages[0].from).toBe('Alice')
- expect(messages[1].from).toBe('Bob')
- })
- it('it should alias participants', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(2);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[1].from).toBe('Bob');
+ });
+ it('it should alias participants', function() {
+ const str =
+ 'sequenceDiagram\n' +
'participant A as Alice\n' +
'participant B as Bob\n' +
'A->B:Hello Bob, how are you?\n' +
- 'B-->A: I am good thanks!'
+ 'B-->A: I am good thanks!';
- parser.parse(str)
+ parser.parse(str);
- const actors = parser.yy.getActors()
- expect(Object.keys(actors)).toEqual(['A', 'B'])
- expect(actors.A.description).toBe('Alice')
- expect(actors.B.description).toBe('Bob')
+ const actors = parser.yy.getActors();
+ expect(Object.keys(actors)).toEqual(['A', 'B']);
+ expect(actors.A.description).toBe('Alice');
+ expect(actors.B.description).toBe('Bob');
- const messages = parser.yy.getMessages()
- expect(messages.length).toBe(2)
- expect(messages[0].from).toBe('A')
- expect(messages[1].from).toBe('B')
- })
- it('it should handle in async messages', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice-xBob:Hello Bob, how are you?'
+ const messages = parser.yy.getMessages();
+ expect(messages.length).toBe(2);
+ expect(messages[0].from).toBe('A');
+ expect(messages[1].from).toBe('B');
+ });
+ it('it should handle in async messages', function() {
+ const str = 'sequenceDiagram\n' + 'Alice-xBob:Hello Bob, how are you?';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(1)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS)
- })
- it('it should handle in async dotted messages', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice--xBob:Hello Bob, how are you?'
+ expect(messages.length).toBe(1);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS);
+ });
+ it('it should handle in async dotted messages', function() {
+ const str = 'sequenceDiagram\n' + 'Alice--xBob:Hello Bob, how are you?';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(1)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS)
- })
- it('it should handle in arrow messages', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice->>Bob:Hello Bob, how are you?'
+ expect(messages.length).toBe(1);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS);
+ });
+ it('it should handle in arrow messages', function() {
+ const str = 'sequenceDiagram\n' + 'Alice->>Bob:Hello Bob, how are you?';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(1)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID)
- })
- it('it should handle in arrow messages', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice-->>Bob:Hello Bob, how are you?'
+ expect(messages.length).toBe(1);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID);
+ });
+ it('it should handle in arrow messages', function() {
+ const str = 'sequenceDiagram\n' + 'Alice-->>Bob:Hello Bob, how are you?';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(1)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
- })
- it('it should handle actor activation', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(1);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED);
+ });
+ it('it should handle actor activation', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice-->>Bob:Hello Bob, how are you?\n' +
'activate Bob\n' +
- 'Bob-->>Alice:Hello Alice, I\'m fine and you?\n' +
- 'deactivate Bob'
+ "Bob-->>Alice:Hello Alice, I'm fine and you?\n" +
+ 'deactivate Bob';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(4)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
- expect(messages[1].from.actor).toBe('Bob')
- expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
- expect(messages[3].from.actor).toBe('Bob')
- })
- it('it should handle actor one line notation activation', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(4);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START);
+ expect(messages[1].from.actor).toBe('Bob');
+ expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
+ expect(messages[3].from.actor).toBe('Bob');
+ });
+ it('it should handle actor one line notation activation', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice-->>+Bob:Hello Bob, how are you?\n' +
- 'Bob-->>- Alice:Hello Alice, I\'m fine and you?'
+ "Bob-->>- Alice:Hello Alice, I'm fine and you?";
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(4)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
- expect(messages[1].from.actor).toBe('Bob')
- expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
- expect(messages[3].from.actor).toBe('Bob')
- })
- it('it should handle stacked activations', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(4);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START);
+ expect(messages[1].from.actor).toBe('Bob');
+ expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
+ expect(messages[3].from.actor).toBe('Bob');
+ });
+ it('it should handle stacked activations', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice-->>+Bob:Hello Bob, how are you?\n' +
'Bob-->>+Carol:Carol, let me introduce Alice?\n' +
'Bob-->>- Alice:Hello Alice, please meet Carol?\n' +
- 'Carol->>- Bob:Oh Bob, I\'m so happy to be here!'
+ "Carol->>- Bob:Oh Bob, I'm so happy to be here!";
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(8)
- expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
- expect(messages[1].from.actor).toBe('Bob')
- expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
- expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
- expect(messages[3].from.actor).toBe('Carol')
- expect(messages[5].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
- expect(messages[5].from.actor).toBe('Bob')
- expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
- expect(messages[7].from.actor).toBe('Carol')
- })
- it('it should handle comments in a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(8);
+ expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START);
+ expect(messages[1].from.actor).toBe('Bob');
+ expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED);
+ expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_START);
+ expect(messages[3].from.actor).toBe('Carol');
+ expect(messages[5].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
+ expect(messages[5].from.actor).toBe('Bob');
+ expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
+ expect(messages[7].from.actor).toBe('Carol');
+ });
+ it('it should handle comments in a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle new lines in a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle new lines in a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!\n'
+ 'Bob-->Alice: I am good thanks!\n';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle semicolons', function () {
- const str = 'sequenceDiagram;' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle semicolons', function() {
+ const str =
+ 'sequenceDiagram;' +
'Alice->Bob: Hello Bob, how are you?;' +
'Note right of Bob: Bob thinks;' +
- 'Bob-->Alice: I am good thanks!;'
+ 'Bob-->Alice: I am good thanks!;';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle one leading space in lines in a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle one leading space in lines in a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle several leading spaces in lines in a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob-->Alice: I am good thanks!'
+ 'Bob-->Alice: I am good thanks!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(3)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(3);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle several leading spaces in lines in a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
'participant Alice\n' +
'participant Bob\n' +
'Alice->John: Hello John, how are you?\n' +
@@ -311,65 +320,66 @@ describe('when parsing a sequenceDiagram', function () {
'Note right of John: Rational thoughts
prevail...\n' +
' John-->Alice: Great!\n' +
' John->Bob: How about you?\n' +
- 'Bob-->John: Jolly good!'
+ 'Bob-->John: Jolly good!';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(8)
- expect(messages[0].from).toBe('Alice')
- expect(messages[2].from).toBe('John')
- })
- it('it should handle notes over a single actor', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice->Bob: Hello Bob, how are you?\n' +
- 'Note over Bob: Bob thinks\n'
+ expect(messages.length).toBe(8);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[2].from).toBe('John');
+ });
+ it('it should handle notes over a single actor', function() {
+ const str =
+ 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n' + 'Note over Bob: Bob thinks\n';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].from).toBe('Bob')
- expect(messages[1].to).toBe('Bob')
- })
- it('it should handle notes over multiple actors', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].from).toBe('Bob');
+ expect(messages[1].to).toBe('Bob');
+ });
+ it('it should handle notes over multiple actors', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: confusion\n' +
- 'Note over Bob,Alice: resolution\n'
+ 'Note over Bob,Alice: resolution\n';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].from).toBe('Alice')
- expect(messages[1].to).toBe('Bob')
- expect(messages[2].from).toBe('Bob')
- expect(messages[2].to).toBe('Alice')
- })
- it('it should handle loop statements', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].from).toBe('Alice');
+ expect(messages[1].to).toBe('Bob');
+ expect(messages[2].from).toBe('Bob');
+ expect(messages[2].to).toBe('Alice');
+ });
+ it('it should handle loop statements', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'loop Multiple happy responses\n\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(5)
- expect(messages[0].from).toBe('Alice')
- expect(messages[1].from).toBe('Bob')
- })
- it('it should add a rect around sequence', function () {
+ expect(messages.length).toBe(5);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[1].from).toBe('Bob');
+ });
+ it('it should add a rect around sequence', function() {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@@ -378,22 +388,22 @@ describe('when parsing a sequenceDiagram', function () {
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks
end
- `
+ `;
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
- expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START)
- expect(messages[1].message).toBe('rgb(200, 255, 200)')
- expect(messages[2].type).toEqual(parser.yy.LINETYPE.NOTE)
- expect(messages[3].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN)
- expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END)
- })
+ const messages = parser.yy.getMessages();
+ expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START);
+ expect(messages[1].message).toBe('rgb(200, 255, 200)');
+ expect(messages[2].type).toEqual(parser.yy.LINETYPE.NOTE);
+ expect(messages[3].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN);
+ expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END);
+ });
- it('it should allow for nested rects', function () {
+ it('it should allow for nested rects', function() {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@@ -404,44 +414,46 @@ describe('when parsing a sequenceDiagram', function () {
end
Bob-->Alice: I am good thanks
end
- `
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ `;
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
- expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START)
- expect(messages[1].message).toBe('rgb(200, 255, 200)')
- expect(messages[2].type).toEqual(parser.yy.LINETYPE.RECT_START)
- expect(messages[2].message).toBe('rgb(0, 0, 0)')
- expect(messages[3].type).toEqual(parser.yy.LINETYPE.NOTE)
- expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END)
- expect(messages[5].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN)
- expect(messages[6].type).toEqual(parser.yy.LINETYPE.RECT_END)
- })
- it('it should handle opt statements', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START);
+ expect(messages[1].message).toBe('rgb(200, 255, 200)');
+ expect(messages[2].type).toEqual(parser.yy.LINETYPE.RECT_START);
+ expect(messages[2].message).toBe('rgb(0, 0, 0)');
+ expect(messages[3].type).toEqual(parser.yy.LINETYPE.NOTE);
+ expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END);
+ expect(messages[5].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN);
+ expect(messages[6].type).toEqual(parser.yy.LINETYPE.RECT_END);
+ });
+ it('it should handle opt statements', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'opt Perhaps a happy response\n\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
- const actors = parser.yy.getActors()
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ parser.parse(str);
+ const actors = parser.yy.getActors();
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(5)
- expect(messages[0].from).toBe('Alice')
- expect(messages[1].from).toBe('Bob')
- })
- it('it should handle alt statements', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(5);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[1].from).toBe('Bob');
+ });
+ it('it should handle alt statements', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
@@ -449,22 +461,23 @@ describe('when parsing a sequenceDiagram', function () {
'Bob-->Alice: I am good thanks!\n' +
'else isSick\n' +
'Bob-->Alice: Feel sick...\n' +
- 'end'
+ 'end';
- parser.parse(str)
- const actors = parser.yy.getActors()
+ parser.parse(str);
+ const actors = parser.yy.getActors();
- expect(actors.Alice.description).toBe('Alice')
- actors.Bob.description = 'Bob'
+ expect(actors.Alice.description).toBe('Alice');
+ actors.Bob.description = 'Bob';
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(7)
- expect(messages[0].from).toBe('Alice')
- expect(messages[1].from).toBe('Bob')
- })
- it('it should handle alt statements with multiple elses', function () {
- const str = 'sequenceDiagram\n' +
+ expect(messages.length).toBe(7);
+ expect(messages[0].from).toBe('Alice');
+ expect(messages[1].from).toBe('Bob');
+ });
+ it('it should handle alt statements with multiple elses', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
@@ -474,21 +487,22 @@ describe('when parsing a sequenceDiagram', function () {
'Bob-->Alice: Feel sick...\n' +
'else default\n' +
'Bob-->Alice: :-)\n' +
- 'end'
- parser.parse(str)
- const messages = parser.yy.getMessages()
- expect(messages.length).toBe(9)
- expect(messages[1].from).toBe('Bob')
- expect(messages[2].type).toBe(parser.yy.LINETYPE.ALT_START)
- expect(messages[3].from).toBe('Bob')
- expect(messages[4].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
- expect(messages[5].from).toBe('Bob')
- expect(messages[6].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
- expect(messages[7].from).toBe('Bob')
- expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END)
- })
- it('it should handle par statements a sequenceDiagram', function () {
- const str = 'sequenceDiagram\n' +
+ 'end';
+ parser.parse(str);
+ const messages = parser.yy.getMessages();
+ expect(messages.length).toBe(9);
+ expect(messages[1].from).toBe('Bob');
+ expect(messages[2].type).toBe(parser.yy.LINETYPE.ALT_START);
+ expect(messages[3].from).toBe('Bob');
+ expect(messages[4].type).toBe(parser.yy.LINETYPE.ALT_ELSE);
+ expect(messages[5].from).toBe('Bob');
+ expect(messages[6].type).toBe(parser.yy.LINETYPE.ALT_ELSE);
+ expect(messages[7].from).toBe('Bob');
+ expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END);
+ });
+ it('it should handle par statements a sequenceDiagram', function() {
+ const str =
+ 'sequenceDiagram\n' +
'par Parallel one\n' +
'Alice->>Bob: Hello Bob, how are you?\n' +
'Bob-->>Alice: I am good thanks!\n' +
@@ -497,162 +511,170 @@ describe('when parsing a sequenceDiagram', function () {
'Bob-->>Alice: Fine!\n' +
'and Parallel three\n' +
'Alice->>Bob: What do you think about it?\n' +
- 'Bob-->>Alice: It\'s good!\n' +
- 'end'
+ "Bob-->>Alice: It's good!\n" +
+ 'end';
- parser.parse(str)
- const actors = parser.yy.getActors()
+ parser.parse(str);
+ const actors = parser.yy.getActors();
- expect(actors.Alice.description).toBe('Alice')
- expect(actors.Bob.description).toBe('Bob')
+ expect(actors.Alice.description).toBe('Alice');
+ expect(actors.Bob.description).toBe('Bob');
- const messages = parser.yy.getMessages()
+ const messages = parser.yy.getMessages();
- expect(messages.length).toBe(10)
- expect(messages[0].message).toBe('Parallel one')
- expect(messages[1].from).toBe('Alice')
- expect(messages[2].from).toBe('Bob')
- })
- it('it should handle special characters in signals', function () {
- const str = 'sequenceDiagram\n' +
- 'Alice->Bob: -:<>,;# comment'
+ expect(messages.length).toBe(10);
+ expect(messages[0].message).toBe('Parallel one');
+ expect(messages[1].from).toBe('Alice');
+ expect(messages[2].from).toBe('Bob');
+ });
+ it('it should handle special characters in signals', function() {
+ const str = 'sequenceDiagram\n' + 'Alice->Bob: -:<>,;# comment';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[0].message).toBe('-:<>,')
- })
- it('it should handle special characters in notes', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[0].message).toBe('-:<>,');
+ });
+ it('it should handle special characters in notes', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
- 'Note right of Bob: -:<>,;# comment'
+ 'Note right of Bob: -:<>,;# comment';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('-:<>,')
- })
- it('it should handle special characters in loop', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('-:<>,');
+ });
+ it('it should handle special characters in loop', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('-:<>,')
- })
- it('it should handle special characters in opt', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('-:<>,');
+ });
+ it('it should handle special characters in opt', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('-:<>,')
- })
- it('it should handle special characters in alt', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('-:<>,');
+ });
+ it('it should handle special characters in alt', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'else ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('-:<>,')
- expect(messages[3].message).toBe(',<>:-')
- })
- it('it should handle special characters in par', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('-:<>,');
+ expect(messages[3].message).toBe(',<>:-');
+ });
+ it('it should handle special characters in par', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'and ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('-:<>,')
- expect(messages[3].message).toBe(',<>:-')
- })
- it('it should handle no-label loop', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('-:<>,');
+ expect(messages[3].message).toBe(',<>:-');
+ });
+ it('it should handle no-label loop', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('')
- expect(messages[2].message).toBe('I am good thanks!')
- })
- it('it should handle no-label opt', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('');
+ expect(messages[2].message).toBe('I am good thanks!');
+ });
+ it('it should handle no-label opt', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('')
- expect(messages[2].message).toBe('I am good thanks!')
- })
- it('it should handle no-label alt', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('');
+ expect(messages[2].message).toBe('I am good thanks!');
+ });
+ it('it should handle no-label alt', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt;' +
'Bob-->Alice: I am good thanks!\n' +
'else # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('')
- expect(messages[2].message).toBe('I am good thanks!')
- expect(messages[3].message).toBe('')
- expect(messages[4].message).toBe('I am good thanks!')
- })
- it('it should handle no-label par', function () {
- const str = 'sequenceDiagram\n' +
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('');
+ expect(messages[2].message).toBe('I am good thanks!');
+ expect(messages[3].message).toBe('');
+ expect(messages[4].message).toBe('I am good thanks!');
+ });
+ it('it should handle no-label par', function() {
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par;' +
'Bob-->Alice: I am good thanks!\n' +
'and # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
- 'end'
+ 'end';
- parser.parse(str)
+ parser.parse(str);
- const messages = parser.yy.getMessages()
- expect(messages[1].message).toBe('')
- expect(messages[2].message).toBe('I am good thanks!')
- expect(messages[3].message).toBe('')
- expect(messages[4].message).toBe('I am good thanks!')
- })
-})
+ const messages = parser.yy.getMessages();
+ expect(messages[1].message).toBe('');
+ expect(messages[2].message).toBe('I am good thanks!');
+ expect(messages[3].message).toBe('');
+ expect(messages[4].message).toBe('I am good thanks!');
+ });
+});
-describe('when checking the bounds in a sequenceDiagram', function () {
- let conf
- beforeEach(function () {
- parser.yy = sequenceDb
- parser.yy.clear()
+describe('when checking the bounds in a sequenceDiagram', function() {
+ let conf;
+ beforeEach(function() {
+ parser.yy = sequenceDb;
+ parser.yy.clear();
conf = {
diagramMarginX: 50,
diagramMarginY: 10,
@@ -664,131 +686,131 @@ describe('when checking the bounds in a sequenceDiagram', function () {
messageMargin: 40,
boxTextMargin: 15,
noteMargin: 25
- }
- renderer.setConf(conf)
- })
- it('it should handle a simple bound call', function () {
- renderer.bounds.init()
+ };
+ renderer.setConf(conf);
+ });
+ it('it should handle a simple bound call', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(100, 100, 200, 200)
+ renderer.bounds.insert(100, 100, 200, 200);
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(100)
- expect(bounds.starty).toBe(100)
- expect(bounds.stopx).toBe(200)
- expect(bounds.stopy).toBe(200)
- })
- it('it should handle an expanding bound', function () {
- renderer.bounds.init()
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(100);
+ expect(bounds.starty).toBe(100);
+ expect(bounds.stopx).toBe(200);
+ expect(bounds.stopy).toBe(200);
+ });
+ it('it should handle an expanding bound', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(100, 100, 200, 200)
- renderer.bounds.insert(25, 50, 300, 400)
+ renderer.bounds.insert(100, 100, 200, 200);
+ renderer.bounds.insert(25, 50, 300, 400);
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(25)
- expect(bounds.starty).toBe(50)
- expect(bounds.stopx).toBe(300)
- expect(bounds.stopy).toBe(400)
- })
- it('it should handle inserts within the bound without changing the outer bounds', function () {
- renderer.bounds.init()
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(25);
+ expect(bounds.starty).toBe(50);
+ expect(bounds.stopx).toBe(300);
+ expect(bounds.stopy).toBe(400);
+ });
+ it('it should handle inserts within the bound without changing the outer bounds', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(100, 100, 200, 200)
- renderer.bounds.insert(25, 50, 300, 400)
- renderer.bounds.insert(125, 150, 150, 200)
+ renderer.bounds.insert(100, 100, 200, 200);
+ renderer.bounds.insert(25, 50, 300, 400);
+ renderer.bounds.insert(125, 150, 150, 200);
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(25)
- expect(bounds.starty).toBe(50)
- expect(bounds.stopx).toBe(300)
- expect(bounds.stopy).toBe(400)
- })
- it('it should handle a loop without expanding the area', function () {
- renderer.bounds.init()
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(25);
+ expect(bounds.starty).toBe(50);
+ expect(bounds.stopx).toBe(300);
+ expect(bounds.stopy).toBe(400);
+ });
+ it('it should handle a loop without expanding the area', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(25, 50, 300, 400)
- renderer.bounds.verticalPos = 150
- renderer.bounds.newLoop()
- renderer.bounds.insert(125, 150, 150, 200)
+ renderer.bounds.insert(25, 50, 300, 400);
+ renderer.bounds.verticalPos = 150;
+ renderer.bounds.newLoop();
+ renderer.bounds.insert(125, 150, 150, 200);
- const loop = renderer.bounds.endLoop()
+ const loop = renderer.bounds.endLoop();
- expect(loop.startx).toBe(125 - conf.boxMargin)
- expect(loop.starty).toBe(150 - conf.boxMargin)
- expect(loop.stopx).toBe(150 + conf.boxMargin)
- expect(loop.stopy).toBe(200 + conf.boxMargin)
+ expect(loop.startx).toBe(125 - conf.boxMargin);
+ expect(loop.starty).toBe(150 - conf.boxMargin);
+ expect(loop.stopx).toBe(150 + conf.boxMargin);
+ expect(loop.stopy).toBe(200 + conf.boxMargin);
// Check bounds of first loop
- const bounds = renderer.bounds.getBounds()
+ const bounds = renderer.bounds.getBounds();
- expect(bounds.startx).toBe(25)
- expect(bounds.starty).toBe(50)
- expect(bounds.stopx).toBe(300)
- expect(bounds.stopy).toBe(400)
- })
- it('it should handle multiple loops withtout expanding the bounds', function () {
- renderer.bounds.init()
+ expect(bounds.startx).toBe(25);
+ expect(bounds.starty).toBe(50);
+ expect(bounds.stopx).toBe(300);
+ expect(bounds.stopy).toBe(400);
+ });
+ it('it should handle multiple loops withtout expanding the bounds', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(100, 100, 1000, 1000)
- renderer.bounds.verticalPos = 200
- renderer.bounds.newLoop()
- renderer.bounds.newLoop()
- renderer.bounds.insert(200, 200, 300, 300)
+ renderer.bounds.insert(100, 100, 1000, 1000);
+ renderer.bounds.verticalPos = 200;
+ renderer.bounds.newLoop();
+ renderer.bounds.newLoop();
+ renderer.bounds.insert(200, 200, 300, 300);
// Check bounds of first loop
- let loop = renderer.bounds.endLoop()
+ let loop = renderer.bounds.endLoop();
- expect(loop.startx).toBe(200 - conf.boxMargin)
- expect(loop.starty).toBe(200 - conf.boxMargin)
- expect(loop.stopx).toBe(300 + conf.boxMargin)
- expect(loop.stopy).toBe(300 + conf.boxMargin)
+ expect(loop.startx).toBe(200 - conf.boxMargin);
+ expect(loop.starty).toBe(200 - conf.boxMargin);
+ expect(loop.stopx).toBe(300 + conf.boxMargin);
+ expect(loop.stopy).toBe(300 + conf.boxMargin);
// Check bounds of second loop
- loop = renderer.bounds.endLoop()
+ loop = renderer.bounds.endLoop();
- expect(loop.startx).toBe(200 - 2 * conf.boxMargin)
- expect(loop.starty).toBe(200 - 2 * conf.boxMargin)
- expect(loop.stopx).toBe(300 + 2 * conf.boxMargin)
- expect(loop.stopy).toBe(300 + 2 * conf.boxMargin)
+ expect(loop.startx).toBe(200 - 2 * conf.boxMargin);
+ expect(loop.starty).toBe(200 - 2 * conf.boxMargin);
+ expect(loop.stopx).toBe(300 + 2 * conf.boxMargin);
+ expect(loop.stopy).toBe(300 + 2 * conf.boxMargin);
// Check bounds of first loop
- const bounds = renderer.bounds.getBounds()
+ const bounds = renderer.bounds.getBounds();
- expect(bounds.startx).toBe(100)
- expect(bounds.starty).toBe(100)
- expect(bounds.stopx).toBe(1000)
- expect(bounds.stopy).toBe(1000)
- })
- it('it should handle a loop that expands the area', function () {
- renderer.bounds.init()
+ expect(bounds.startx).toBe(100);
+ expect(bounds.starty).toBe(100);
+ expect(bounds.stopx).toBe(1000);
+ expect(bounds.stopy).toBe(1000);
+ });
+ it('it should handle a loop that expands the area', function() {
+ renderer.bounds.init();
- renderer.bounds.insert(100, 100, 200, 200)
- renderer.bounds.verticalPos = 200
- renderer.bounds.newLoop()
- renderer.bounds.insert(50, 50, 300, 300)
+ renderer.bounds.insert(100, 100, 200, 200);
+ renderer.bounds.verticalPos = 200;
+ renderer.bounds.newLoop();
+ renderer.bounds.insert(50, 50, 300, 300);
- const loop = renderer.bounds.endLoop()
+ const loop = renderer.bounds.endLoop();
- expect(loop.startx).toBe(50 - conf.boxMargin)
- expect(loop.starty).toBe(50 - conf.boxMargin)
- expect(loop.stopx).toBe(300 + conf.boxMargin)
- expect(loop.stopy).toBe(300 + conf.boxMargin)
+ expect(loop.startx).toBe(50 - conf.boxMargin);
+ expect(loop.starty).toBe(50 - conf.boxMargin);
+ expect(loop.stopx).toBe(300 + conf.boxMargin);
+ expect(loop.stopy).toBe(300 + conf.boxMargin);
// Check bounds after the loop
- const bounds = renderer.bounds.getBounds()
+ const bounds = renderer.bounds.getBounds();
- expect(bounds.startx).toBe(loop.startx)
- expect(bounds.starty).toBe(loop.starty)
- expect(bounds.stopx).toBe(loop.stopx)
- expect(bounds.stopy).toBe(loop.stopy)
- })
-})
+ expect(bounds.startx).toBe(loop.startx);
+ expect(bounds.starty).toBe(loop.starty);
+ expect(bounds.stopx).toBe(loop.stopx);
+ expect(bounds.stopy).toBe(loop.stopy);
+ });
+});
-describe('when rendering a sequenceDiagram', function () {
- let conf
- beforeEach(function () {
- parser.yy = sequenceDb
- parser.yy.clear()
+describe('when rendering a sequenceDiagram', function() {
+ let conf;
+ beforeEach(function() {
+ parser.yy = sequenceDb;
+ parser.yy.clear();
conf = {
diagramMarginX: 50,
@@ -801,210 +823,213 @@ describe('when rendering a sequenceDiagram', function () {
messageMargin: 40,
boxTextMargin: 15,
noteMargin: 25
- }
- renderer.setConf(conf)
+ };
+ renderer.setConf(conf);
});
- ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
- it('it should handle one actor, when textPlacement is ' + textPlacement, function () {
- renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'participant Alice'
+ ['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) {
+ it('it should handle one actor, when textPlacement is ' + textPlacement, function() {
+ renderer.setConf(addConf(conf, 'textPlacement', textPlacement));
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'participant Alice';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width)
- expect(bounds.stopy).toBe(conf.height)
- })
- })
- it('it should handle same actor with different whitespace properly', function () {
- renderer.bounds.init()
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width);
+ expect(bounds.stopy).toBe(conf.height);
+ });
+ });
+ it('it should handle same actor with different whitespace properly', function() {
+ renderer.bounds.init();
- const str = 'sequenceDiagram\n' +
+ const str =
+ 'sequenceDiagram\n' +
'participant Alice\n' +
'participant Alice \n' +
- 'participant Alice \n'
+ 'participant Alice \n';
- parser.parse(str)
+ parser.parse(str);
- const actors = parser.yy.getActors()
- expect(Object.keys(actors)).toEqual(['Alice'])
- })
- it('it should handle one actor and a centered note', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'participant Alice\n' +
- 'Note over Alice: Alice thinks\n'
+ const actors = parser.yy.getActors();
+ expect(Object.keys(actors)).toEqual(['Alice']);
+ });
+ it('it should handle one actor and a centered note', function() {
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'participant Alice\n' + 'Note over Alice: Alice thinks\n';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width);
// 10 comes from mock of text height
- expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
- })
- it('it should handle one actor and a note to the left', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'participant Alice\n' +
- 'Note left of Alice: Alice thinks'
+ expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10);
+ });
+ it('it should handle one actor and a note to the left', function() {
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'participant Alice\n' + 'Note left of Alice: Alice thinks';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width);
// 10 comes from mock of text height
- expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
- })
- it('it should handle one actor and a note to the right', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'participant Alice\n' +
- 'Note right of Alice: Alice thinks'
+ expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10);
+ });
+ it('it should handle one actor and a note to the right', function() {
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'participant Alice\n' + 'Note right of Alice: Alice thinks';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe((conf.width / 2) + (conf.actorMargin / 2) + conf.width)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width / 2 + conf.actorMargin / 2 + conf.width);
// 10 comes from mock of text height
- expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
- })
- it('it should handle two actors', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'Alice->Bob: Hello Bob, how are you?'
+ expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10);
+ });
+ it('it should handle two actors', function() {
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(0 + conf.messageMargin + conf.height)
- })
- it('it should handle two actors and two centered shared notes', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(0 + conf.messageMargin + conf.height);
+ });
+ it('it should handle two actors and two centered shared notes', function() {
+ renderer.bounds.init();
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: Looks\n' +
- 'Note over Bob,Alice: Looks back\n'
+ 'Note over Bob,Alice: Looks back\n';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(conf.height + conf.messageMargin + 2 * (conf.boxMargin + 2 * conf.noteMargin + 10))
- })
- it('it should draw two actors and two messages', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'Alice->Bob: Hello Bob, how are you?\n' +
- 'Bob->Alice: Fine!'
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(
+ conf.height + conf.messageMargin + 2 * (conf.boxMargin + 2 * conf.noteMargin + 10)
+ );
+ });
+ it('it should draw two actors and two messages', function() {
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n' + 'Bob->Alice: Fine!';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height)
- })
- it('it should draw two actors notes to the right', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height);
+ });
+ it('it should draw two actors notes to the right', function() {
+ renderer.bounds.init();
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
- 'Bob->Alice: Fine!'
+ 'Bob->Alice: Fine!';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
- const expStopX = conf.actorMargin + conf.width + (conf.width / 2) + conf.noteMargin + conf.width
+ const expStopX = conf.actorMargin + conf.width + conf.width / 2 + conf.noteMargin + conf.width;
- expect(bounds.stopx).toBe(expStopX)
- expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
- })
- it('it should draw two actors notes to the left', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
+ expect(bounds.stopx).toBe(expStopX);
+ expect(bounds.stopy).toBe(
+ 2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin
+ );
+ });
+ it('it should draw two actors notes to the left', function() {
+ renderer.bounds.init();
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note left of Alice: Bob thinks\n' +
- 'Bob->Alice: Fine!'
+ 'Bob->Alice: Fine!';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
- expect(bounds.starty).toBe(0)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2);
+ expect(bounds.starty).toBe(0);
- expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
- })
- it('it should draw two loops', function () {
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
+ expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(
+ 2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin
+ );
+ });
+ it('it should draw two loops', function() {
+ renderer.bounds.init();
+ const str =
+ 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop Cheers\n' +
'Bob->Alice: Fine!\n' +
- 'end'
- parser.parse(str)
- renderer.draw(str, 'tst')
+ 'end';
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
- expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin + conf.boxTextMargin)
- })
- it('it should draw background rect', function () {
- renderer.bounds.init()
+ expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(
+ 0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin + conf.boxTextMargin
+ );
+ });
+ it('it should draw background rect', function() {
+ renderer.bounds.init();
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, are you alright?
rect rgb(0, 0, 0)
Bob->Alice: I feel surrounded by darkness
end
- `
- parser.parse(str)
- renderer.draw(str, 'tst')
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
+ `;
+ parser.parse(str);
+ renderer.draw(str, 'tst');
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
- expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
- expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin)
- })
-})
+ expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin);
+ expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin);
+ });
+});
-describe('when rendering a sequenceDiagram with actor mirror activated', function () {
- let conf
- beforeEach(function () {
- parser.yy = sequenceDb
- parser.yy.clear()
+describe('when rendering a sequenceDiagram with actor mirror activated', function() {
+ let conf;
+ beforeEach(function() {
+ parser.yy = sequenceDb;
+ parser.yy.clear();
conf = {
diagramMarginX: 50,
@@ -1021,24 +1046,23 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
bottomMarginAdj: 1
- }
- renderer.setConf(conf)
+ };
+ renderer.setConf(conf);
});
- ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
- it('it should handle one actor, when textPlacement is' + textPlacement, function () {
- renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
- renderer.bounds.init()
- const str = 'sequenceDiagram\n' +
- 'participant Alice'
+ ['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) {
+ it('it should handle one actor, when textPlacement is' + textPlacement, function() {
+ renderer.setConf(addConf(conf, 'textPlacement', textPlacement));
+ renderer.bounds.init();
+ const str = 'sequenceDiagram\n' + 'participant Alice';
- parser.parse(str)
- renderer.draw(str, 'tst')
+ parser.parse(str);
+ renderer.draw(str, 'tst');
- const bounds = renderer.bounds.getBounds()
- expect(bounds.startx).toBe(0)
- expect(bounds.starty).toBe(0)
- expect(bounds.stopx).toBe(conf.width)
- expect(bounds.stopy).toBe(2 * conf.height + 2 * conf.boxMargin)
- })
- })
-})
+ const bounds = renderer.bounds.getBounds();
+ expect(bounds.startx).toBe(0);
+ expect(bounds.starty).toBe(0);
+ expect(bounds.stopx).toBe(conf.width);
+ expect(bounds.stopy).toBe(2 * conf.height + 2 * conf.boxMargin);
+ });
+ });
+});
diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js
index 4e4b0f74d..6ebd5a52d 100644
--- a/src/diagrams/sequence/sequenceRenderer.js
+++ b/src/diagrams/sequence/sequenceRenderer.js
@@ -1,14 +1,13 @@
-import * as d3 from 'd3'
+import * as d3 from 'd3';
-import svgDraw from './svgDraw'
-import { logger } from '../../logger'
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
+import svgDraw from './svgDraw';
+import { logger } from '../../logger';
+import { parser } from './parser/sequenceDiagram';
+import sequenceDb from './sequenceDb';
-parser.yy = sequenceDb
+parser.yy = sequenceDb;
const conf = {
-
diagramMarginX: 50,
diagramMarginY: 30,
// Margin between actors
@@ -38,7 +37,7 @@ const conf = {
textPlacement: 'tspan',
showSequenceNumbers: false
-}
+};
export const bounds = {
data: {
@@ -51,69 +50,69 @@ export const bounds = {
sequenceItems: [],
activations: [],
- init: function () {
- this.sequenceItems = []
- this.activations = []
+ init: function() {
+ this.sequenceItems = [];
+ this.activations = [];
this.data = {
startx: undefined,
stopx: undefined,
starty: undefined,
stopy: undefined
- }
- this.verticalPos = 0
+ };
+ this.verticalPos = 0;
},
- updateVal: function (obj, key, val, fun) {
+ updateVal: function(obj, key, val, fun) {
if (typeof obj[key] === 'undefined') {
- obj[key] = val
+ obj[key] = val;
} else {
- obj[key] = fun(val, obj[key])
+ obj[key] = fun(val, obj[key]);
}
},
- updateBounds: function (startx, starty, stopx, stopy) {
- const _self = this
- let cnt = 0
- function updateFn (type) {
- return function updateItemBounds (item) {
- cnt++
+ updateBounds: function(startx, starty, stopx, stopy) {
+ const _self = this;
+ let cnt = 0;
+ function updateFn(type) {
+ return function updateItemBounds(item) {
+ cnt++;
// The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
- const n = _self.sequenceItems.length - cnt + 1
+ const n = _self.sequenceItems.length - cnt + 1;
- _self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min)
- _self.updateVal(item, 'stopy', stopy + n * conf.boxMargin, Math.max)
+ _self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min);
+ _self.updateVal(item, 'stopy', stopy + n * conf.boxMargin, Math.max);
- _self.updateVal(bounds.data, 'startx', startx - n * conf.boxMargin, Math.min)
- _self.updateVal(bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max)
+ _self.updateVal(bounds.data, 'startx', startx - n * conf.boxMargin, Math.min);
+ _self.updateVal(bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max);
if (!(type === 'activation')) {
- _self.updateVal(item, 'startx', startx - n * conf.boxMargin, Math.min)
- _self.updateVal(item, 'stopx', stopx + n * conf.boxMargin, Math.max)
+ _self.updateVal(item, 'startx', startx - n * conf.boxMargin, Math.min);
+ _self.updateVal(item, 'stopx', stopx + n * conf.boxMargin, Math.max);
- _self.updateVal(bounds.data, 'starty', starty - n * conf.boxMargin, Math.min)
- _self.updateVal(bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max)
+ _self.updateVal(bounds.data, 'starty', starty - n * conf.boxMargin, Math.min);
+ _self.updateVal(bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max);
}
- }
+ };
}
- this.sequenceItems.forEach(updateFn())
- this.activations.forEach(updateFn('activation'))
+ this.sequenceItems.forEach(updateFn());
+ this.activations.forEach(updateFn('activation'));
},
- insert: function (startx, starty, stopx, stopy) {
- const _startx = Math.min(startx, stopx)
- const _stopx = Math.max(startx, stopx)
- const _starty = Math.min(starty, stopy)
- const _stopy = Math.max(starty, stopy)
+ insert: function(startx, starty, stopx, stopy) {
+ const _startx = Math.min(startx, stopx);
+ const _stopx = Math.max(startx, stopx);
+ const _starty = Math.min(starty, stopy);
+ const _stopy = Math.max(starty, stopy);
- this.updateVal(bounds.data, 'startx', _startx, Math.min)
- this.updateVal(bounds.data, 'starty', _starty, Math.min)
- this.updateVal(bounds.data, 'stopx', _stopx, Math.max)
- this.updateVal(bounds.data, 'stopy', _stopy, Math.max)
+ this.updateVal(bounds.data, 'startx', _startx, Math.min);
+ this.updateVal(bounds.data, 'starty', _starty, Math.min);
+ this.updateVal(bounds.data, 'stopx', _stopx, Math.max);
+ this.updateVal(bounds.data, 'stopy', _stopy, Math.max);
- this.updateBounds(_startx, _starty, _stopx, _stopy)
+ this.updateBounds(_startx, _starty, _stopx, _stopy);
},
- newActivation: function (message, diagram) {
- const actorRect = parser.yy.getActors()[message.from.actor]
- const stackedSize = actorActivations(message.from.actor).length
- const x = actorRect.x + conf.width / 2 + (stackedSize - 1) * conf.activationWidth / 2
+ newActivation: function(message, diagram) {
+ const actorRect = parser.yy.getActors()[message.from.actor];
+ const stackedSize = actorActivations(message.from.actor).length;
+ const x = actorRect.x + conf.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
this.activations.push({
startx: x,
starty: this.verticalPos + 2,
@@ -121,59 +120,68 @@ export const bounds = {
stopy: undefined,
actor: message.from.actor,
anchored: svgDraw.anchorElement(diagram)
- })
+ });
},
- endActivation: function (message) {
+ endActivation: function(message) {
// find most recent activation for given actor
const lastActorActivationIdx = this.activations
- .map(function (activation) { return activation.actor })
- .lastIndexOf(message.from.actor)
- const activation = this.activations.splice(lastActorActivationIdx, 1)[0]
- return activation
+ .map(function(activation) {
+ return activation.actor;
+ })
+ .lastIndexOf(message.from.actor);
+ const activation = this.activations.splice(lastActorActivationIdx, 1)[0];
+ return activation;
},
- newLoop: function (title, fill) {
- this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title, fill: fill })
+ newLoop: function(title, fill) {
+ this.sequenceItems.push({
+ startx: undefined,
+ starty: this.verticalPos,
+ stopx: undefined,
+ stopy: undefined,
+ title: title,
+ fill: fill
+ });
},
- endLoop: function () {
- const loop = this.sequenceItems.pop()
- return loop
+ endLoop: function() {
+ const loop = this.sequenceItems.pop();
+ return loop;
},
- addSectionToLoop: function (message) {
- const loop = this.sequenceItems.pop()
- loop.sections = loop.sections || []
- loop.sectionTitles = loop.sectionTitles || []
- loop.sections.push(bounds.getVerticalPos())
- loop.sectionTitles.push(message)
- this.sequenceItems.push(loop)
+ addSectionToLoop: function(message) {
+ const loop = this.sequenceItems.pop();
+ loop.sections = loop.sections || [];
+ loop.sectionTitles = loop.sectionTitles || [];
+ loop.sections.push(bounds.getVerticalPos());
+ loop.sectionTitles.push(message);
+ this.sequenceItems.push(loop);
},
- bumpVerticalPos: function (bump) {
- this.verticalPos = this.verticalPos + bump
- this.data.stopy = this.verticalPos
+ bumpVerticalPos: function(bump) {
+ this.verticalPos = this.verticalPos + bump;
+ this.data.stopy = this.verticalPos;
},
- getVerticalPos: function () {
- return this.verticalPos
+ getVerticalPos: function() {
+ return this.verticalPos;
},
- getBounds: function () {
- return this.data
+ getBounds: function() {
+ return this.data;
}
-}
+};
const _drawLongText = (text, x, y, g, width) => {
- let textHeight = 0
- const lines = text.split(/
/ig)
+ let textHeight = 0;
+ const lines = text.split(/
/gi);
for (const line of lines) {
- const textObj = svgDraw.getTextObj()
- textObj.x = x
- textObj.y = y + textHeight
- textObj.textMargin = conf.noteMargin
- textObj.dy = '1em'
- textObj.text = line
- textObj.class = 'noteText'
- const textElem = svgDraw.drawText(g, textObj, width)
- textHeight += (textElem._groups || textElem)[0][0].getBBox().height
+ const textObj = svgDraw.getTextObj();
+ textObj.x = x;
+ textObj.y = y + textHeight;
+ textObj.textMargin = conf.noteMargin;
+ textObj.dy = '1em';
+ textObj.text = line;
+ textObj.class = 'noteText';
+ const textElem = svgDraw.drawText(g, textObj, width);
+ textHeight += (textElem._groups || textElem)[0][0].getBBox().height;
}
- return textHeight
-}
+ return textHeight;
+};
/**
* Draws an actor in the diagram with the attaced line
@@ -181,22 +189,33 @@ const _drawLongText = (text, x, y, g, width) => {
* @param pos The position if the actor in the liost of actors
* @param description The text in the box
*/
-const drawNote = function (elem, startx, verticalPos, msg, forceWidth) {
- const rect = svgDraw.getNoteRect()
- rect.x = startx
- rect.y = verticalPos
- rect.width = forceWidth || conf.width
- rect.class = 'note'
+const drawNote = function(elem, startx, verticalPos, msg, forceWidth) {
+ const rect = svgDraw.getNoteRect();
+ rect.x = startx;
+ rect.y = verticalPos;
+ rect.width = forceWidth || conf.width;
+ rect.class = 'note';
- let g = elem.append('g')
- const rectElem = svgDraw.drawRect(g, rect)
+ let g = elem.append('g');
+ const rectElem = svgDraw.drawRect(g, rect);
- const textHeight = _drawLongText(msg.message, startx - 4, verticalPos + 24, g, rect.width - conf.noteMargin)
+ const textHeight = _drawLongText(
+ msg.message,
+ startx - 4,
+ verticalPos + 24,
+ g,
+ rect.width - conf.noteMargin
+ );
- bounds.insert(startx, verticalPos, startx + rect.width, verticalPos + 2 * conf.noteMargin + textHeight)
- rectElem.attr('height', textHeight + 2 * conf.noteMargin)
- bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin)
-}
+ bounds.insert(
+ startx,
+ verticalPos,
+ startx + rect.width,
+ verticalPos + 2 * conf.noteMargin + textHeight
+ );
+ rectElem.attr('height', textHeight + 2 * conf.noteMargin);
+ bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin);
+};
/**
* Draws a message
@@ -207,70 +226,104 @@ const drawNote = function (elem, startx, verticalPos, msg, forceWidth) {
* @param txtCenter
* @param msg
*/
-const drawMessage = function (elem, startx, stopx, verticalPos, msg, sequenceIndex) {
- const g = elem.append('g')
- const txtCenter = startx + (stopx - startx) / 2
+const drawMessage = function(elem, startx, stopx, verticalPos, msg, sequenceIndex) {
+ const g = elem.append('g');
+ const txtCenter = startx + (stopx - startx) / 2;
- const textElem = g.append('text') // text label for the x axis
+ const textElem = g
+ .append('text') // text label for the x axis
.attr('x', txtCenter)
.attr('y', verticalPos - 7)
.style('text-anchor', 'middle')
.attr('class', 'messageText')
- .text(msg.message)
+ .text(msg.message);
- let textWidth = (textElem._groups || textElem)[0][0].getBBox().width
+ let textWidth = (textElem._groups || textElem)[0][0].getBBox().width;
- let line
+ let line;
if (startx === stopx) {
if (conf.rightAngles) {
- line = g.append('path').attr('d', `M ${startx},${verticalPos} H ${startx + (conf.width / 2)} V ${verticalPos + 25} H ${startx}`)
+ line = g
+ .append('path')
+ .attr(
+ 'd',
+ `M ${startx},${verticalPos} H ${startx + conf.width / 2} V ${verticalPos +
+ 25} H ${startx}`
+ );
} else {
- line = g.append('path')
- .attr('d', 'M ' + startx + ',' + verticalPos + ' C ' + (startx + 60) + ',' + (verticalPos - 10) + ' ' + (startx + 60) + ',' +
- (verticalPos + 30) + ' ' + startx + ',' + (verticalPos + 20))
+ line = g
+ .append('path')
+ .attr(
+ 'd',
+ 'M ' +
+ startx +
+ ',' +
+ verticalPos +
+ ' C ' +
+ (startx + 60) +
+ ',' +
+ (verticalPos - 10) +
+ ' ' +
+ (startx + 60) +
+ ',' +
+ (verticalPos + 30) +
+ ' ' +
+ startx +
+ ',' +
+ (verticalPos + 20)
+ );
}
- bounds.bumpVerticalPos(30)
- const dx = Math.max(textWidth / 2, 100)
- bounds.insert(startx - dx, bounds.getVerticalPos() - 10, stopx + dx, bounds.getVerticalPos())
+ bounds.bumpVerticalPos(30);
+ const dx = Math.max(textWidth / 2, 100);
+ bounds.insert(startx - dx, bounds.getVerticalPos() - 10, stopx + dx, bounds.getVerticalPos());
} else {
- line = g.append('line')
- line.attr('x1', startx)
- line.attr('y1', verticalPos)
- line.attr('x2', stopx)
- line.attr('y2', verticalPos)
- bounds.insert(startx, bounds.getVerticalPos() - 10, stopx, bounds.getVerticalPos())
+ line = g.append('line');
+ line.attr('x1', startx);
+ line.attr('y1', verticalPos);
+ line.attr('x2', stopx);
+ line.attr('y2', verticalPos);
+ bounds.insert(startx, bounds.getVerticalPos() - 10, stopx, bounds.getVerticalPos());
}
// Make an SVG Container
// Draw the line
- if (msg.type === parser.yy.LINETYPE.DOTTED || msg.type === parser.yy.LINETYPE.DOTTED_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_OPEN) {
- line.style('stroke-dasharray', ('3, 3'))
- line.attr('class', 'messageLine1')
+ if (
+ msg.type === parser.yy.LINETYPE.DOTTED ||
+ msg.type === parser.yy.LINETYPE.DOTTED_CROSS ||
+ msg.type === parser.yy.LINETYPE.DOTTED_OPEN
+ ) {
+ line.style('stroke-dasharray', '3, 3');
+ line.attr('class', 'messageLine1');
} else {
- line.attr('class', 'messageLine0')
+ line.attr('class', 'messageLine0');
}
- let url = ''
+ let url = '';
if (conf.arrowMarkerAbsolute) {
- url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
- url = url.replace(/\(/g, '\\(')
- url = url.replace(/\)/g, '\\)')
+ url =
+ window.location.protocol +
+ '//' +
+ window.location.host +
+ window.location.pathname +
+ window.location.search;
+ url = url.replace(/\(/g, '\\(');
+ url = url.replace(/\)/g, '\\)');
}
- line.attr('stroke-width', 2)
- line.attr('stroke', 'black')
- line.style('fill', 'none') // remove any fill colour
+ line.attr('stroke-width', 2);
+ line.attr('stroke', 'black');
+ line.style('fill', 'none'); // remove any fill colour
if (msg.type === parser.yy.LINETYPE.SOLID || msg.type === parser.yy.LINETYPE.DOTTED) {
- line.attr('marker-end', 'url(' + url + '#arrowhead)')
+ line.attr('marker-end', 'url(' + url + '#arrowhead)');
}
if (msg.type === parser.yy.LINETYPE.SOLID_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_CROSS) {
- line.attr('marker-end', 'url(' + url + '#crosshead)')
+ line.attr('marker-end', 'url(' + url + '#crosshead)');
}
// add node number
if (conf.showSequenceNumbers) {
- line.attr('marker-start', 'url(' + url + '#sequencenumber)')
+ line.attr('marker-start', 'url(' + url + '#sequencenumber)');
g.append('text')
.attr('x', startx)
.attr('y', verticalPos + 4)
@@ -279,263 +332,306 @@ const drawMessage = function (elem, startx, stopx, verticalPos, msg, sequenceInd
.attr('text-anchor', 'middle')
.attr('textLength', '16px')
.attr('class', 'sequenceNumber')
- .text(sequenceIndex)
+ .text(sequenceIndex);
}
-}
+};
-export const drawActors = function (diagram, actors, actorKeys, verticalPos) {
+export const drawActors = function(diagram, actors, actorKeys, verticalPos) {
// Draw the actors
for (let i = 0; i < actorKeys.length; i++) {
- const key = actorKeys[i]
+ const key = actorKeys[i];
// Add some rendering data to the object
- actors[key].x = i * conf.actorMargin + i * conf.width
- actors[key].y = verticalPos
- actors[key].width = conf.diagramMarginX
- actors[key].height = conf.diagramMarginY
+ actors[key].x = i * conf.actorMargin + i * conf.width;
+ actors[key].y = verticalPos;
+ actors[key].width = conf.diagramMarginX;
+ actors[key].height = conf.diagramMarginY;
// Draw the box with the attached line
- svgDraw.drawActor(diagram, actors[key].x, verticalPos, actors[key].description, conf)
- bounds.insert(actors[key].x, verticalPos, actors[key].x + conf.width, conf.height)
+ svgDraw.drawActor(diagram, actors[key].x, verticalPos, actors[key].description, conf);
+ bounds.insert(actors[key].x, verticalPos, actors[key].x + conf.width, conf.height);
}
// Add a margin between the actor boxes and the first arrow
- bounds.bumpVerticalPos(conf.height)
-}
+ bounds.bumpVerticalPos(conf.height);
+};
-export const setConf = function (cnf) {
- const keys = Object.keys(cnf)
+export const setConf = function(cnf) {
+ const keys = Object.keys(cnf);
- keys.forEach(function (key) {
- conf[key] = cnf[key]
- })
-}
+ keys.forEach(function(key) {
+ conf[key] = cnf[key];
+ });
+};
-const actorActivations = function (actor) {
- return bounds.activations.filter(function (activation) {
- return activation.actor === actor
- })
-}
+const actorActivations = function(actor) {
+ return bounds.activations.filter(function(activation) {
+ return activation.actor === actor;
+ });
+};
-const actorFlowVerticaBounds = function (actor) {
+const actorFlowVerticaBounds = function(actor) {
// handle multiple stacked activations for same actor
- const actors = parser.yy.getActors()
- const activations = actorActivations(actor)
+ const actors = parser.yy.getActors();
+ const activations = actorActivations(actor);
- const left = activations.reduce(function (acc, activation) { return Math.min(acc, activation.startx) }, actors[actor].x + conf.width / 2)
- const right = activations.reduce(function (acc, activation) { return Math.max(acc, activation.stopx) }, actors[actor].x + conf.width / 2)
- return [left, right]
-}
+ const left = activations.reduce(function(acc, activation) {
+ return Math.min(acc, activation.startx);
+ }, actors[actor].x + conf.width / 2);
+ const right = activations.reduce(function(acc, activation) {
+ return Math.max(acc, activation.stopx);
+ }, actors[actor].x + conf.width / 2);
+ return [left, right];
+};
/**
* Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text
* @param id
*/
-export const draw = function (text, id) {
- parser.yy.clear()
- parser.parse(text + '\n')
+export const draw = function(text, id) {
+ parser.yy.clear();
+ parser.parse(text + '\n');
- bounds.init()
- const diagram = d3.select(`[id="${id}"]`)
+ bounds.init();
+ const diagram = d3.select(`[id="${id}"]`);
- let startx
- let stopx
- let forceWidth
+ let startx;
+ let stopx;
+ let forceWidth;
// Fetch data from the parsing
- const actors = parser.yy.getActors()
- const actorKeys = parser.yy.getActorKeys()
- const messages = parser.yy.getMessages()
- const title = parser.yy.getTitle()
- drawActors(diagram, actors, actorKeys, 0)
+ const actors = parser.yy.getActors();
+ const actorKeys = parser.yy.getActorKeys();
+ const messages = parser.yy.getMessages();
+ const title = parser.yy.getTitle();
+ drawActors(diagram, actors, actorKeys, 0);
// The arrow head definition is attached to the svg once
- svgDraw.insertArrowHead(diagram)
- svgDraw.insertArrowCrossHead(diagram)
- svgDraw.insertSequenceNumber(diagram)
+ svgDraw.insertArrowHead(diagram);
+ svgDraw.insertArrowCrossHead(diagram);
+ svgDraw.insertSequenceNumber(diagram);
- function activeEnd (msg, verticalPos) {
- const activationData = bounds.endActivation(msg)
+ function activeEnd(msg, verticalPos) {
+ const activationData = bounds.endActivation(msg);
if (activationData.starty + 18 > verticalPos) {
- activationData.starty = verticalPos - 6
- verticalPos += 12
+ activationData.starty = verticalPos - 6;
+ verticalPos += 12;
}
- svgDraw.drawActivation(diagram, activationData, verticalPos, conf, actorActivations(msg.from.actor).length)
+ svgDraw.drawActivation(
+ diagram,
+ activationData,
+ verticalPos,
+ conf,
+ actorActivations(msg.from.actor).length
+ );
- bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos)
+ bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos);
}
// const lastMsg
// Draw the messages/signals
- let sequenceIndex = 1
- messages.forEach(function (msg) {
- let loopData
+ let sequenceIndex = 1;
+ messages.forEach(function(msg) {
+ let loopData;
switch (msg.type) {
case parser.yy.LINETYPE.NOTE:
- bounds.bumpVerticalPos(conf.boxMargin)
+ bounds.bumpVerticalPos(conf.boxMargin);
- startx = actors[msg.from].x
- stopx = actors[msg.to].x
+ startx = actors[msg.from].x;
+ stopx = actors[msg.to].x;
if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) {
- drawNote(diagram, startx + (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
+ drawNote(
+ diagram,
+ startx + (conf.width + conf.actorMargin) / 2,
+ bounds.getVerticalPos(),
+ msg
+ );
} else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
- drawNote(diagram, startx - (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
+ drawNote(
+ diagram,
+ startx - (conf.width + conf.actorMargin) / 2,
+ bounds.getVerticalPos(),
+ msg
+ );
} else if (msg.to === msg.from) {
// Single-actor over
- drawNote(diagram, startx, bounds.getVerticalPos(), msg)
+ drawNote(diagram, startx, bounds.getVerticalPos(), msg);
} else {
// Multi-actor over
- forceWidth = Math.abs(startx - stopx) + conf.actorMargin
- drawNote(diagram, (startx + stopx + conf.width - forceWidth) / 2, bounds.getVerticalPos(), msg,
- forceWidth)
+ forceWidth = Math.abs(startx - stopx) + conf.actorMargin;
+ drawNote(
+ diagram,
+ (startx + stopx + conf.width - forceWidth) / 2,
+ bounds.getVerticalPos(),
+ msg,
+ forceWidth
+ );
}
- break
+ break;
case parser.yy.LINETYPE.ACTIVE_START:
- bounds.newActivation(msg, diagram)
- break
+ bounds.newActivation(msg, diagram);
+ break;
case parser.yy.LINETYPE.ACTIVE_END:
- activeEnd(msg, bounds.getVerticalPos())
- break
+ activeEnd(msg, bounds.getVerticalPos());
+ break;
case parser.yy.LINETYPE.LOOP_START:
- bounds.bumpVerticalPos(conf.boxMargin)
- bounds.newLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ bounds.newLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
+ break;
case parser.yy.LINETYPE.LOOP_END:
- loopData = bounds.endLoop()
+ loopData = bounds.endLoop();
- svgDraw.drawLoop(diagram, loopData, 'loop', conf)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ svgDraw.drawLoop(diagram, loopData, 'loop', conf);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.RECT_START:
- bounds.bumpVerticalPos(conf.boxMargin)
- bounds.newLoop(undefined, msg.message)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ bounds.newLoop(undefined, msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.RECT_END:
- const rectData = bounds.endLoop()
- svgDraw.drawBackgroundRect(diagram, rectData)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ const rectData = bounds.endLoop();
+ svgDraw.drawBackgroundRect(diagram, rectData);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.OPT_START:
- bounds.bumpVerticalPos(conf.boxMargin)
- bounds.newLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ bounds.newLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
+ break;
case parser.yy.LINETYPE.OPT_END:
- loopData = bounds.endLoop()
+ loopData = bounds.endLoop();
- svgDraw.drawLoop(diagram, loopData, 'opt', conf)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ svgDraw.drawLoop(diagram, loopData, 'opt', conf);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.ALT_START:
- bounds.bumpVerticalPos(conf.boxMargin)
- bounds.newLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ bounds.newLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
+ break;
case parser.yy.LINETYPE.ALT_ELSE:
- bounds.bumpVerticalPos(conf.boxMargin)
- loopData = bounds.addSectionToLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ loopData = bounds.addSectionToLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.ALT_END:
- loopData = bounds.endLoop()
+ loopData = bounds.endLoop();
- svgDraw.drawLoop(diagram, loopData, 'alt', conf)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ svgDraw.drawLoop(diagram, loopData, 'alt', conf);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.PAR_START:
- bounds.bumpVerticalPos(conf.boxMargin)
- bounds.newLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ bounds.newLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
+ break;
case parser.yy.LINETYPE.PAR_AND:
- bounds.bumpVerticalPos(conf.boxMargin)
- loopData = bounds.addSectionToLoop(msg.message)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ bounds.bumpVerticalPos(conf.boxMargin);
+ loopData = bounds.addSectionToLoop(msg.message);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
case parser.yy.LINETYPE.PAR_END:
- loopData = bounds.endLoop()
- svgDraw.drawLoop(diagram, loopData, 'par', conf)
- bounds.bumpVerticalPos(conf.boxMargin)
- break
+ loopData = bounds.endLoop();
+ svgDraw.drawLoop(diagram, loopData, 'par', conf);
+ bounds.bumpVerticalPos(conf.boxMargin);
+ break;
default:
try {
// lastMsg = msg
- bounds.bumpVerticalPos(conf.messageMargin)
- const fromBounds = actorFlowVerticaBounds(msg.from)
- const toBounds = actorFlowVerticaBounds(msg.to)
- const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0
- const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1
- startx = fromBounds[fromIdx]
- stopx = toBounds[toIdx]
+ bounds.bumpVerticalPos(conf.messageMargin);
+ const fromBounds = actorFlowVerticaBounds(msg.from);
+ const toBounds = actorFlowVerticaBounds(msg.to);
+ const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0;
+ const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1;
+ startx = fromBounds[fromIdx];
+ stopx = toBounds[toIdx];
- const verticalPos = bounds.getVerticalPos()
- drawMessage(diagram, startx, stopx, verticalPos, msg, sequenceIndex)
- const allBounds = fromBounds.concat(toBounds)
- bounds.insert(Math.min.apply(null, allBounds), verticalPos, Math.max.apply(null, allBounds), verticalPos)
+ const verticalPos = bounds.getVerticalPos();
+ drawMessage(diagram, startx, stopx, verticalPos, msg, sequenceIndex);
+ const allBounds = fromBounds.concat(toBounds);
+ bounds.insert(
+ Math.min.apply(null, allBounds),
+ verticalPos,
+ Math.max.apply(null, allBounds),
+ verticalPos
+ );
} catch (e) {
- logger.error('error while drawing message', e)
+ logger.error('error while drawing message', e);
}
}
// Increment sequence counter if msg.type is a line (and not another event like activation or note, etc)
- if ([
- parser.yy.LINETYPE.SOLID_OPEN,
- parser.yy.LINETYPE.DOTTED_OPEN,
- parser.yy.LINETYPE.SOLID,
- parser.yy.LINETYPE.DOTTED,
- parser.yy.LINETYPE.SOLID_CROSS,
- parser.yy.LINETYPE.DOTTED_CROSS
- ].includes(msg.type)) {
- sequenceIndex++
+ if (
+ [
+ parser.yy.LINETYPE.SOLID_OPEN,
+ parser.yy.LINETYPE.DOTTED_OPEN,
+ parser.yy.LINETYPE.SOLID,
+ parser.yy.LINETYPE.DOTTED,
+ parser.yy.LINETYPE.SOLID_CROSS,
+ parser.yy.LINETYPE.DOTTED_CROSS
+ ].includes(msg.type)
+ ) {
+ sequenceIndex++;
}
- })
+ });
if (conf.mirrorActors) {
// Draw actors below diagram
- bounds.bumpVerticalPos(conf.boxMargin * 2)
- drawActors(diagram, actors, actorKeys, bounds.getVerticalPos())
+ bounds.bumpVerticalPos(conf.boxMargin * 2);
+ drawActors(diagram, actors, actorKeys, bounds.getVerticalPos());
}
- const box = bounds.getBounds()
+ const box = bounds.getBounds();
// Adjust line height of actor lines now that the height of the diagram is known
- logger.debug('For line height fix Querying: #' + id + ' .actor-line')
- const actorLines = d3.selectAll('#' + id + ' .actor-line')
- actorLines.attr('y2', box.stopy)
+ logger.debug('For line height fix Querying: #' + id + ' .actor-line');
+ const actorLines = d3.selectAll('#' + id + ' .actor-line');
+ actorLines.attr('y2', box.stopy);
- let height = box.stopy - box.starty + 2 * conf.diagramMarginY
+ let height = box.stopy - box.starty + 2 * conf.diagramMarginY;
if (conf.mirrorActors) {
- height = height - conf.boxMargin + conf.bottomMarginAdj
+ height = height - conf.boxMargin + conf.bottomMarginAdj;
}
- const width = (box.stopx - box.startx) + (2 * conf.diagramMarginX)
+ const width = box.stopx - box.startx + 2 * conf.diagramMarginX;
if (title) {
- diagram.append('text')
+ diagram
+ .append('text')
.text(title)
- .attr('x', ((box.stopx - box.startx) / 2) - (2 * conf.diagramMarginX))
- .attr('y', -25)
+ .attr('x', (box.stopx - box.startx) / 2 - 2 * conf.diagramMarginX)
+ .attr('y', -25);
}
if (conf.useMaxWidth) {
- diagram.attr('height', '100%')
- diagram.attr('width', '100%')
- diagram.attr('style', 'max-width:' + (width) + 'px;')
+ diagram.attr('height', '100%');
+ diagram.attr('width', '100%');
+ diagram.attr('style', 'max-width:' + width + 'px;');
} else {
- diagram.attr('height', height)
- diagram.attr('width', width)
+ diagram.attr('height', height);
+ diagram.attr('width', width);
}
- const extraVertForTitle = title ? 40 : 0
- diagram.attr('viewBox', (box.startx - conf.diagramMarginX) + ' -' + (conf.diagramMarginY + extraVertForTitle) + ' ' + width + ' ' + (height + extraVertForTitle))
-}
+ const extraVertForTitle = title ? 40 : 0;
+ diagram.attr(
+ 'viewBox',
+ box.startx -
+ conf.diagramMarginX +
+ ' -' +
+ (conf.diagramMarginY + extraVertForTitle) +
+ ' ' +
+ width +
+ ' ' +
+ (height + extraVertForTitle)
+ );
+};
export default {
bounds,
drawActors,
setConf,
draw
-}
+};
diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js
index c33e470cc..4658f174f 100644
--- a/src/diagrams/sequence/svgDraw.js
+++ b/src/diagrams/sequence/svgDraw.js
@@ -1,71 +1,87 @@
-export const drawRect = function (elem, rectData) {
- const rectElem = elem.append('rect')
- rectElem.attr('x', rectData.x)
- rectElem.attr('y', rectData.y)
- rectElem.attr('fill', rectData.fill)
- rectElem.attr('stroke', rectData.stroke)
- rectElem.attr('width', rectData.width)
- rectElem.attr('height', rectData.height)
- rectElem.attr('rx', rectData.rx)
- rectElem.attr('ry', rectData.ry)
+export const drawRect = function(elem, rectData) {
+ const rectElem = elem.append('rect');
+ rectElem.attr('x', rectData.x);
+ rectElem.attr('y', rectData.y);
+ rectElem.attr('fill', rectData.fill);
+ rectElem.attr('stroke', rectData.stroke);
+ rectElem.attr('width', rectData.width);
+ rectElem.attr('height', rectData.height);
+ rectElem.attr('rx', rectData.rx);
+ rectElem.attr('ry', rectData.ry);
if (typeof rectData.class !== 'undefined') {
- rectElem.attr('class', rectData.class)
+ rectElem.attr('class', rectData.class);
}
- return rectElem
-}
+ return rectElem;
+};
-export const drawText = function (elem, textData, width) {
+export const drawText = function(elem, textData, width) {
// Remove and ignore br:s
- const nText = textData.text.replace(/
/ig, ' ')
+ const nText = textData.text.replace(/
/gi, ' ');
- const textElem = elem.append('text')
- textElem.attr('x', textData.x)
- textElem.attr('y', textData.y)
- textElem.style('text-anchor', textData.anchor)
- textElem.attr('fill', textData.fill)
+ const textElem = elem.append('text');
+ textElem.attr('x', textData.x);
+ textElem.attr('y', textData.y);
+ textElem.style('text-anchor', textData.anchor);
+ textElem.attr('fill', textData.fill);
if (typeof textData.class !== 'undefined') {
- textElem.attr('class', textData.class)
+ textElem.attr('class', textData.class);
}
- const span = textElem.append('tspan')
- span.attr('x', textData.x + textData.textMargin * 2)
- span.attr('fill', textData.fill)
- span.text(nText)
+ const span = textElem.append('tspan');
+ span.attr('x', textData.x + textData.textMargin * 2);
+ span.attr('fill', textData.fill);
+ span.text(nText);
- return textElem
-}
+ return textElem;
+};
-export const drawLabel = function (elem, txtObject) {
- function genPoints (x, y, width, height, cut) {
- return x + ',' + y + ' ' +
- (x + width) + ',' + y + ' ' +
- (x + width) + ',' + (y + height - cut) + ' ' +
- (x + width - cut * 1.2) + ',' + (y + height) + ' ' +
- (x) + ',' + (y + height)
+export const drawLabel = function(elem, txtObject) {
+ function genPoints(x, y, width, height, cut) {
+ return (
+ x +
+ ',' +
+ y +
+ ' ' +
+ (x + width) +
+ ',' +
+ y +
+ ' ' +
+ (x + width) +
+ ',' +
+ (y + height - cut) +
+ ' ' +
+ (x + width - cut * 1.2) +
+ ',' +
+ (y + height) +
+ ' ' +
+ x +
+ ',' +
+ (y + height)
+ );
}
- const polygon = elem.append('polygon')
- polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7))
- polygon.attr('class', 'labelBox')
+ const polygon = elem.append('polygon');
+ polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7));
+ polygon.attr('class', 'labelBox');
- txtObject.y = txtObject.y + txtObject.labelMargin
- txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin
- drawText(elem, txtObject)
-}
+ txtObject.y = txtObject.y + txtObject.labelMargin;
+ txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;
+ drawText(elem, txtObject);
+};
-let actorCnt = -1
+let actorCnt = -1;
/**
* Draws an actor in the diagram with the attaced line
* @param center - The center of the the actor
* @param pos The position if the actor in the liost of actors
* @param description The text in the box
*/
-export const drawActor = function (elem, left, verticalPos, description, conf) {
- const center = left + (conf.width / 2)
- const g = elem.append('g')
+export const drawActor = function(elem, left, verticalPos, description, conf) {
+ const center = left + conf.width / 2;
+ const g = elem.append('g');
if (verticalPos === 0) {
- actorCnt++
+ actorCnt++;
g.append('line')
.attr('id', 'actor' + actorCnt)
.attr('x1', center)
@@ -74,43 +90,51 @@ export const drawActor = function (elem, left, verticalPos, description, conf) {
.attr('y2', 2000)
.attr('class', 'actor-line')
.attr('stroke-width', '0.5px')
- .attr('stroke', '#999')
+ .attr('stroke', '#999');
}
- const rect = getNoteRect()
- rect.x = left
- rect.y = verticalPos
- rect.fill = '#eaeaea'
- rect.width = conf.width
- rect.height = conf.height
- rect.class = 'actor'
- rect.rx = 3
- rect.ry = 3
- drawRect(g, rect)
+ const rect = getNoteRect();
+ rect.x = left;
+ rect.y = verticalPos;
+ rect.fill = '#eaeaea';
+ rect.width = conf.width;
+ rect.height = conf.height;
+ rect.class = 'actor';
+ rect.rx = 3;
+ rect.ry = 3;
+ drawRect(g, rect);
- _drawTextCandidateFunc(conf)(description, g,
- rect.x, rect.y, rect.width, rect.height, { 'class': 'actor' }, conf)
-}
+ _drawTextCandidateFunc(conf)(
+ description,
+ g,
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height,
+ { class: 'actor' },
+ conf
+ );
+};
-export const anchorElement = function (elem) {
- return elem.append('g')
-}
+export const anchorElement = function(elem) {
+ return elem.append('g');
+};
/**
* Draws an actor in the diagram with the attaced line
* @param elem - element to append activation rect
* @param bounds - activation box bounds
* @param verticalPos - precise y cooridnate of bottom activation box edge
*/
-export const drawActivation = function (elem, bounds, verticalPos, conf, actorActivations) {
- const rect = getNoteRect()
- const g = bounds.anchored
- rect.x = bounds.startx
- rect.y = bounds.starty
- rect.class = 'activation' + (actorActivations % 3) // Will evaluate to 0, 1 or 2
- rect.width = bounds.stopx - bounds.startx
- rect.height = verticalPos - bounds.starty
- drawRect(g, rect)
-}
+export const drawActivation = function(elem, bounds, verticalPos, conf, actorActivations) {
+ const rect = getNoteRect();
+ const g = bounds.anchored;
+ rect.x = bounds.startx;
+ rect.y = bounds.starty;
+ rect.class = 'activation' + (actorActivations % 3); // Will evaluate to 0, 1 or 2
+ rect.width = bounds.stopx - bounds.startx;
+ rect.height = verticalPos - bounds.starty;
+ drawRect(g, rect);
+};
/**
* Draws an actor in the diagram with the attaced line
@@ -118,60 +142,61 @@ export const drawActivation = function (elem, bounds, verticalPos, conf, actorAc
* @param pos The position if the actor in the list of actors
* @param description The text in the box
*/
-export const drawLoop = function (elem, bounds, labelText, conf) {
- const g = elem.append('g')
- const drawLoopLine = function (startx, starty, stopx, stopy) {
- return g.append('line')
+export const drawLoop = function(elem, bounds, labelText, conf) {
+ const g = elem.append('g');
+ const drawLoopLine = function(startx, starty, stopx, stopy) {
+ return g
+ .append('line')
.attr('x1', startx)
.attr('y1', starty)
.attr('x2', stopx)
.attr('y2', stopy)
- .attr('class', 'loopLine')
- }
- drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty)
- drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy)
- drawLoopLine(bounds.startx, bounds.stopy, bounds.stopx, bounds.stopy)
- drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy)
+ .attr('class', 'loopLine');
+ };
+ drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty);
+ drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy);
+ drawLoopLine(bounds.startx, bounds.stopy, bounds.stopx, bounds.stopy);
+ drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy);
if (typeof bounds.sections !== 'undefined') {
- bounds.sections.forEach(function (item) {
- drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3')
- })
+ bounds.sections.forEach(function(item) {
+ drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3');
+ });
}
- let txt = getTextObj()
- txt.text = labelText
- txt.x = bounds.startx
- txt.y = bounds.starty
- txt.labelMargin = 1.5 * 10 // This is the small box that says "loop"
- txt.class = 'labelText' // Its size & position are fixed.
+ let txt = getTextObj();
+ txt.text = labelText;
+ txt.x = bounds.startx;
+ txt.y = bounds.starty;
+ txt.labelMargin = 1.5 * 10; // This is the small box that says "loop"
+ txt.class = 'labelText'; // Its size & position are fixed.
- drawLabel(g, txt)
+ drawLabel(g, txt);
- txt = getTextObj()
- txt.text = '[ ' + bounds.title + ' ]'
- txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2
- txt.y = bounds.starty + 1.5 * conf.boxMargin
- txt.anchor = 'middle'
- txt.class = 'loopText'
+ txt = getTextObj();
+ txt.text = '[ ' + bounds.title + ' ]';
+ txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2;
+ txt.y = bounds.starty + 1.5 * conf.boxMargin;
+ txt.anchor = 'middle';
+ txt.class = 'loopText';
- drawText(g, txt)
+ drawText(g, txt);
if (typeof bounds.sectionTitles !== 'undefined') {
- bounds.sectionTitles.forEach(function (item, idx) {
+ bounds.sectionTitles.forEach(function(item, idx) {
if (item !== '') {
- txt.text = '[ ' + item + ' ]'
- txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin
- drawText(g, txt)
+ txt.text = '[ ' + item + ' ]';
+ txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin;
+ drawText(g, txt);
}
- })
+ });
}
-}
+};
/**
* Draws a background rectangle
* @param color - The fill color for the background
*/
-export const drawBackgroundRect = function (elem, bounds) {
+export const drawBackgroundRect = function(elem, bounds) {
const rectElem = drawRect(elem, {
x: bounds.startx,
y: bounds.starty,
@@ -179,14 +204,16 @@ export const drawBackgroundRect = function (elem, bounds) {
height: bounds.stopy - bounds.starty,
fill: bounds.fill,
class: 'rect'
- })
- rectElem.lower()
-}
+ });
+ rectElem.lower();
+};
/**
* Setup arrow head and define the marker. The result is appended to the svg.
*/
-export const insertArrowHead = function (elem) {
- elem.append('defs').append('marker')
+export const insertArrowHead = function(elem) {
+ elem
+ .append('defs')
+ .append('marker')
.attr('id', 'arrowhead')
.attr('refX', 5)
.attr('refY', 2)
@@ -194,13 +221,15 @@ export const insertArrowHead = function (elem) {
.attr('markerHeight', 4)
.attr('orient', 'auto')
.append('path')
- .attr('d', 'M 0,0 V 4 L6,2 Z') // this is actual shape for arrowhead
-}
+ .attr('d', 'M 0,0 V 4 L6,2 Z'); // this is actual shape for arrowhead
+};
/**
* Setup node number. The result is appended to the svg.
*/
-export const insertSequenceNumber = function (elem) {
- elem.append('defs').append('marker')
+export const insertSequenceNumber = function(elem) {
+ elem
+ .append('defs')
+ .append('marker')
.attr('id', 'sequencenumber')
.attr('refX', 15)
.attr('refY', 15)
@@ -210,45 +239,48 @@ export const insertSequenceNumber = function (elem) {
.append('circle')
.attr('cx', 15)
.attr('cy', 15)
- .attr('r', 6)
- // .style("fill", '#f00');
-}
+ .attr('r', 6);
+ // .style("fill", '#f00');
+};
/**
* Setup arrow head and define the marker. The result is appended to the svg.
*/
-export const insertArrowCrossHead = function (elem) {
- const defs = elem.append('defs')
- const marker = defs.append('marker')
+export const insertArrowCrossHead = function(elem) {
+ const defs = elem.append('defs');
+ const marker = defs
+ .append('marker')
.attr('id', 'crosshead')
.attr('markerWidth', 15)
.attr('markerHeight', 8)
.attr('orient', 'auto')
.attr('refX', 16)
- .attr('refY', 4)
+ .attr('refY', 4);
// The arrow
- marker.append('path')
+ marker
+ .append('path')
.attr('fill', 'black')
.attr('stroke', '#000000')
- .style('stroke-dasharray', ('0, 0'))
+ .style('stroke-dasharray', '0, 0')
.attr('stroke-width', '1px')
- .attr('d', 'M 9,2 V 6 L16,4 Z')
+ .attr('d', 'M 9,2 V 6 L16,4 Z');
// The cross
- marker.append('path')
+ marker
+ .append('path')
.attr('fill', 'none')
.attr('stroke', '#000000')
- .style('stroke-dasharray', ('0, 0'))
+ .style('stroke-dasharray', '0, 0')
.attr('stroke-width', '1px')
- .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
+ .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7');
// this is actual shape for arrowhead
-}
+};
-export const getTextObj = function () {
+export const getTextObj = function() {
const txt = {
x: 0,
y: 0,
- 'fill': undefined,
+ fill: undefined,
'text-anchor': 'start',
style: '#666',
width: 100,
@@ -256,11 +288,11 @@ export const getTextObj = function () {
textMargin: 0,
rx: 0,
ry: 0
- }
- return txt
-}
+ };
+ return txt;
+};
-export const getNoteRect = function () {
+export const getNoteRect = function() {
const rect = {
x: 0,
y: 0,
@@ -271,72 +303,87 @@ export const getNoteRect = function () {
height: 100,
rx: 0,
ry: 0
- }
- return rect
-}
+ };
+ return rect;
+};
-const _drawTextCandidateFunc = (function () {
- function byText (content, g, x, y, width, height, textAttrs) {
- const text = g.append('text')
- .attr('x', x + width / 2).attr('y', y + height / 2 + 5)
+const _drawTextCandidateFunc = (function() {
+ function byText(content, g, x, y, width, height, textAttrs) {
+ const text = g
+ .append('text')
+ .attr('x', x + width / 2)
+ .attr('y', y + height / 2 + 5)
.style('text-anchor', 'middle')
- .text(content)
- _setTextAttrs(text, textAttrs)
+ .text(content);
+ _setTextAttrs(text, textAttrs);
}
- function byTspan (content, g, x, y, width, height, textAttrs, conf) {
- const { actorFontSize, actorFontFamily } = conf
+ function byTspan(content, g, x, y, width, height, textAttrs, conf) {
+ const { actorFontSize, actorFontFamily } = conf;
- const lines = content.split(/
/ig)
+ const lines = content.split(/
/gi);
for (let i = 0; i < lines.length; i++) {
- const dy = (i * actorFontSize) - (actorFontSize * (lines.length - 1) / 2)
- const text = g.append('text')
- .attr('x', x + width / 2).attr('y', y)
+ const dy = i * actorFontSize - (actorFontSize * (lines.length - 1)) / 2;
+ const text = g
+ .append('text')
+ .attr('x', x + width / 2)
+ .attr('y', y)
.style('text-anchor', 'middle')
.style('font-size', actorFontSize)
- .style('font-family', actorFontFamily)
- text.append('tspan')
- .attr('x', x + width / 2).attr('dy', dy)
- .text(lines[i])
+ .style('font-family', actorFontFamily);
+ text
+ .append('tspan')
+ .attr('x', x + width / 2)
+ .attr('dy', dy)
+ .text(lines[i]);
- text.attr('y', y + height / 2.0)
+ text
+ .attr('y', y + height / 2.0)
.attr('dominant-baseline', 'central')
- .attr('alignment-baseline', 'central')
+ .attr('alignment-baseline', 'central');
- _setTextAttrs(text, textAttrs)
+ _setTextAttrs(text, textAttrs);
}
}
- function byFo (content, g, x, y, width, height, textAttrs, conf) {
- const s = g.append('switch')
- const f = s.append('foreignObject')
- .attr('x', x).attr('y', y)
- .attr('width', width).attr('height', height)
+ function byFo(content, g, x, y, width, height, textAttrs, conf) {
+ const s = g.append('switch');
+ const f = s
+ .append('foreignObject')
+ .attr('x', x)
+ .attr('y', y)
+ .attr('width', width)
+ .attr('height', height);
- const text = f.append('div').style('display', 'table')
- .style('height', '100%').style('width', '100%')
+ const text = f
+ .append('div')
+ .style('display', 'table')
+ .style('height', '100%')
+ .style('width', '100%');
- text.append('div').style('display', 'table-cell')
- .style('text-align', 'center').style('vertical-align', 'middle')
- .text(content)
+ text
+ .append('div')
+ .style('display', 'table-cell')
+ .style('text-align', 'center')
+ .style('vertical-align', 'middle')
+ .text(content);
- byTspan(content, s, x, y, width, height, textAttrs, conf)
- _setTextAttrs(text, textAttrs)
+ byTspan(content, s, x, y, width, height, textAttrs, conf);
+ _setTextAttrs(text, textAttrs);
}
- function _setTextAttrs (toText, fromTextAttrsDict) {
+ function _setTextAttrs(toText, fromTextAttrsDict) {
for (const key in fromTextAttrsDict) {
if (fromTextAttrsDict.hasOwnProperty(key)) {
- toText.attr(key, fromTextAttrsDict[key])
+ toText.attr(key, fromTextAttrsDict[key]);
}
}
}
- return function (conf) {
- return conf.textPlacement === 'fo' ? byFo : (
- conf.textPlacement === 'old' ? byText : byTspan)
- }
-})()
+ return function(conf) {
+ return conf.textPlacement === 'fo' ? byFo : conf.textPlacement === 'old' ? byText : byTspan;
+ };
+})();
export default {
drawRect,
@@ -352,4 +399,4 @@ export default {
insertArrowCrossHead,
getTextObj,
getNoteRect
-}
+};
diff --git a/src/diagrams/sequence/svgDraw.spec.js b/src/diagrams/sequence/svgDraw.spec.js
index efb541e78..c99b9b95b 100644
--- a/src/diagrams/sequence/svgDraw.spec.js
+++ b/src/diagrams/sequence/svgDraw.spec.js
@@ -1,11 +1,11 @@
/* eslint-env jasmine */
-const svgDraw = require('./svgDraw')
-const { MockD3 } = require('d3')
+const svgDraw = require('./svgDraw');
+const { MockD3 } = require('d3');
-describe('svgDraw', function () {
- describe('drawRect', function () {
- it('it should append a rectangle', function () {
- const svg = MockD3('svg')
+describe('svgDraw', function() {
+ describe('drawRect', function() {
+ it('it should append a rectangle', function() {
+ const svg = MockD3('svg');
svgDraw.drawRect(svg, {
x: 10,
y: 10,
@@ -16,22 +16,22 @@ describe('svgDraw', function () {
rx: '10',
ry: '10',
class: 'unitTestRectangleClass'
- })
- expect(svg.__children.length).toBe(1)
- const rect = svg.__children[0]
- expect(rect.__name).toBe('rect')
- expect(rect.attr).toHaveBeenCalledWith('x', 10)
- expect(rect.attr).toHaveBeenCalledWith('y', 10)
- expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc')
- expect(rect.attr).toHaveBeenCalledWith('stroke', 'red')
- expect(rect.attr).toHaveBeenCalledWith('width', '20')
- expect(rect.attr).toHaveBeenCalledWith('height', '20')
- expect(rect.attr).toHaveBeenCalledWith('rx', '10')
- expect(rect.attr).toHaveBeenCalledWith('ry', '10')
- expect(rect.attr).toHaveBeenCalledWith('class', 'unitTestRectangleClass')
- })
+ });
+ expect(svg.__children.length).toBe(1);
+ const rect = svg.__children[0];
+ expect(rect.__name).toBe('rect');
+ expect(rect.attr).toHaveBeenCalledWith('x', 10);
+ expect(rect.attr).toHaveBeenCalledWith('y', 10);
+ expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc');
+ expect(rect.attr).toHaveBeenCalledWith('stroke', 'red');
+ expect(rect.attr).toHaveBeenCalledWith('width', '20');
+ expect(rect.attr).toHaveBeenCalledWith('height', '20');
+ expect(rect.attr).toHaveBeenCalledWith('rx', '10');
+ expect(rect.attr).toHaveBeenCalledWith('ry', '10');
+ expect(rect.attr).toHaveBeenCalledWith('class', 'unitTestRectangleClass');
+ });
it('it should not add the class attribute if a class isn`t provided', () => {
- const svg = MockD3('svg')
+ const svg = MockD3('svg');
svgDraw.drawRect(svg, {
x: 10,
y: 10,
@@ -41,17 +41,17 @@ describe('svgDraw', function () {
height: '20',
rx: '10',
ry: '10'
- })
- expect(svg.__children.length).toBe(1)
- const rect = svg.__children[0]
- expect(rect.__name).toBe('rect')
- expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc')
- expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything())
- })
- })
- describe('drawBackgroundRect', function () {
- it('it should append a rect before the previous element within a given bound', function () {
- const svg = MockD3('svg')
+ });
+ expect(svg.__children.length).toBe(1);
+ const rect = svg.__children[0];
+ expect(rect.__name).toBe('rect');
+ expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc');
+ expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything());
+ });
+ });
+ describe('drawBackgroundRect', function() {
+ it('it should append a rect before the previous element within a given bound', function() {
+ const svg = MockD3('svg');
const boundingRect = {
startx: 50,
starty: 200,
@@ -59,18 +59,18 @@ describe('svgDraw', function () {
stopy: 260,
title: undefined,
fill: '#ccc'
- }
- svgDraw.drawBackgroundRect(svg, boundingRect)
- expect(svg.__children.length).toBe(1)
- const rect = svg.__children[0]
- expect(rect.__name).toBe('rect')
- expect(rect.attr).toHaveBeenCalledWith('x', 50)
- expect(rect.attr).toHaveBeenCalledWith('y', 200)
- expect(rect.attr).toHaveBeenCalledWith('width', 100)
- expect(rect.attr).toHaveBeenCalledWith('height', 60)
- expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc')
- expect(rect.attr).toHaveBeenCalledWith('class', 'rect')
- expect(rect.lower).toHaveBeenCalled()
- })
- })
-})
+ };
+ svgDraw.drawBackgroundRect(svg, boundingRect);
+ expect(svg.__children.length).toBe(1);
+ const rect = svg.__children[0];
+ expect(rect.__name).toBe('rect');
+ expect(rect.attr).toHaveBeenCalledWith('x', 50);
+ expect(rect.attr).toHaveBeenCalledWith('y', 200);
+ expect(rect.attr).toHaveBeenCalledWith('width', 100);
+ expect(rect.attr).toHaveBeenCalledWith('height', 60);
+ expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc');
+ expect(rect.attr).toHaveBeenCalledWith('class', 'rect');
+ expect(rect.lower).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/logger.js b/src/logger.js
index eefaccf34..5de9e320a 100644
--- a/src/logger.js
+++ b/src/logger.js
@@ -1,4 +1,4 @@
-import moment from 'moment-mini'
+import moment from 'moment-mini';
export const LEVELS = {
debug: 1,
@@ -6,7 +6,7 @@ export const LEVELS = {
warn: 3,
error: 4,
fatal: 5
-}
+};
export const logger = {
debug: () => {},
@@ -14,32 +14,32 @@ export const logger = {
warn: () => {},
error: () => {},
fatal: () => {}
-}
+};
-export const setLogLevel = function (level) {
- logger.debug = () => {}
- logger.info = () => {}
- logger.warn = () => {}
- logger.error = () => {}
- logger.fatal = () => {}
+export const setLogLevel = function(level) {
+ logger.debug = () => {};
+ logger.info = () => {};
+ logger.warn = () => {};
+ logger.error = () => {};
+ logger.fatal = () => {};
if (level <= LEVELS.fatal) {
- logger.fatal = console.log.bind(console, '\x1b[35m', format('FATAL'))
+ logger.fatal = console.log.bind(console, '\x1b[35m', format('FATAL'));
}
if (level <= LEVELS.error) {
- logger.error = console.log.bind(console, '\x1b[31m', format('ERROR'))
+ logger.error = console.log.bind(console, '\x1b[31m', format('ERROR'));
}
if (level <= LEVELS.warn) {
- logger.warn = console.log.bind(console, `\x1b[33m`, format('WARN'))
+ logger.warn = console.log.bind(console, `\x1b[33m`, format('WARN'));
}
if (level <= LEVELS.info) {
- logger.info = console.log.bind(console, '\x1b[34m', format('INFO'))
+ logger.info = console.log.bind(console, '\x1b[34m', format('INFO'));
}
if (level <= LEVELS.debug) {
- logger.debug = console.log.bind(console, '\x1b[32m', format('DEBUG'))
+ logger.debug = console.log.bind(console, '\x1b[32m', format('DEBUG'));
}
-}
+};
-const format = (level) => {
- const time = moment().format('HH:mm:ss.SSS')
- return `${time} : ${level} : `
-}
+const format = level => {
+ const time = moment().format('HH:mm:ss.SSS');
+ return `${time} : ${level} : `;
+};
diff --git a/src/mermaid.js b/src/mermaid.js
index ebfc87532..76b644ef2 100644
--- a/src/mermaid.js
+++ b/src/mermaid.js
@@ -2,10 +2,10 @@
* Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render
* the diagrams to svg code.
*/
-import he from 'he'
+import he from 'he';
-import mermaidAPI from './mermaidAPI'
-import { logger } from './logger'
+import mermaidAPI from './mermaidAPI';
+import { logger } from './logger';
/**
* ## init
@@ -28,126 +28,142 @@ import { logger } from './logger'
* Renders the mermaid diagrams
* @param nodes a css selector or an array of nodes
*/
-const init = function () {
- const conf = mermaidAPI.getConfig()
- logger.debug('Starting rendering diagrams')
- let nodes
+const init = function() {
+ const conf = mermaidAPI.getConfig();
+ logger.debug('Starting rendering diagrams');
+ let nodes;
if (arguments.length >= 2) {
/*! sequence config was passed as #1 */
if (typeof arguments[0] !== 'undefined') {
- mermaid.sequenceConfig = arguments[0]
+ mermaid.sequenceConfig = arguments[0];
}
- nodes = arguments[1]
+ nodes = arguments[1];
} else {
- nodes = arguments[0]
+ nodes = arguments[0];
}
// if last argument is a function this is the callback function
- let callback
+ let callback;
if (typeof arguments[arguments.length - 1] === 'function') {
- callback = arguments[arguments.length - 1]
- logger.debug('Callback function found')
+ callback = arguments[arguments.length - 1];
+ logger.debug('Callback function found');
} else {
if (typeof conf.mermaid !== 'undefined') {
if (typeof conf.mermaid.callback === 'function') {
- callback = conf.mermaid.callback
- logger.debug('Callback function found')
+ callback = conf.mermaid.callback;
+ logger.debug('Callback function found');
} else {
- logger.debug('No Callback function found')
+ logger.debug('No Callback function found');
}
}
}
- nodes = nodes === undefined ? document.querySelectorAll('.mermaid')
- : typeof nodes === 'string' ? document.querySelectorAll(nodes)
- : nodes instanceof window.Node ? [nodes]
- : nodes // Last case - sequence config was passed pick next
+ nodes =
+ nodes === undefined
+ ? document.querySelectorAll('.mermaid')
+ : typeof nodes === 'string'
+ ? document.querySelectorAll(nodes)
+ : nodes instanceof window.Node
+ ? [nodes]
+ : nodes; // Last case - sequence config was passed pick next
- logger.debug('Start On Load before: ' + mermaid.startOnLoad)
+ logger.debug('Start On Load before: ' + mermaid.startOnLoad);
if (typeof mermaid.startOnLoad !== 'undefined') {
- logger.debug('Start On Load inner: ' + mermaid.startOnLoad)
- mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad })
+ logger.debug('Start On Load inner: ' + mermaid.startOnLoad);
+ mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad });
}
if (typeof mermaid.ganttConfig !== 'undefined') {
- mermaidAPI.initialize({ gantt: mermaid.ganttConfig })
+ mermaidAPI.initialize({ gantt: mermaid.ganttConfig });
}
- let txt
+ let txt;
for (let i = 0; i < nodes.length; i++) {
- const element = nodes[i]
+ const element = nodes[i];
/*! Check if previously processed */
if (!element.getAttribute('data-processed')) {
- element.setAttribute('data-processed', true)
+ element.setAttribute('data-processed', true);
} else {
- continue
+ continue;
}
- const id = `mermaid-${Date.now()}`
+ const id = `mermaid-${Date.now()}`;
// Fetch the graph definition including tags
- txt = element.innerHTML
+ txt = element.innerHTML;
// transforms the html to pure text
- txt = he.decode(txt).trim().replace(/
/ig, '
')
+ txt = he
+ .decode(txt)
+ .trim()
+ .replace(/
/gi, '
');
- mermaidAPI.render(id, txt, (svgCode, bindFunctions) => {
- element.innerHTML = svgCode
- if (typeof callback !== 'undefined') {
- callback(id)
- }
- if (bindFunctions) bindFunctions(element)
- }, element)
+ mermaidAPI.render(
+ id,
+ txt,
+ (svgCode, bindFunctions) => {
+ element.innerHTML = svgCode;
+ if (typeof callback !== 'undefined') {
+ callback(id);
+ }
+ if (bindFunctions) bindFunctions(element);
+ },
+ element
+ );
}
-}
+};
-const initialize = function (config) {
- logger.debug('Initializing mermaid ')
+const initialize = function(config) {
+ logger.debug('Initializing mermaid ');
if (typeof config.mermaid !== 'undefined') {
if (typeof config.mermaid.startOnLoad !== 'undefined') {
- mermaid.startOnLoad = config.mermaid.startOnLoad
+ mermaid.startOnLoad = config.mermaid.startOnLoad;
}
if (typeof config.mermaid.htmlLabels !== 'undefined') {
- mermaid.htmlLabels = config.mermaid.htmlLabels
+ mermaid.htmlLabels = config.mermaid.htmlLabels;
}
}
- mermaidAPI.initialize(config)
-}
+ mermaidAPI.initialize(config);
+};
/**
* ##contentLoaded
* Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
* calls init for rendering the mermaid diagrams on the page.
*/
-const contentLoaded = function () {
- let config
+const contentLoaded = function() {
+ let config;
if (mermaid.startOnLoad) {
// No config found, do check API config
- config = mermaidAPI.getConfig()
+ config = mermaidAPI.getConfig();
if (config.startOnLoad) {
- mermaid.init()
+ mermaid.init();
}
} else {
if (typeof mermaid.startOnLoad === 'undefined') {
- logger.debug('In start, no config')
- config = mermaidAPI.getConfig()
+ logger.debug('In start, no config');
+ config = mermaidAPI.getConfig();
if (config.startOnLoad) {
- mermaid.init()
+ mermaid.init();
}
}
}
-}
+};
if (typeof document !== 'undefined') {
/*!
* Wait for document loaded before starting the execution
*/
- window.addEventListener('load', function () {
- contentLoaded()
- }, false)
+ window.addEventListener(
+ 'load',
+ function() {
+ contentLoaded();
+ },
+ false
+ );
}
const mermaid = {
@@ -162,6 +178,6 @@ const mermaid = {
initialize,
contentLoaded
-}
+};
-export default mermaid
+export default mermaid;
diff --git a/src/mermaid.spec.js b/src/mermaid.spec.js
index 996ad21f5..8bfbc1995 100644
--- a/src/mermaid.spec.js
+++ b/src/mermaid.spec.js
@@ -1,195 +1,200 @@
/* eslint-env jasmine */
-import mermaid from './mermaid'
-import flowDb from './diagrams/flowchart/flowDb'
-import flowParser from './diagrams/flowchart/parser/flow'
-import flowRenderer from './diagrams/flowchart/flowRenderer'
+import mermaid from './mermaid';
+import flowDb from './diagrams/flowchart/flowDb';
+import flowParser from './diagrams/flowchart/parser/flow';
+import flowRenderer from './diagrams/flowchart/flowRenderer';
-describe('when using mermaid and ', function () {
- describe('when detecting chart type ', function () {
- it('should not start rendering with mermaid.startOnLoad set to false', function () {
- mermaid.startOnLoad = false
- document.body.innerHTML = '
- * "theme": "forest", - * "themeCSS": ".node rect { fill: red; }" - *- */ + * + * **theme** - Choose one of the built-in themes: + * * default + * * forest + * * dark + * * neutral. + * To disable any pre-defined mermaid theme, use "null". + * + * **themeCSS** - Use your own CSS. This overrides **theme**. + *
+ * "theme": "forest", + * "themeCSS": ".node rect { fill: red; }" + *+ */ theme: 'default', themeCSS: undefined, @@ -149,7 +148,6 @@ const config = { * The object containing configurations specific for sequence diagrams */ sequence: { - /** * margin to the right and left of the sequence diagram. * **Default value 50**. @@ -234,7 +232,6 @@ const config = { * **Default value false**. */ showSequenceNumbers: false - }, /** @@ -303,100 +300,100 @@ const config = { }, class: {}, git: {} -} +}; -setLogLevel(config.logLevel) -setConfig(config) +setLogLevel(config.logLevel); +setConfig(config); -function parse (text) { - const graphType = utils.detectType(text) - let parser +function parse(text) { + const graphType = utils.detectType(text); + let parser; - logger.debug('Type ' + graphType) + logger.debug('Type ' + graphType); switch (graphType) { case 'git': - parser = gitGraphParser - parser.parser.yy = gitGraphAst - break + parser = gitGraphParser; + parser.parser.yy = gitGraphAst; + break; case 'flowchart': - parser = flowParser - parser.parser.yy = flowDb - break + parser = flowParser; + parser.parser.yy = flowDb; + break; case 'sequence': - parser = sequenceParser - parser.parser.yy = sequenceDb - break + parser = sequenceParser; + parser.parser.yy = sequenceDb; + break; case 'gantt': - parser = ganttParser - parser.parser.yy = ganttDb - break + parser = ganttParser; + parser.parser.yy = ganttDb; + break; case 'class': - parser = classParser - parser.parser.yy = classDb - break + parser = classParser; + parser.parser.yy = classDb; + break; case 'info': - logger.debug('info info info') - console.warn('In API', pkg.version) + logger.debug('info info info'); + console.warn('In API', pkg.version); - parser = infoParser - parser.parser.yy = infoDb - break + parser = infoParser; + parser.parser.yy = infoDb; + break; case 'pie': - logger.debug('pie') - parser = pieParser - parser.parser.yy = pieDb - break + logger.debug('pie'); + parser = pieParser; + parser.parser.yy = pieDb; + break; } parser.parser.yy.parseError = (str, hash) => { - const error = { str, hash } - throw error - } + const error = { str, hash }; + throw error; + }; - parser.parse(text) + parser.parse(text); } -export const encodeEntities = function (text) { - let txt = text +export const encodeEntities = function(text) { + let txt = text; - txt = txt.replace(/style.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1) - return innerTxt - }) - txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1) - return innerTxt - }) + txt = txt.replace(/style.*:\S*#.*;/g, function(s) { + const innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); + txt = txt.replace(/classDef.*:\S*#.*;/g, function(s) { + const innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); - txt = txt.replace(/#\w+;/g, function (s) { - const innerTxt = s.substring(1, s.length - 1) + txt = txt.replace(/#\w+;/g, function(s) { + const innerTxt = s.substring(1, s.length - 1); - const isInt = /^\+?\d+$/.test(innerTxt) + const isInt = /^\+?\d+$/.test(innerTxt); if (isInt) { - return 'fl°°' + innerTxt + '¶ß' + return 'fl°°' + innerTxt + '¶ß'; } else { - return 'fl°' + innerTxt + '¶ß' + return 'fl°' + innerTxt + '¶ß'; } - }) + }); - return txt -} + return txt; +}; -export const decodeEntities = function (text) { - let txt = text +export const decodeEntities = function(text) { + let txt = text; - txt = txt.replace(/fl°°/g, function () { - return '' - }) - txt = txt.replace(/fl°/g, function () { - return '&' - }) - txt = txt.replace(/¶ß/g, function () { - return ';' - }) + txt = txt.replace(/fl°°/g, function() { + return ''; + }); + txt = txt.replace(/fl°/g, function() { + return '&'; + }); + txt = txt.replace(/¶ß/g, function() { + return ';'; + }); - return txt -} + return txt; +}; /** * Function that renders an svg with a graph from a chart definition. Usage example below. * @@ -419,183 +416,209 @@ export const decodeEntities = function (text) { * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is * completed. */ -const render = function (id, txt, cb, container) { +const render = function(id, txt, cb, container) { if (typeof container !== 'undefined') { - container.innerHTML = '' + container.innerHTML = ''; - d3.select(container).append('div') + d3.select(container) + .append('div') .attr('id', 'd' + id) .append('svg') .attr('id', id) .attr('width', '100%') .attr('xmlns', 'http://www.w3.org/2000/svg') - .append('g') + .append('g'); } else { - const element = document.querySelector('#' + 'd' + id) + const element = document.querySelector('#' + 'd' + id); if (element) { - element.innerHTML = '' + element.innerHTML = ''; } - d3.select('body').append('div') + d3.select('body') + .append('div') .attr('id', 'd' + id) .append('svg') .attr('id', id) .attr('width', '100%') .attr('xmlns', 'http://www.w3.org/2000/svg') - .append('g') + .append('g'); } - window.txt = txt - txt = encodeEntities(txt) + window.txt = txt; + txt = encodeEntities(txt); - const element = d3.select('#d' + id).node() - const graphType = utils.detectType(txt) + const element = d3.select('#d' + id).node(); + const graphType = utils.detectType(txt); // insert inline style into svg - const svg = element.firstChild - const firstChild = svg.firstChild + const svg = element.firstChild; + const firstChild = svg.firstChild; // pre-defined theme - let style = themes[config.theme] + let style = themes[config.theme]; if (style === undefined) { - style = '' + style = ''; } // user provided theme CSS if (config.themeCSS !== undefined) { - style += `\n${config.themeCSS}` + style += `\n${config.themeCSS}`; } // classDef if (graphType === 'flowchart') { - const classes = flowRenderer.getClasses(txt) + const classes = flowRenderer.getClasses(txt); for (const className in classes) { - style += `\n.${className} > * { ${classes[className].styles.join(' !important; ')} !important; }` + style += `\n.${className} > * { ${classes[className].styles.join( + ' !important; ' + )} !important; }`; } } - const style1 = document.createElement('style') - style1.innerHTML = scope(style, `#${id}`) - svg.insertBefore(style1, firstChild) + const style1 = document.createElement('style'); + style1.innerHTML = scope(style, `#${id}`); + svg.insertBefore(style1, firstChild); - const style2 = document.createElement('style') - const cs = window.getComputedStyle(svg) + const style2 = document.createElement('style'); + const cs = window.getComputedStyle(svg); style2.innerHTML = `#${id} { color: ${cs.color}; font: ${cs.font}; - }` - svg.insertBefore(style2, firstChild) + }`; + svg.insertBefore(style2, firstChild); switch (graphType) { case 'git': - config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute - gitGraphRenderer.setConf(config.git) - gitGraphRenderer.draw(txt, id, false) - break + config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + gitGraphRenderer.setConf(config.git); + gitGraphRenderer.draw(txt, id, false); + break; case 'flowchart': - config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute - flowRenderer.setConf(config.flowchart) - flowRenderer.draw(txt, id, false) - break + config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + flowRenderer.setConf(config.flowchart); + flowRenderer.draw(txt, id, false); + break; case 'sequence': - config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute - if (config.sequenceDiagram) { // backwards compatibility - sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram)) - console.error('`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.') + config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + if (config.sequenceDiagram) { + // backwards compatibility + sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram)); + console.error( + '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.' + ); } else { - sequenceRenderer.setConf(config.sequence) + sequenceRenderer.setConf(config.sequence); } - sequenceRenderer.draw(txt, id) - break + sequenceRenderer.draw(txt, id); + break; case 'gantt': - config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute - ganttRenderer.setConf(config.gantt) - ganttRenderer.draw(txt, id) - break + config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + ganttRenderer.setConf(config.gantt); + ganttRenderer.draw(txt, id); + break; case 'class': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - classRenderer.setConf(config.class) - classRenderer.draw(txt, id) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + classRenderer.setConf(config.class); + classRenderer.draw(txt, id); + break; case 'info': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - infoRenderer.setConf(config.class) - infoRenderer.draw(txt, id, pkg.version) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + infoRenderer.setConf(config.class); + infoRenderer.draw(txt, id, pkg.version); + break; case 'pie': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - pieRenderer.setConf(config.class) - pieRenderer.draw(txt, id, pkg.version) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + pieRenderer.setConf(config.class); + pieRenderer.draw(txt, id, pkg.version); + break; } - d3.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', 'http://www.w3.org/1999/xhtml') + d3.select(`[id="${id}"]`) + .selectAll('foreignobject > *') + .attr('xmlns', 'http://www.w3.org/1999/xhtml'); - let url = '' + let url = ''; if (config.arrowMarkerAbsolute) { - url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search - url = url.replace(/\(/g, '\\(') - url = url.replace(/\)/g, '\\)') + url = + window.location.protocol + + '//' + + window.location.host + + window.location.pathname + + window.location.search; + url = url.replace(/\(/g, '\\('); + url = url.replace(/\)/g, '\\)'); } // Fix for when the base tag is used - let svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g') + let svgCode = d3 + .select('#d' + id) + .node() + .innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g'); - svgCode = decodeEntities(svgCode) + svgCode = decodeEntities(svgCode); if (typeof cb !== 'undefined') { switch (graphType) { case 'flowchart': - cb(svgCode, flowDb.bindFunctions) - break + cb(svgCode, flowDb.bindFunctions); + break; case 'gantt': - cb(svgCode, ganttDb.bindFunctions) - break + cb(svgCode, ganttDb.bindFunctions); + break; default: - cb(svgCode) + cb(svgCode); } } else { - logger.debug('CB = undefined!') + logger.debug('CB = undefined!'); } - const node = d3.select('#d' + id).node() + const node = d3.select('#d' + id).node(); if (node !== null && typeof node.remove === 'function') { - d3.select('#d' + id).node().remove() + d3.select('#d' + id) + .node() + .remove(); } - return svgCode -} + return svgCode; +}; -const setConf = function (cnf) { +const setConf = function(cnf) { // Top level initially mermaid, gflow, sequenceDiagram and gantt - const lvl1Keys = Object.keys(cnf) + const lvl1Keys = Object.keys(cnf); for (let i = 0; i < lvl1Keys.length; i++) { if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) { - const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]) + const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]); for (let j = 0; j < lvl2Keys.length; j++) { - logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]) + logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]); if (typeof config[lvl1Keys[i]] === 'undefined') { - config[lvl1Keys[i]] = {} + config[lvl1Keys[i]] = {}; } - logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]]) - config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]] + logger.debug( + 'Setting config: ' + + lvl1Keys[i] + + ' ' + + lvl2Keys[j] + + ' to ' + + cnf[lvl1Keys[i]][lvl2Keys[j]] + ); + config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]; } } else { - config[lvl1Keys[i]] = cnf[lvl1Keys[i]] + config[lvl1Keys[i]] = cnf[lvl1Keys[i]]; } } -} +}; -function initialize (options) { - logger.debug('Initializing mermaidAPI ', pkg.version) +function initialize(options) { + logger.debug('Initializing mermaidAPI ', pkg.version); // Update default config with options supplied at initialization if (typeof options === 'object') { - setConf(options) + setConf(options); } - setConfig(config) - setLogLevel(config.logLevel) + setConfig(config); + setLogLevel(config.logLevel); } // function getConfig () { @@ -608,9 +631,9 @@ const mermaidAPI = { parse, initialize, getConfig -} +}; -export default mermaidAPI +export default mermaidAPI; /** * ## mermaidAPI configuration defaults *
diff --git a/src/mermaidAPI.spec.js b/src/mermaidAPI.spec.js index 51749677c..a5114356f 100644 --- a/src/mermaidAPI.spec.js +++ b/src/mermaidAPI.spec.js @@ -1,45 +1,45 @@ /* eslint-env jasmine */ -import mermaidAPI from './mermaidAPI' +import mermaidAPI from './mermaidAPI'; -describe('when using mermaidAPI and ', function () { - describe('doing initialize ', function () { - beforeEach(function () { - document.body.innerHTML = '' - }) +describe('when using mermaidAPI and ', function() { + describe('doing initialize ', function() { + beforeEach(function() { + document.body.innerHTML = ''; + }); - it('should copy a literal into the configuration', function () { - const orgConfig = mermaidAPI.getConfig() - expect(orgConfig.testLiteral).toBe(undefined) + it('should copy a literal into the configuration', function() { + const orgConfig = mermaidAPI.getConfig(); + expect(orgConfig.testLiteral).toBe(undefined); - mermaidAPI.initialize({ 'testLiteral': true }) - const config = mermaidAPI.getConfig() + mermaidAPI.initialize({ testLiteral: true }); + const config = mermaidAPI.getConfig(); - expect(config.testLiteral).toBe(true) - }) - it('should copy a an object into the configuration', function () { - const orgConfig = mermaidAPI.getConfig() - expect(orgConfig.testObject).toBe(undefined) + expect(config.testLiteral).toBe(true); + }); + it('should copy a an object into the configuration', function() { + const orgConfig = mermaidAPI.getConfig(); + expect(orgConfig.testObject).toBe(undefined); const object = { test1: 1, test2: false - } + }; - mermaidAPI.initialize({ 'testObject': object }) - mermaidAPI.initialize({ 'testObject': { 'test3': true } }) - const config = mermaidAPI.getConfig() + mermaidAPI.initialize({ testObject: object }); + mermaidAPI.initialize({ testObject: { test3: true } }); + const config = mermaidAPI.getConfig(); - expect(config.testObject.test1).toBe(1) - expect(config.testObject.test2).toBe(false) - expect(config.testObject.test3).toBe(true) - }) - }) - describe('checking validity of input ', function () { - it('it should throw for an invalid definiton', function () { - expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow() - }) - it('it should not throw for a valid definiton', function () { - expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow() - }) - }) -}) + expect(config.testObject.test1).toBe(1); + expect(config.testObject.test2).toBe(false); + expect(config.testObject.test3).toBe(true); + }); + }); + describe('checking validity of input ', function() { + it('it should throw for an invalid definiton', function() { + expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow(); + }); + it('it should not throw for a valid definiton', function() { + expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow(); + }); + }); +}); diff --git a/src/utils.js b/src/utils.js index 462e7040c..357865fbf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,5 @@ -import * as d3 from 'd3' -import { logger } from './logger' +import * as d3 from 'd3'; +import { logger } from './logger'; /** * @function detectType @@ -18,34 +18,34 @@ import { logger } from './logger' * @param {string} text The text defining the graph * @returns {string} A graph definition key */ -export const detectType = function (text) { - text = text.replace(/^\s*%%.*\n/g, '\n') - logger.debug('Detecting diagram type based on the text ' + text) +export const detectType = function(text) { + text = text.replace(/^\s*%%.*\n/g, '\n'); + logger.debug('Detecting diagram type based on the text ' + text); if (text.match(/^\s*sequenceDiagram/)) { - return 'sequence' + return 'sequence'; } if (text.match(/^\s*gantt/)) { - return 'gantt' + return 'gantt'; } if (text.match(/^\s*classDiagram/)) { - return 'class' + return 'class'; } if (text.match(/^\s*gitGraph/)) { - return 'git' + return 'git'; } if (text.match(/^\s*info/)) { - return 'info' + return 'info'; } if (text.match(/^\s*pie/)) { - return 'pie' + return 'pie'; } - return 'flowchart' -} + return 'flowchart'; +}; /** * @function isSubstringInArray @@ -54,23 +54,23 @@ export const detectType = function (text) { * @param {array} arr The array to search * @returns {number} the array index containing the substring or -1 if not present **/ -export const isSubstringInArray = function (str, arr) { +export const isSubstringInArray = function(str, arr) { for (let i = 0; i < arr.length; i++) { - if (arr[i].match(str)) return i + if (arr[i].match(str)) return i; } - return -1 -} + return -1; +}; export const interpolateToCurve = (interpolate, defaultCurve) => { if (!interpolate) { - return defaultCurve + return defaultCurve; } - const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}` - return d3[curveName] || defaultCurve -} + const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`; + return d3[curveName] || defaultCurve; +}; export default { detectType, isSubstringInArray, interpolateToCurve -} +}; diff --git a/src/utils.spec.js b/src/utils.spec.js index 43341fb6d..86de39513 100644 --- a/src/utils.spec.js +++ b/src/utils.spec.js @@ -1,39 +1,39 @@ /* eslint-env jasmine */ -import utils from './utils' +import utils from './utils'; -describe('when detecting chart type ', function () { - it('should handle a graph defintion', function () { - const str = 'graph TB\nbfs1:queue' - const type = utils.detectType(str) - expect(type).toBe('flowchart') - }) - it('should handle a graph defintion with leading spaces', function () { - const str = ' graph TB\nbfs1:queue' - const type = utils.detectType(str) - expect(type).toBe('flowchart') - }) +describe('when detecting chart type ', function() { + it('should handle a graph defintion', function() { + const str = 'graph TB\nbfs1:queue'; + const type = utils.detectType(str); + expect(type).toBe('flowchart'); + }); + it('should handle a graph defintion with leading spaces', function() { + const str = ' graph TB\nbfs1:queue'; + const type = utils.detectType(str); + expect(type).toBe('flowchart'); + }); - it('should handle a graph defintion with leading spaces and newline', function () { - const str = ' \n graph TB\nbfs1:queue' - const type = utils.detectType(str) - expect(type).toBe('flowchart') - }) - it('should handle a graph defintion for gitGraph', function () { - const str = ' \n gitGraph TB:\nbfs1:queue' - const type = utils.detectType(str) - expect(type).toBe('git') - }) -}) + it('should handle a graph defintion with leading spaces and newline', function() { + const str = ' \n graph TB\nbfs1:queue'; + const type = utils.detectType(str); + expect(type).toBe('flowchart'); + }); + it('should handle a graph defintion for gitGraph', function() { + const str = ' \n gitGraph TB:\nbfs1:queue'; + const type = utils.detectType(str); + expect(type).toBe('git'); + }); +}); -describe('when finding substring in array ', function () { - it('should return the array index that contains the substring', function () { - const arr = ['stroke:val1', 'fill:val2'] - const result = utils.isSubstringInArray('fill', arr) - expect(result).toEqual(1) - }) - it('should return -1 if the substring is not found in the array', function () { - const arr = ['stroke:val1', 'stroke-width:val2'] - const result = utils.isSubstringInArray('fill', arr) - expect(result).toEqual(-1) - }) -}) +describe('when finding substring in array ', function() { + it('should return the array index that contains the substring', function() { + const arr = ['stroke:val1', 'fill:val2']; + const result = utils.isSubstringInArray('fill', arr); + expect(result).toEqual(1); + }); + it('should return -1 if the substring is not found in the array', function() { + const arr = ['stroke:val1', 'stroke-width:val2']; + const result = utils.isSubstringInArray('fill', arr); + expect(result).toEqual(-1); + }); +}); diff --git a/yarn.lock b/yarn.lock index c2e24ae0b..8f64c4adb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1528,6 +1528,11 @@ acorn-jsx@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" +acorn-jsx@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== + acorn-walk@^6.0.1: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" @@ -1540,6 +1545,11 @@ acorn@^6.0.1, acorn@^6.0.2: version "6.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" +acorn@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" + integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== + agent-base@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -1575,6 +1585,16 @@ ajv@^6.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^6.10.0, ajv@^6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -1591,9 +1611,10 @@ ansi-escapes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" -ansi-escapes@^3.1.0: +ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-html@0.0.7, ansi-html@^0.0.7: version "0.0.7" @@ -2383,6 +2404,11 @@ callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camel-case@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" @@ -2504,6 +2530,11 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + check-more-types@2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" @@ -3394,9 +3425,10 @@ debug@3.2.6, debug@^3.2.5, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@4.1.1, debug@^4.1.1: +debug@4.1.1, debug@^4.0.1, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" @@ -3627,6 +3659,13 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + documentation@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/documentation/-/documentation-12.0.1.tgz#4abe263d5415f3ed7ee737829921ef6159e6a335" @@ -3899,6 +3938,13 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.3.0.tgz#e73b48e59dc49d950843f3eb96d519e2248286a3" + integrity sha512-EWaGjlDAZRzVFveh2Jsglcere2KK5CJBhkNSa1xs3KfMUGdRiT7lG089eqPdvlzWHpAqaekubOsOMu8W8Yk71A== + dependencies: + get-stdin "^6.0.0" + eslint-config-standard-jsx@6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz#90c9aa16ac2c4f8970c13fc7efc608bacd02da70" @@ -3954,6 +4000,13 @@ eslint-plugin-node@~7.0.1: resolve "^1.8.1" semver "^5.5.0" +eslint-plugin-prettier@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#8695188f95daa93b0dc54b249347ca3b79c4686d" + integrity sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-plugin-promise@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" @@ -3979,14 +4032,77 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-utils@^1.3.0, eslint-utils@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" +eslint-utils@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" +eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.3.0.tgz#1f1a902f67bfd4c354e7288b81e40654d927eb6a" + integrity sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.4.1" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + eslint@~5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.4.0.tgz#d068ec03006bb9e06b429dc85f7e46c1b69fac62" @@ -4038,6 +4154,15 @@ espree@^4.0.0: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== + dependencies: + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" + esprima@1.1.x, esprima@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" @@ -4289,6 +4414,15 @@ external-editor@^2.1.0: iconv-lite "^0.4.17" tmp "^0.0.33" +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -4337,6 +4471,11 @@ fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602" @@ -4420,6 +4559,13 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -4537,6 +4683,20 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" @@ -5260,7 +5420,7 @@ hyperlinker@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" -iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4: +iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" dependencies: @@ -5300,9 +5460,10 @@ ignore@^3.0.9: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" -ignore@^4.0.2: +ignore@^4.0.2, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1: version "5.1.4" @@ -5315,6 +5476,14 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-fresh@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -5396,6 +5565,25 @@ inquirer@^5.2.0: strip-ansi "^4.0.0" through "^2.3.6" +inquirer@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + internal-ip@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" @@ -6661,9 +6849,10 @@ lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, version "4.17.13" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" -lodash@^4.17.13: +lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== log-driver@^1.2.7: version "1.2.7" @@ -7699,6 +7888,13 @@ param-case@2.1.x: dependencies: no-case "^2.2.0" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" @@ -8062,6 +8258,18 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" + integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== + pretty-format@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" @@ -8804,6 +9012,11 @@ resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-options@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" @@ -8856,7 +9069,7 @@ reusify@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: +rimraf@2, rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" dependencies: @@ -8907,6 +9120,13 @@ rxjs@^5.0.0-beta.11, rxjs@^5.5.2: dependencies: symbol-observable "1.0.1" +rxjs@^6.4.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@^5.1.1, safe-buffer@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -9036,6 +9256,11 @@ semver@^6.1.1: version "6.2.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -9199,6 +9424,15 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + slugify@^1.3.1: version "1.3.4" resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.4.tgz#78d2792d7222b55cd9fc81fa018df99af779efeb" @@ -9648,6 +9882,11 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + subarg@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" @@ -9708,6 +9947,16 @@ table@^4.0.3: slice-ansi "1.0.0" string-width "^2.1.1" +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + tapable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" @@ -10253,6 +10502,11 @@ v8-compile-cache@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" @@ -10687,6 +10941,13 @@ write-file-atomic@^2.1.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"