mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-19 23:39:50 +02:00
WIP
This commit is contained in:
@@ -370,3 +370,7 @@ This document contains important guidelines and standards for working on the Mer
|
|||||||
- Documentation for diagram types is located in packages/mermaid/src/docs/
|
- Documentation for diagram types is located in packages/mermaid/src/docs/
|
||||||
- Add links to the sidenav when adding new diagram documentation
|
- Add links to the sidenav when adding new diagram documentation
|
||||||
- Use classDiagram.spec.js as a reference for writing diagram test files
|
- Use classDiagram.spec.js as a reference for writing diagram test files
|
||||||
|
|
||||||
|
Run the tests using: `vitest run packages/mermaid/src/diagrams/flowchart/parser/lezer-*.spec.ts`
|
||||||
|
|
||||||
|
|
||||||
|
@@ -211,6 +211,46 @@ class LezerFlowParser {
|
|||||||
// Look for patterns like:
|
// Look for patterns like:
|
||||||
// 1. A--text including URL space and send-->B
|
// 1. A--text including URL space and send-->B
|
||||||
// 2. A-- text including URL space and send -->B
|
// 2. A-- text including URL space and send -->B
|
||||||
|
// 3. A---|text|B (pipe-delimited)
|
||||||
|
|
||||||
|
// Check for simple edge pattern first (A---B, A--xB, etc.)
|
||||||
|
// But only if it's not part of a pipe-delimited pattern
|
||||||
|
if (
|
||||||
|
this.isSimpleEdgePattern(tokens[startIndex]) &&
|
||||||
|
!this.isPartOfPipeDelimitedPattern(tokens, startIndex)
|
||||||
|
) {
|
||||||
|
const patternTokens = [tokens[startIndex]];
|
||||||
|
console.log(
|
||||||
|
`UIO DEBUG: Analyzing simple edge pattern: ${patternTokens.map((t) => t.value).join(' ')}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const merged = this.detectAndMergeEdgePattern(patternTokens, tokens, startIndex);
|
||||||
|
if (merged) {
|
||||||
|
return {
|
||||||
|
mergedTokens: merged,
|
||||||
|
nextIndex: startIndex + 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for pipe-delimited pattern (A---|text|B)
|
||||||
|
if (this.isPipeDelimitedEdgePattern(tokens, startIndex)) {
|
||||||
|
const endIndex = this.findPipeDelimitedPatternEnd(tokens, startIndex);
|
||||||
|
if (endIndex > startIndex) {
|
||||||
|
const patternTokens = tokens.slice(startIndex, endIndex);
|
||||||
|
console.log(
|
||||||
|
`UIO DEBUG: Analyzing pipe-delimited edge pattern: ${patternTokens.map((t) => t.value).join(' ')}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const merged = this.detectAndMergeEdgePattern(patternTokens, tokens, startIndex);
|
||||||
|
if (merged) {
|
||||||
|
return {
|
||||||
|
mergedTokens: merged,
|
||||||
|
nextIndex: endIndex,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find the end of this potential edge pattern
|
// Find the end of this potential edge pattern
|
||||||
let endIndex = startIndex;
|
let endIndex = startIndex;
|
||||||
@@ -260,6 +300,97 @@ class LezerFlowParser {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if tokens starting at index form a pipe-delimited edge pattern
|
||||||
|
*/
|
||||||
|
private isPipeDelimitedEdgePattern(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[],
|
||||||
|
startIndex: number
|
||||||
|
): boolean {
|
||||||
|
if (startIndex + 3 >= tokens.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const first = tokens[startIndex];
|
||||||
|
const second = tokens[startIndex + 1];
|
||||||
|
|
||||||
|
return (
|
||||||
|
first.type === 'NODE_STRING' && this.endsWithArrow(first.value) && second.type === 'PIPE'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a single NODE_STRING token contains a simple edge pattern
|
||||||
|
*/
|
||||||
|
private isSimpleEdgePattern(token: { type: string; value: string }): boolean {
|
||||||
|
if (token.type !== 'NODE_STRING') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for patterns like A---B, A--xB, A--oB, A-->B, etc.
|
||||||
|
const simpleEdgePatterns = [
|
||||||
|
/^(.+?)(---?)([ox]?)(.+)$/, // A---B, A--B, A---xB, A--oB
|
||||||
|
/^(.+?)(==+)([ox]?)(.+)$/, // A===B, A==B, A===xB, A==oB
|
||||||
|
/^(.+?)(-\.-?)([ox]?)(.+)$/, // A-.-B, A-.B, A-.-xB, A-.oB
|
||||||
|
/^(.+?)(--+>)(.+)$/, // A-->B, A--->B
|
||||||
|
/^(.+?)(==+>)(.+)$/, // A==>B, A===>B
|
||||||
|
/^(.+?)(-\.->)(.+)$/, // A-.->B
|
||||||
|
];
|
||||||
|
|
||||||
|
return simpleEdgePatterns.some((pattern) => pattern.test(token.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a token is part of a pipe-delimited pattern (should not be treated as simple edge)
|
||||||
|
*/
|
||||||
|
private isPartOfPipeDelimitedPattern(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[],
|
||||||
|
startIndex: number
|
||||||
|
): boolean {
|
||||||
|
// Check if the current token could be the start of a pipe-delimited pattern
|
||||||
|
// This includes tokens that end with arrows (A---) or arrow+ending (A--x)
|
||||||
|
if (startIndex + 1 < tokens.length) {
|
||||||
|
const currentToken = tokens[startIndex];
|
||||||
|
const nextToken = tokens[startIndex + 1];
|
||||||
|
|
||||||
|
if (currentToken.type === 'NODE_STRING' && nextToken.type === 'PIPE') {
|
||||||
|
// Check if current token ends with arrow patterns that could be pipe-delimited
|
||||||
|
const arrowPatterns = [
|
||||||
|
/---?[ox]?$/, // ---, --, --x, --o, ---x, ---o
|
||||||
|
/==+[ox]?$/, // ==, ===, ==x, ==o, ===x, ===o
|
||||||
|
/-\.-?[ox]?$/, // -., -.-, -.x, -.o, -.-x, -.-o
|
||||||
|
];
|
||||||
|
|
||||||
|
return arrowPatterns.some((pattern) => pattern.test(currentToken.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the end index of a pipe-delimited pattern
|
||||||
|
*/
|
||||||
|
private findPipeDelimitedPatternEnd(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[],
|
||||||
|
startIndex: number
|
||||||
|
): number {
|
||||||
|
// Look for the closing pipe and target node
|
||||||
|
for (let i = startIndex + 2; i < tokens.length; i++) {
|
||||||
|
if (
|
||||||
|
tokens[i].type === 'PIPE' &&
|
||||||
|
i + 1 < tokens.length &&
|
||||||
|
tokens[i + 1].type === 'NODE_STRING'
|
||||||
|
) {
|
||||||
|
return i + 2; // Include the target node
|
||||||
|
}
|
||||||
|
if (tokens[i].type === 'SEMI') {
|
||||||
|
break; // End of statement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: does a NODE_STRING like "A-.-" followed by TagEnd '>' and a NODE_STRING target
|
* Helper: does a NODE_STRING like "A-.-" followed by TagEnd '>' and a NODE_STRING target
|
||||||
* represent a dotted simple edge A-.->B? If so, merge into canonical tokens.
|
* represent a dotted simple edge A-.->B? If so, merge into canonical tokens.
|
||||||
@@ -309,6 +440,231 @@ class LezerFlowParser {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if tokens match pipe-delimited pattern: A---|text|B
|
||||||
|
*/
|
||||||
|
private matchesPipeDelimitedPattern(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[]
|
||||||
|
): boolean {
|
||||||
|
if (tokens.length < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First token should be NODE_STRING ending with arrow (like "A---", "A==>", "A-.-")
|
||||||
|
const first = tokens[0];
|
||||||
|
if (first.type !== 'NODE_STRING' || !this.endsWithArrow(first.value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second token should be PIPE
|
||||||
|
if (tokens[1].type !== 'PIPE') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the closing pipe and target
|
||||||
|
let closingPipeIndex = -1;
|
||||||
|
for (let i = 2; i < tokens.length; i++) {
|
||||||
|
if (tokens[i].type === 'PIPE') {
|
||||||
|
closingPipeIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closingPipeIndex === -1 || closingPipeIndex >= tokens.length - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last token should be NODE_STRING (target)
|
||||||
|
const last = tokens[tokens.length - 1];
|
||||||
|
if (last.type !== 'NODE_STRING') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All tokens between pipes should be text tokens
|
||||||
|
const textTokens = tokens.slice(2, closingPipeIndex);
|
||||||
|
return textTokens.every((t) => this.isTextToken(t.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge pipe-delimited pattern tokens into proper edge format
|
||||||
|
*/
|
||||||
|
private mergePipeDelimitedPattern(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[]
|
||||||
|
): { type: string; value: string; from: number; to: number }[] {
|
||||||
|
const firstToken = tokens[0];
|
||||||
|
|
||||||
|
// Extract source node ID and arrow from first token (e.g., "A---" -> "A" + "---")
|
||||||
|
const { sourceId, arrow } = this.extractSourceAndArrow(firstToken.value);
|
||||||
|
|
||||||
|
// Find the closing pipe
|
||||||
|
let closingPipeIndex = -1;
|
||||||
|
for (let i = 2; i < tokens.length; i++) {
|
||||||
|
if (tokens[i].type === 'PIPE') {
|
||||||
|
closingPipeIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract text from tokens between pipes
|
||||||
|
const textTokens = tokens.slice(2, closingPipeIndex);
|
||||||
|
const edgeText = textTokens
|
||||||
|
.map((t) => t.value)
|
||||||
|
.join(' ')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
const targetToken = tokens[tokens.length - 1];
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`UIO DEBUG: Pipe-delimited merge - source: ${sourceId}, arrow: ${arrow}, text: "${edgeText}", target: ${targetToken.value}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'NODE_STRING',
|
||||||
|
value: sourceId,
|
||||||
|
from: firstToken.from,
|
||||||
|
to: firstToken.from + sourceId.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: arrow,
|
||||||
|
from: firstToken.from + sourceId.length,
|
||||||
|
to: firstToken.from + sourceId.length + arrow.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'PIPE',
|
||||||
|
value: '|',
|
||||||
|
from: firstToken.from + sourceId.length + arrow.length,
|
||||||
|
to: firstToken.from + sourceId.length + arrow.length + 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'NODE_STRING',
|
||||||
|
value: edgeText,
|
||||||
|
from: firstToken.from + sourceId.length + arrow.length + 1,
|
||||||
|
to: firstToken.from + sourceId.length + arrow.length + 1 + edgeText.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'PIPE',
|
||||||
|
value: '|',
|
||||||
|
from: firstToken.from + sourceId.length + arrow.length + 1 + edgeText.length,
|
||||||
|
to: firstToken.from + sourceId.length + arrow.length + 2 + edgeText.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'NODE_STRING',
|
||||||
|
value: targetToken.value,
|
||||||
|
from: targetToken.from,
|
||||||
|
to: targetToken.to,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string ends with an arrow pattern
|
||||||
|
*/
|
||||||
|
private endsWithArrow(value: string): boolean {
|
||||||
|
return (
|
||||||
|
value.endsWith('---') ||
|
||||||
|
value.endsWith('-->') ||
|
||||||
|
value.endsWith('==>') ||
|
||||||
|
value.endsWith('===') ||
|
||||||
|
value.endsWith('-.-') ||
|
||||||
|
value.endsWith('-.->') ||
|
||||||
|
value.endsWith('--') ||
|
||||||
|
value.endsWith('==')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract source node ID and arrow from a combined string
|
||||||
|
*/
|
||||||
|
private extractSourceAndArrow(value: string): { sourceId: string; arrow: string } {
|
||||||
|
// Try different arrow patterns, longest first
|
||||||
|
const patterns = ['--->', '===>', '-.->', '---', '===', '-.-', '-->', '==>', '--', '=='];
|
||||||
|
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (value.endsWith(pattern)) {
|
||||||
|
const sourceId = value.substring(0, value.length - pattern.length);
|
||||||
|
return { sourceId, arrow: pattern };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback - shouldn't happen if endsWithArrow returned true
|
||||||
|
return { sourceId: value, arrow: '' };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge a simple edge pattern token (A---B) into proper edge format
|
||||||
|
*/
|
||||||
|
private mergeSimpleEdgePattern(token: {
|
||||||
|
type: string;
|
||||||
|
value: string;
|
||||||
|
from: number;
|
||||||
|
to: number;
|
||||||
|
}): { type: string; value: string; from: number; to: number }[] {
|
||||||
|
const value = token.value;
|
||||||
|
|
||||||
|
// Try to match different simple edge patterns
|
||||||
|
const patterns = [
|
||||||
|
{ regex: /^(.+?)(---?)([ox])(.+)$/, hasEnding: true }, // A---xB, A--oB
|
||||||
|
{ regex: /^(.+?)(---?)(.+)$/, hasEnding: false }, // A---B, A--B
|
||||||
|
{ regex: /^(.+?)(==+)([ox])(.+)$/, hasEnding: true }, // A===xB, A==oB
|
||||||
|
{ regex: /^(.+?)(==+)(.+)$/, hasEnding: false }, // A===B, A==B
|
||||||
|
{ regex: /^(.+?)(-\.-?)([ox])(.+)$/, hasEnding: true }, // A-.-xB, A-.oB
|
||||||
|
{ regex: /^(.+?)(-\.-?)(.+)$/, hasEnding: false }, // A-.-B, A-.B
|
||||||
|
{ regex: /^(.+?)(--+>)(.+)$/, hasEnding: false }, // A-->B, A--->B
|
||||||
|
{ regex: /^(.+?)(==+>)(.+)$/, hasEnding: false }, // A==>B, A===>B
|
||||||
|
{ regex: /^(.+?)(-\.->)(.+)$/, hasEnding: false }, // A-.->B
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
const match = value.match(pattern.regex);
|
||||||
|
if (match) {
|
||||||
|
const sourceId = match[1];
|
||||||
|
let arrow: string;
|
||||||
|
let targetId: string;
|
||||||
|
|
||||||
|
if (pattern.hasEnding) {
|
||||||
|
// Pattern with ending: source, arrow, ending, target
|
||||||
|
arrow = match[2] + match[3]; // arrow + ending (x, o)
|
||||||
|
targetId = match[4];
|
||||||
|
} else {
|
||||||
|
// Pattern without ending: source, arrow, target
|
||||||
|
arrow = match[2];
|
||||||
|
targetId = match[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`UIO DEBUG: Simple edge merge - source: ${sourceId}, arrow: ${arrow}, target: ${targetId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'NODE_STRING',
|
||||||
|
value: sourceId,
|
||||||
|
from: token.from,
|
||||||
|
to: token.from + sourceId.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: arrow,
|
||||||
|
from: token.from + sourceId.length,
|
||||||
|
to: token.from + sourceId.length + arrow.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'NODE_STRING',
|
||||||
|
value: targetId,
|
||||||
|
from: token.from + sourceId.length + arrow.length,
|
||||||
|
to: token.to,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback - return original token if no pattern matches
|
||||||
|
console.log(`UIO DEBUG: No simple edge pattern matched for: ${value}`);
|
||||||
|
return [token];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect and merge specific edge patterns
|
* Detect and merge specific edge patterns
|
||||||
* @param patternTokens - The tokens that form the potential edge pattern
|
* @param patternTokens - The tokens that form the potential edge pattern
|
||||||
@@ -320,6 +676,17 @@ class LezerFlowParser {
|
|||||||
allTokens: { type: string; value: string; from: number; to: number }[],
|
allTokens: { type: string; value: string; from: number; to: number }[],
|
||||||
startIndex: number
|
startIndex: number
|
||||||
): { type: string; value: string; from: number; to: number }[] | null {
|
): { type: string; value: string; from: number; to: number }[] | null {
|
||||||
|
// Pattern 0: Simple edge pattern A---B, A--xB, A-->B (single token)
|
||||||
|
if (patternTokens.length === 1 && this.isSimpleEdgePattern(patternTokens[0])) {
|
||||||
|
return this.mergeSimpleEdgePattern(patternTokens[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern 3: Pipe-delimited edge text A---|text|B
|
||||||
|
// Tokens: [A---, |, text, tokens..., |, B]
|
||||||
|
if (this.matchesPipeDelimitedPattern(patternTokens)) {
|
||||||
|
return this.mergePipeDelimitedPattern(patternTokens);
|
||||||
|
}
|
||||||
|
|
||||||
// Pattern 1: A--text including URL space and send-->B
|
// Pattern 1: A--text including URL space and send-->B
|
||||||
// Tokens: [A--text, including, URL, space, and, send--, >, B]
|
// Tokens: [A--text, including, URL, space, and, send--, >, B]
|
||||||
if (this.matchesPattern1(patternTokens)) {
|
if (this.matchesPattern1(patternTokens)) {
|
||||||
@@ -2964,7 +3331,7 @@ class LezerFlowParser {
|
|||||||
);
|
);
|
||||||
} else if (hasEmbeddedArrowWithNode) {
|
} else if (hasEmbeddedArrowWithNode) {
|
||||||
// Extract the actual node ID and target node from the combined token (e.g., "A--xv" -> "A" and "v")
|
// Extract the actual node ID and target node from the combined token (e.g., "A--xv" -> "A" and "v")
|
||||||
const match = /^(.+?)--[xo](.+)$/.exec(sourceToken.value);
|
const match = /^(.+?)--[ox](.+)$/.exec(sourceToken.value);
|
||||||
if (match) {
|
if (match) {
|
||||||
sourceId = match[1]; // "A"
|
sourceId = match[1]; // "A"
|
||||||
const targetNodeId = match[2]; // "v"
|
const targetNodeId = match[2]; // "v"
|
||||||
@@ -3016,7 +3383,7 @@ class LezerFlowParser {
|
|||||||
let edgeInfo;
|
let edgeInfo;
|
||||||
if (hasEmbeddedArrowWithPipe) {
|
if (hasEmbeddedArrowWithPipe) {
|
||||||
// For embedded arrows like "A--x", extract the arrow and handle pipe-delimited text
|
// For embedded arrows like "A--x", extract the arrow and handle pipe-delimited text
|
||||||
const arrowMatch = /--([xo])$/.exec(sourceToken.value);
|
const arrowMatch = /--([ox])$/.exec(sourceToken.value);
|
||||||
if (arrowMatch) {
|
if (arrowMatch) {
|
||||||
const arrowType = arrowMatch[1]; // 'x' or 'o'
|
const arrowType = arrowMatch[1]; // 'x' or 'o'
|
||||||
const arrow = `--${arrowType}`;
|
const arrow = `--${arrowType}`;
|
||||||
@@ -3034,7 +3401,7 @@ class LezerFlowParser {
|
|||||||
}
|
}
|
||||||
} else if (hasEmbeddedArrowWithNode) {
|
} else if (hasEmbeddedArrowWithNode) {
|
||||||
// For embedded arrows like "A--xv", extract the arrow and target node
|
// For embedded arrows like "A--xv", extract the arrow and target node
|
||||||
const match = /^(.+?)--([xo])(.+)$/.exec(sourceToken.value);
|
const match = /^(.+?)--([ox])(.+)$/.exec(sourceToken.value);
|
||||||
if (match) {
|
if (match) {
|
||||||
const arrowType = match[2]; // 'x' or 'o'
|
const arrowType = match[2]; // 'x' or 'o'
|
||||||
const arrow = `--${arrowType}`;
|
const arrow = `--${arrowType}`;
|
||||||
|
114
packages/mermaid/src/diagrams/sequence/demo.spec.js
Normal file
114
packages/mermaid/src/diagrams/sequence/demo.spec.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import { vi } from 'vitest';
|
||||||
|
import { setSiteConfig } from '../../diagram-api/diagramAPI.js';
|
||||||
|
import mermaidAPI from '../../mermaidAPI.js';
|
||||||
|
import { Diagram } from '../../Diagram.js';
|
||||||
|
import { addDiagrams } from '../../diagram-api/diagram-orchestration.js';
|
||||||
|
import { SequenceDB } from './sequenceDb.js';
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
// Is required to load the sequence diagram
|
||||||
|
await Diagram.fromText('sequenceDiagram');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence diagrams require their own very special version of a mocked d3 module
|
||||||
|
* diagrams/sequence/svgDraw uses statements like this with d3 nodes: (note the [0][0])
|
||||||
|
*
|
||||||
|
* // in drawText(...)
|
||||||
|
* textHeight += (textElem._groups || textElem)[0][0].getBBox().height;
|
||||||
|
*/
|
||||||
|
vi.mock('d3', () => {
|
||||||
|
const NewD3 = function () {
|
||||||
|
function returnThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
append: function () {
|
||||||
|
return NewD3();
|
||||||
|
},
|
||||||
|
lower: returnThis,
|
||||||
|
attr: returnThis,
|
||||||
|
style: returnThis,
|
||||||
|
text: returnThis,
|
||||||
|
// [0][0] (below) is required by drawText() in packages/mermaid/src/diagrams/sequence/svgDraw.js
|
||||||
|
0: {
|
||||||
|
0: {
|
||||||
|
getBBox: function () {
|
||||||
|
return {
|
||||||
|
height: 10,
|
||||||
|
width: 20,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
select: function () {
|
||||||
|
return new NewD3();
|
||||||
|
},
|
||||||
|
|
||||||
|
selectAll: function () {
|
||||||
|
return new NewD3();
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: In d3 these are CurveFactory types, not strings
|
||||||
|
curveBasis: 'basis',
|
||||||
|
curveBasisClosed: 'basisClosed',
|
||||||
|
curveBasisOpen: 'basisOpen',
|
||||||
|
curveBumpX: 'bumpX',
|
||||||
|
curveBumpY: 'bumpY',
|
||||||
|
curveBundle: 'bundle',
|
||||||
|
curveCardinalClosed: 'cardinalClosed',
|
||||||
|
curveCardinalOpen: 'cardinalOpen',
|
||||||
|
curveCardinal: 'cardinal',
|
||||||
|
curveCatmullRomClosed: 'catmullRomClosed',
|
||||||
|
curveCatmullRomOpen: 'catmullRomOpen',
|
||||||
|
curveCatmullRom: 'catmullRom',
|
||||||
|
curveLinear: 'linear',
|
||||||
|
curveLinearClosed: 'linearClosed',
|
||||||
|
curveMonotoneX: 'monotoneX',
|
||||||
|
curveMonotoneY: 'monotoneY',
|
||||||
|
curveNatural: 'natural',
|
||||||
|
curveStep: 'step',
|
||||||
|
curveStepAfter: 'stepAfter',
|
||||||
|
curveStepBefore: 'stepBefore',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// -------------------------------
|
||||||
|
|
||||||
|
addDiagrams();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param conf
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
function addConf(conf, key, value) {
|
||||||
|
if (value !== undefined) {
|
||||||
|
conf[key] = value;
|
||||||
|
}
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// const parser = sequence.parser;
|
||||||
|
|
||||||
|
describe('when parsing a sequenceDiagram', function () {
|
||||||
|
let diagram;
|
||||||
|
beforeEach(async function () {
|
||||||
|
diagram = await Diagram.fromText(`
|
||||||
|
sequenceDiagram
|
||||||
|
Alice->Bob:Hello Bob, how are you?
|
||||||
|
Note right of Bob: Bob thinks
|
||||||
|
Bob-->Alice: I am good thanks!`);
|
||||||
|
});
|
||||||
|
it('should parse', async () => {
|
||||||
|
const diagram = await Diagram.fromText(`
|
||||||
|
sequenceDiagram
|
||||||
|
participant Alice@{ type : database }
|
||||||
|
Bob->>Alice: Hi Alice
|
||||||
|
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
Reference in New Issue
Block a user