Merge pull request #3436 from mermaid-js/3061_decoupling
Creating detectors and moving out diagram specific code from the diag…
This commit is contained in:
commit
0edc2751f3
|
@ -38,7 +38,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
flowchart LR
|
||||
classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px;
|
||||
classDef crm stroke:#333333,fill:#DCDCDC,color:#333333,rx:5px,ry:5px;
|
||||
|
@ -99,7 +99,7 @@ flowchart TD
|
|||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
sequenceDiagram
|
||||
title: My Sequence Diagram Title
|
||||
accTitle: My Acc Sequence Diagram
|
||||
|
@ -109,14 +109,14 @@ flowchart TD
|
|||
John-->>Alice: Great!
|
||||
Alice-)John: See you later!
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
graph TD
|
||||
A -->|000| B
|
||||
B -->|111| C
|
||||
|
||||
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
journey
|
||||
accTitle: My User Journey Diagram
|
||||
accDescr: My User Journey Diagram Description
|
||||
|
@ -130,10 +130,10 @@ graph TD
|
|||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
info
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
requirementDiagram
|
||||
accTitle: My req Diagram
|
||||
accDescr: My req Diagram Description
|
||||
|
@ -174,7 +174,7 @@ requirementDiagram
|
|||
test_req - contains -> test_req3
|
||||
test_req <- copies - test_entity2
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram functionality to mermaid
|
||||
|
@ -206,7 +206,7 @@ gantt
|
|||
Add gantt diagram to demo page :20h
|
||||
Add another diagram to demo page :48h
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
stateDiagram
|
||||
state Active {
|
||||
Idle
|
||||
|
@ -234,7 +234,7 @@ stateDiagram
|
|||
end
|
||||
B ->> A: Return
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
classDiagram
|
||||
accTitle: My class diagram
|
||||
accDescr: My class diagram Description
|
||||
|
@ -259,7 +259,7 @@ class Class10 {
|
|||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
gitGraph
|
||||
commit id: "ZERO"
|
||||
branch develop
|
||||
|
@ -288,7 +288,7 @@ flowchart TD
|
|||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
classDiagram
|
||||
Animal "1" <|-- Duck
|
||||
Animal <|-- Fish
|
||||
|
@ -311,7 +311,7 @@ flowchart TD
|
|||
+run()
|
||||
}
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
CAR {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mermaid",
|
||||
"version": "9.1.6",
|
||||
"version": "9.2.0-rc1",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.min.js",
|
||||
"module": "dist/mermaid.esm.min.mjs",
|
||||
|
|
|
@ -1,26 +1,12 @@
|
|||
import { MermaidConfig } from '../config.type';
|
||||
|
||||
export type DiagramDetector = (text: string) => boolean;
|
||||
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||
|
||||
const directive =
|
||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||
const anyComment = /\s*%%.*\n/gm;
|
||||
|
||||
const detectors: Record<string, DiagramDetector> = {};
|
||||
const diagramMatchers: Record<string, RegExp> = {
|
||||
c4: /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/,
|
||||
sequence: /^\s*sequenceDiagram/,
|
||||
gantt: /^\s*gantt/,
|
||||
classDiagram: /^\s*classDiagram-v2/,
|
||||
stateDiagram: /^\s*stateDiagram-v2/,
|
||||
'flowchart-v2': /^\s*flowchart/, // Might need to add |graph to fix #3391
|
||||
info: /^\s*info/,
|
||||
pie: /^\s*pie/,
|
||||
er: /^\s*erDiagram/,
|
||||
journey: /^\s*journey/,
|
||||
// gitGraph: /^\s*gitGraph/,
|
||||
requirement: /^\s*requirement(Diagram)?/,
|
||||
};
|
||||
|
||||
/**
|
||||
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
||||
|
@ -47,28 +33,9 @@ const diagramMatchers: Record<string, RegExp> = {
|
|||
*/
|
||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
||||
for (const [diagram, matcher] of Object.entries(diagramMatchers)) {
|
||||
if (text.match(matcher)) {
|
||||
return diagram;
|
||||
}
|
||||
}
|
||||
|
||||
if (text.match(/^\s*classDiagram/)) {
|
||||
if (config?.class?.defaultRenderer === 'dagre-wrapper') return 'classDiagram';
|
||||
return 'class';
|
||||
}
|
||||
|
||||
if (text.match(/^\s*stateDiagram/)) {
|
||||
if (config?.state?.defaultRenderer === 'dagre-wrapper') return 'stateDiagram';
|
||||
return 'state';
|
||||
}
|
||||
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
|
||||
return 'flowchart-v2';
|
||||
}
|
||||
|
||||
for (const [key, detector] of Object.entries(detectors)) {
|
||||
if (detector(text)) {
|
||||
if (detector(text, config)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,310 @@
|
|||
import { registerDiagram } from './diagramAPI';
|
||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
import mindmapStyles from '../diagrams/mindmap/styles';
|
||||
|
||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||
import gitGraphStyles from '../diagrams/git/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||
import { c4Detector } from '../diagrams/c4/c4Detector';
|
||||
import c4Db from '../diagrams/c4/c4Db';
|
||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||
import c4Styles from '../diagrams/c4/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import classParser from '../diagrams/class/parser/classDiagram';
|
||||
import { classDetector } from '../diagrams/class/classDetector';
|
||||
import { classDetectorV2 } from '../diagrams/class/classDetector-V2';
|
||||
import classDb from '../diagrams/class/classDb';
|
||||
import classRenderer from '../diagrams/class/classRenderer';
|
||||
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||
import classStyles from '../diagrams/class/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import erParser from '../diagrams/er/parser/erDiagram';
|
||||
import { erDetector } from '../diagrams/er/erDetector';
|
||||
import erDb from '../diagrams/er/erDb';
|
||||
import erRenderer from '../diagrams/er/erRenderer';
|
||||
import erStyles from '../diagrams/er/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||
import { flowDetector } from '../diagrams/flowchart/flowDetector';
|
||||
import { flowDetectorV2 } from '../diagrams/flowchart/flowDetector-v2';
|
||||
import flowDb from '../diagrams/flowchart/flowDb';
|
||||
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||
import flowStyles from '../diagrams/flowchart/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||
import { ganttDetector } from '../diagrams/gantt/ganttDetector';
|
||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||
import ganttStyles from '../diagrams/gantt/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import infoParser from '../diagrams/info/parser/info';
|
||||
import infoDb from '../diagrams/info/infoDb';
|
||||
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||
import { infoDetector } from '../diagrams/info/infoDetector';
|
||||
import infoStyles from '../diagrams/info/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import pieParser from '../diagrams/pie/parser/pie';
|
||||
import { pieDetector } from '../diagrams/pie/pieDetector';
|
||||
import pieDb from '../diagrams/pie/pieDb';
|
||||
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||
import pieStyles from '../diagrams/pie/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||
import { requirementDetector } from '../diagrams/requirement/requirementDetector';
|
||||
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||
import requirementStyles from '../diagrams/requirement/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||
import { sequenceDetector } from '../diagrams/sequence/sequenceDetector';
|
||||
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||
import sequenceStyles from '../diagrams/sequence/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||
import { stateDetector } from '../diagrams/state/stateDetector';
|
||||
import { stateDetectorV2 } from '../diagrams/state/stateDetector-V2';
|
||||
import stateDb from '../diagrams/state/stateDb';
|
||||
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||
import stateStyles from '../diagrams/state/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { journeyDetector } from '../diagrams/user-journey/journeyDetector';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
|
||||
export const addDiagrams = () => {
|
||||
// Register mindmap and other built-in diagrams
|
||||
registerDiagram(
|
||||
'c4',
|
||||
{
|
||||
parser: c4Parser,
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
styles: c4Styles,
|
||||
init: (cnf) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
},
|
||||
c4Detector
|
||||
);
|
||||
registerDiagram(
|
||||
'class',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRenderer,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'classDiagram',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRendererV2,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'er',
|
||||
{
|
||||
parser: erParser,
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
styles: erStyles,
|
||||
},
|
||||
erDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'gantt',
|
||||
{
|
||||
parser: ganttParser,
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
styles: ganttStyles,
|
||||
},
|
||||
ganttDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'info',
|
||||
{
|
||||
parser: infoParser,
|
||||
db: infoDb,
|
||||
renderer: infoRenderer,
|
||||
styles: infoStyles,
|
||||
},
|
||||
infoDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'pie',
|
||||
{
|
||||
parser: pieParser,
|
||||
db: pieDb,
|
||||
renderer: pieRenderer,
|
||||
styles: pieStyles,
|
||||
},
|
||||
pieDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'requirement',
|
||||
{
|
||||
parser: requirementParser,
|
||||
db: requirementDb,
|
||||
renderer: requirementRenderer,
|
||||
styles: requirementStyles,
|
||||
},
|
||||
requirementDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'sequence',
|
||||
{
|
||||
parser: sequenceParser,
|
||||
db: sequenceDb,
|
||||
renderer: sequenceRenderer,
|
||||
styles: sequenceStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
if ('sequenceDiagram' in cnf) {
|
||||
throw new Error(
|
||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||
);
|
||||
}
|
||||
sequenceDb.setWrap(cnf.wrap);
|
||||
sequenceRenderer.setConf(cnf.sequence);
|
||||
},
|
||||
},
|
||||
sequenceDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'state',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRenderer,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'stateDiagram',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRendererV2,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'journey',
|
||||
{
|
||||
parser: journeyParser,
|
||||
db: journeyDb,
|
||||
renderer: journeyRenderer,
|
||||
styles: journeyStyles,
|
||||
init: (cnf) => {
|
||||
journeyRenderer.setConf(cnf.journey);
|
||||
journeyDb.clear();
|
||||
},
|
||||
},
|
||||
journeyDetector
|
||||
);
|
||||
|
||||
registerDiagram(
|
||||
'flowchart',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
},
|
||||
flowDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'flowchart-v2',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
},
|
||||
flowDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'gitGraph',
|
||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { detectType } from './detectType';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { addDiagrams } from './diagram-orchestration';
|
||||
|
||||
addDiagrams();
|
||||
|
||||
describe('DiagramAPI', () => {
|
||||
it('should return default diagrams', () => {
|
||||
|
|
|
@ -1,70 +1,23 @@
|
|||
import c4Db from '../diagrams/c4/c4Db';
|
||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||
import c4Styles from '../diagrams/c4/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||
import classDb from '../diagrams/class/classDb';
|
||||
import classRenderer from '../diagrams/class/classRenderer';
|
||||
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||
import classStyles from '../diagrams/class/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import classParser from '../diagrams/class/parser/classDiagram';
|
||||
import erDb from '../diagrams/er/erDb';
|
||||
import erRenderer from '../diagrams/er/erRenderer';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import erParser from '../diagrams/er/parser/erDiagram';
|
||||
import erStyles from '../diagrams/er/styles';
|
||||
import flowDb from '../diagrams/flowchart/flowDb';
|
||||
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||
import flowStyles from '../diagrams/flowchart/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||
import ganttStyles from '../diagrams/gantt/styles';
|
||||
|
||||
import infoDb from '../diagrams/info/infoDb';
|
||||
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import infoParser from '../diagrams/info/parser/info';
|
||||
import infoStyles from '../diagrams/info/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import pieParser from '../diagrams/pie/parser/pie';
|
||||
import pieDb from '../diagrams/pie/pieDb';
|
||||
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||
import pieStyles from '../diagrams/pie/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||
import requirementStyles from '../diagrams/requirement/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||
import sequenceStyles from '../diagrams/sequence/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||
import stateDb from '../diagrams/state/stateDb';
|
||||
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||
import stateStyles from '../diagrams/state/styles';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { addDetector, DiagramDetector } from './detectType';
|
||||
import { log as _log } from '../logger';
|
||||
import { addDetector, DiagramDetector as _DiagramDetector } from './detectType';
|
||||
import { log as _log, setLogLevel as _setLogLevel } from '../logger';
|
||||
import { getConfig as _getConfig } from '../config';
|
||||
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
||||
import { MermaidConfig } from '../config.type';
|
||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
||||
import { addStylesForDiagram } from '../styles';
|
||||
|
||||
/*
|
||||
Packaging and exposing resources for externa diagrams so that they can import
|
||||
diagramAPI and have access to selct parts of mermaid common code reqiored to
|
||||
create diagrams worling like the internal diagrams.
|
||||
*/
|
||||
export const log = _log;
|
||||
export const setLogLevel = _setLogLevel;
|
||||
export type DiagramDetector = _DiagramDetector;
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||
export const setupGraphViewbox = _setupGraphViewbox;
|
||||
|
||||
export interface DiagramDefinition {
|
||||
db: any;
|
||||
renderer: any;
|
||||
|
@ -73,158 +26,7 @@ export interface DiagramDefinition {
|
|||
init?: (config: MermaidConfig) => void;
|
||||
}
|
||||
|
||||
const diagrams: Record<string, DiagramDefinition> = {
|
||||
c4: {
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
parser: c4Parser,
|
||||
init: (cnf) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
styles: c4Styles,
|
||||
},
|
||||
class: {
|
||||
db: classDb,
|
||||
renderer: classRenderer,
|
||||
parser: classParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
styles: classStyles,
|
||||
},
|
||||
classDiagram: {
|
||||
db: classDb,
|
||||
renderer: classRendererV2,
|
||||
parser: classParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
styles: classStyles,
|
||||
},
|
||||
er: {
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
parser: erParser,
|
||||
styles: erStyles,
|
||||
},
|
||||
flowchart: {
|
||||
db: flowDb,
|
||||
renderer: flowRenderer,
|
||||
parser: flowParser,
|
||||
init: (cnf) => {
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
styles: flowStyles,
|
||||
},
|
||||
'flowchart-v2': {
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
parser: flowParser,
|
||||
init: (cnf) => {
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
styles: flowStyles,
|
||||
},
|
||||
gantt: {
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
parser: ganttParser,
|
||||
styles: ganttStyles,
|
||||
},
|
||||
info: {
|
||||
db: infoDb,
|
||||
renderer: infoRenderer,
|
||||
parser: infoParser,
|
||||
styles: infoStyles,
|
||||
},
|
||||
pie: {
|
||||
db: pieDb,
|
||||
renderer: pieRenderer,
|
||||
parser: pieParser,
|
||||
styles: pieStyles,
|
||||
},
|
||||
requirement: {
|
||||
db: requirementDb,
|
||||
renderer: requirementRenderer,
|
||||
parser: requirementParser,
|
||||
styles: requirementStyles,
|
||||
},
|
||||
sequence: {
|
||||
db: sequenceDb,
|
||||
renderer: sequenceRenderer,
|
||||
parser: sequenceParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
if ('sequenceDiagram' in cnf) {
|
||||
throw new Error(
|
||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||
);
|
||||
}
|
||||
sequenceDb.setWrap(cnf.wrap);
|
||||
sequenceRenderer.setConf(cnf.sequence);
|
||||
},
|
||||
styles: sequenceStyles,
|
||||
},
|
||||
state: {
|
||||
db: stateDb,
|
||||
renderer: stateRenderer,
|
||||
parser: stateParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
styles: stateStyles,
|
||||
},
|
||||
stateDiagram: {
|
||||
db: stateDb,
|
||||
renderer: stateRendererV2,
|
||||
parser: stateParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
styles: stateStyles,
|
||||
},
|
||||
journey: {
|
||||
db: journeyDb,
|
||||
renderer: journeyRenderer,
|
||||
parser: journeyParser,
|
||||
init: (cnf) => {
|
||||
journeyRenderer.setConf(cnf.journey);
|
||||
journeyDb.clear();
|
||||
},
|
||||
styles: journeyStyles,
|
||||
},
|
||||
};
|
||||
const diagrams: Record<string, DiagramDefinition> = {};
|
||||
|
||||
export const registerDiagram = (
|
||||
id: string,
|
||||
|
@ -245,8 +47,3 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
|||
}
|
||||
throw new Error(`Diagram ${name} not found.`);
|
||||
};
|
||||
|
||||
export const log = _log;
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||
export const setupGraphViewbox = _setupGraphViewbox;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const c4Detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const classDetectorV2: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram
|
||||
if (txt.match(/^\s*classDiagram/) !== null && config?.class?.defaultRenderer === 'dagre-wrapper')
|
||||
return true;
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram-v2/) !== null;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const classDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should never return true in this function
|
||||
if (config?.class?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram/) !== null;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const erDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*erDiagram/) !== null;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const flowDetectorV2: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper' && txt.match(/^\s*graph/) !== null)
|
||||
return true;
|
||||
return txt.match(/^\s*flowchart/) !== null;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const flowDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confired to only use new flow charts this function shohuld always return false
|
||||
// as in not signalling true for a legacy flowchart
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
return txt.match(/^\s*graph/) !== null;
|
||||
};
|
|
@ -0,0 +1,154 @@
|
|||
import flowDb from './flowDb';
|
||||
import flowParser from './parser/flow';
|
||||
import flowRenderer from './flowRenderer';
|
||||
import Diagram from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
addDiagrams();
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when using mermaid and ', function () {
|
||||
describe('when calling addEdges ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should handle edges with text', function () {
|
||||
const diag = new Diagram('graph TD;A-->|text ex|B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
expect(options.label.match('text ex')).toBeTruthy();
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges without text', function () {
|
||||
const diag = new Diagram('graph TD;A-->B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle open-ended edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges with styles defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with interpolation defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.curve).toBe('basis'); // mocked as string
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with text and styles defined', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.label.match('the text')).toBeTruthy();
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should set fill to "none" by default when handling edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should not set fill to none if fill is set in linkStyle', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const ganttDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gantt/) !== null;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const infoDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*info/) !== null;
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import { parser as mindmap } from './parser/mindmap';
|
||||
import * as mindmapDB from './mindmapDb';
|
||||
import { setLogLevel } from '../../logger';
|
||||
import { setLogLevel } from '../../diagram-api/diagramAPI';
|
||||
|
||||
describe('when parsing a mindmap ', function () {
|
||||
beforeEach(function () {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/** Created by knut on 15-01-14. */
|
||||
import { sanitizeText, getConfig } from '../../diagram-api/diagramAPI';
|
||||
import { log as _log } from '../../logger';
|
||||
import { sanitizeText, getConfig, log as _log } from '../../diagram-api/diagramAPI';
|
||||
|
||||
let nodes = [];
|
||||
let cnt = 0;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
const lineBreakRegex = /<br\s*\/?>/gi;
|
||||
import { select } from 'd3';
|
||||
import * as db from './mindmapDb';
|
||||
|
||||
|
@ -15,7 +14,6 @@ function wrap(text, width) {
|
|||
.reverse(),
|
||||
word,
|
||||
line = [],
|
||||
lineNumber = 0,
|
||||
lineHeight = 1.1, // ems
|
||||
y = text.attr('y'),
|
||||
dy = parseFloat(text.attr('dy')),
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const pieDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*pie/) !== null;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const requirementDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*requirement(Diagram)?/) !== null;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const sequenceDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*sequenceDiagram/) !== null;
|
||||
};
|
|
@ -1,12 +1,8 @@
|
|||
// import sequence from './parser/sequenceDiagram';
|
||||
// import sequenceDb from './sequenceDb';
|
||||
import * as configApi from '../../config';
|
||||
// import renderer from './sequenceRenderer';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
// import '../../diagram-api/diagramAPI';
|
||||
import Diagram from '../../Diagram';
|
||||
|
||||
// console.log('sequenceDiagram', sequenceDb);
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
addDiagrams();
|
||||
/**
|
||||
* @param conf
|
||||
* @param key
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const stateDetectorV2: DiagramDetector = (text, config) => {
|
||||
if (text.match(/^\s*stateDiagram-v2/) !== null) return true;
|
||||
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper')
|
||||
return true;
|
||||
return false;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const stateDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confired to only use new state diagrams this function should always return false
|
||||
// as in not signalling true for a legacy state diagram
|
||||
if (config?.state?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
return txt.match(/^\s*stateDiagram/) !== null;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const journeyDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*journey/) !== null;
|
||||
};
|
|
@ -2,8 +2,6 @@ import mermaid from './mermaid';
|
|||
import { mermaidAPI } from './mermaidAPI';
|
||||
import flowDb from './diagrams/flowchart/flowDb';
|
||||
import flowParser from './diagrams/flowchart/parser/flow';
|
||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
||||
import Diagram from './Diagram';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
|
||||
|
@ -58,149 +56,6 @@ describe('when using mermaid and ', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when calling addEdges ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should handle edges with text', function () {
|
||||
const diag = new Diagram('graph TD;A-->|text ex|B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
expect(options.label.match('text ex')).toBeTruthy();
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges without text', function () {
|
||||
const diag = new Diagram('graph TD;A-->B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle open-ended edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges with styles defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with interpolation defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.curve).toBe('basis'); // mocked as string
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with text and styles defined', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.label.match('the text')).toBeTruthy();
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should set fill to "none" by default when handling edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should not set fill to none if fill is set in linkStyle', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checking validity of input ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
|
|
Loading…
Reference in New Issue