Merge pull request #908 from knsv/bug/subgraphs_number_in_id_and_space_in_titles_895_and_900

Bug/subgraphs number in id and space in titles 895 and 900
This commit is contained in:
Knut Sveidqvist
2019-08-16 13:02:30 +02:00
committed by GitHub
5 changed files with 325 additions and 152 deletions

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
<style>
body {
font-family: 'trebuchet ms', verdana, arial;
}
</style>
</head>
<body>
<div class="mermaid">
graph TD
A[Christmas] -->|Get money| B(Go shopping)
subgraph 1test["id starting with number"]
A
end
style 1test fill:#F99,stroke-width:2px,stroke:#F0F
</div>
<div class="mermaid">
graph TD
A[Christmas] -->|Get money| B(Go shopping)
subgraph test["id starting with number"]
A
end
style test fill:#F99,stroke-width:2px,stroke:#F0F
</div>
<div class="mermaid">
graph TD
9e122290-->82072290_1ec3_e711_8c5a_005056ad0002
style 9e122290 fill:#F99,stroke-width:2px,stroke:#F0F
</div>
<script src="./mermaid.js"></script>
<script>
function showFullFirstSquad(elemName) {
console.log('show ' + elemName);
}
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
</script>
</body>
</html>

View File

@@ -37,9 +37,9 @@ const sanitize = text => {
* @param style
* @param classes
*/
export const addVertex = function (id, text, type, style, classes) {
export const addVertex = function (_id, text, type, style, classes) {
let txt
let id = _id
if (typeof id === 'undefined') {
return
}
@@ -47,6 +47,8 @@ export const addVertex = function (id, text, type, style, classes) {
return
}
if (id[0].match(/\d/)) id = 's' + id
if (typeof vertices[id] === 'undefined') {
vertices[id] = { id: id, styles: [], classes: [] }
}
@@ -86,8 +88,13 @@ export const addVertex = function (id, text, type, style, classes) {
* @param type
* @param linktext
*/
export const addLink = function (start, end, type, 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)
const edge = { start: start, end: end, type: undefined, text: '' }
linktext = type.text
@@ -338,7 +345,12 @@ export const defaultStyle = function () {
/**
* Clears the internal graph db so that a new graph can be parsed.
*/
export const addSubGraph = function (id, list, title) {
export const addSubGraph = function (_id, list, _title) {
let id = _id
let title = _title
if (_id === _title && _title.match(/\s/)) {
id = undefined
}
function uniq (a) {
const prims = { 'boolean': {}, 'number': {}, 'string': {} }
const objs = []
@@ -357,6 +369,7 @@ export const addSubGraph = function (id, list, title) {
nodeList = uniq(nodeList.concat.apply(nodeList, list))
id = id || ('subGraph' + subCount)
if (id[0].match(/\d/)) id = 's' + id
title = title || ''
title = sanitize(title)
subCount = subCount + 1

View File

@@ -251,12 +251,12 @@ statement
{$$=[];}
| clickStatement separator
{$$=[];}
| subgraph SPACE alphaNum SQS text SQE separator document end
| subgraph SPACE text SQS text SQE separator document end
{$$=yy.addSubGraph($3,$8,$5);}
| subgraph SPACE STR separator document end
{$$=yy.addSubGraph(undefined,$5,$3);}
| subgraph SPACE alphaNum separator document end
| subgraph SPACE text separator document end
{$$=yy.addSubGraph($3,$5,$3);}
// | subgraph SPACE text separator document end
// {$$=yy.addSubGraph($3,$5,$3);}
| subgraph separator document end
{$$=yy.addSubGraph(undefined,$3,undefined);}
;

View File

@@ -27,54 +27,6 @@ describe('when parsing ', function () {
expect(edges[0].text).toBe('')
})
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
expect(subgraph.title).toBe('Some Title')
expect(subgraph.id).toBe('subGraph0')
});
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
expect(subgraph.title).toBe('Some Title')
expect(subgraph.id).toBe('some-id')
});
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 angle bracket ' > ' as direction LR", function () {
const res = flow.parser.parse('graph >;A-->B;')
@@ -384,53 +336,6 @@ describe('when parsing ', function () {
expect(edges[0].type).toBe('arrow_circle')
})
it('should handle subgraphs', 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()
expect(edges[0].type).toBe('arrow')
})
it('should handle subgraphs', 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()
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 subgraphs', 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()
expect(edges[0].type).toBe('arrow')
})
it('should handle subgraphs', 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()
expect(edges[0].type).toBe('arrow')
})
it('should handle classDefs with style in classes', function () {
const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;')
@@ -449,7 +354,7 @@ describe('when parsing ', function () {
expect(edges[0].type).toBe('arrow')
})
it('should handle style definitons with more then 1 digit in a row', function () {
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' +
@@ -1508,7 +1413,7 @@ describe('when parsing ', function () {
const edges = flow.parser.yy.getEdges()
expect(edges.length).toBe(0)
expect(vert['1id'].styles.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

View File

@@ -0,0 +1,211 @@
import flowDb from '../flowDb'
import flow from './flow'
import { setConfig } from '../../../config'
setConfig({
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
expect(subgraph.title).toBe('Some Title')
expect(subgraph.id).toBe('subGraph0')
});
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('a1')
expect(subgraph.nodes[1]).toBe('a2')
expect(subgraph.title).toBe('Some Title')
expect(subgraph.id).toBe('some-id')
});
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`)
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;')
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;')
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]
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;')
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]
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;')
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]
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;')
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]
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;')
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]
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;')
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]
expect(subgraph.title).toBe('textofdoom')
expect(subgraph.id).toBe('uid2')
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')
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
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 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()
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;')
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
expect(edges[0].type).toBe('arrow')
})
})