mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-19 23:39:50 +02:00
feat: Ensure proper detection for flowcharts
This commit is contained in:
@@ -46,7 +46,9 @@ export const detectType = function (text: string, config?: MermaidConfig): strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnknownDiagramError(`No diagram type detected for text: ${text}`);
|
throw new UnknownDiagramError(
|
||||||
|
`No diagram type detected matching given configuration for text: ${text}`
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinition[]) => {
|
export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinition[]) => {
|
||||||
|
@@ -41,5 +41,42 @@ describe('diagram-orchestration', () => {
|
|||||||
expect(detectType(text)).toBe(expected);
|
expect(detectType(text)).toBe(expected);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it('should detect proper flowchart type based on config', () => {
|
||||||
|
// graph & dagre-d3 => flowchart
|
||||||
|
expect(detectType('graph TD; A-->B')).toBe('flowchart');
|
||||||
|
// graph & dagre-d3 => flowchart
|
||||||
|
expect(detectType('graph TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' } })).toBe(
|
||||||
|
'flowchart'
|
||||||
|
);
|
||||||
|
// flowchart & dagre-d3 => error
|
||||||
|
expect(() =>
|
||||||
|
detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' } })
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
'"No diagram type detected matching given configuration for text: flowchart TD; A-->B"'
|
||||||
|
);
|
||||||
|
|
||||||
|
// graph & dagre-wrapper => flowchart-v2
|
||||||
|
expect(
|
||||||
|
detectType('graph TD; A-->B', { flowchart: { defaultRenderer: 'dagre-wrapper' } })
|
||||||
|
).toBe('flowchart-v2');
|
||||||
|
// flowchart ==> flowchart-v2
|
||||||
|
expect(detectType('flowchart TD; A-->B')).toBe('flowchart-v2');
|
||||||
|
// flowchart && dagre-wrapper ==> flowchart-v2
|
||||||
|
expect(
|
||||||
|
detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-wrapper' } })
|
||||||
|
).toBe('flowchart-v2');
|
||||||
|
// flowchart && elk ==> flowchart-elk
|
||||||
|
expect(detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'elk' } })).toBe(
|
||||||
|
'flowchart-elk'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not detect flowchart if pie contains flowchart', () => {
|
||||||
|
expect(
|
||||||
|
detectType(`pie title: "flowchart"
|
||||||
|
flowchart: 1 "pie" pie: 2 "pie"`)
|
||||||
|
).toBe('pie');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -68,10 +68,8 @@ export const addDiagrams = () => {
|
|||||||
requirement,
|
requirement,
|
||||||
sequence,
|
sequence,
|
||||||
flowchartElk,
|
flowchartElk,
|
||||||
// TODO @knsv: Should v2 come before flowchart?
|
|
||||||
// This will fail few unit tests as they expect graph to be detected as flowchart, but it is detected as flowchart-v2.
|
|
||||||
flowchart,
|
|
||||||
flowchartV2,
|
flowchartV2,
|
||||||
|
flowchart,
|
||||||
mindmap,
|
mindmap,
|
||||||
timeline,
|
timeline,
|
||||||
git,
|
git,
|
||||||
|
@@ -20,8 +20,8 @@ describe('DiagramAPI', () => {
|
|||||||
|
|
||||||
it('should handle diagram registrations', () => {
|
it('should handle diagram registrations', () => {
|
||||||
expect(() => getDiagram('loki')).toThrow();
|
expect(() => getDiagram('loki')).toThrow();
|
||||||
expect(() => detectType('loki diagram')).toThrow(
|
expect(() => detectType('loki diagram')).toThrowErrorMatchingInlineSnapshot(
|
||||||
'No diagram type detected for text: loki diagram'
|
'"No diagram type detected matching given configuration for text: loki diagram"'
|
||||||
);
|
);
|
||||||
const detector: DiagramDetector = (str: string) => {
|
const detector: DiagramDetector = (str: string) => {
|
||||||
return str.match('loki') !== null;
|
return str.match('loki') !== null;
|
||||||
|
@@ -61,8 +61,8 @@ Expecting 'TXT', got 'NEWLINE'"
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should throw the right error for unregistered diagrams', async () => {
|
test('should throw the right error for unregistered diagrams', async () => {
|
||||||
await expect(getDiagramFromText('thor TD; A-->B')).rejects.toThrowError(
|
await expect(getDiagramFromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'No diagram type detected for text: thor TD; A-->B'
|
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -4,15 +4,15 @@ import type { ExternalDiagramDefinition } from '../../diagram-api/types';
|
|||||||
const id = 'flowchart-v2';
|
const id = 'flowchart-v2';
|
||||||
|
|
||||||
const detector: DiagramDetector = (txt, config) => {
|
const detector: DiagramDetector = (txt, config) => {
|
||||||
if (config?.flowchart?.defaultRenderer === 'dagre-d3') {
|
if (
|
||||||
return false;
|
config?.flowchart?.defaultRenderer === 'dagre-d3' ||
|
||||||
}
|
config?.flowchart?.defaultRenderer === 'elk'
|
||||||
if (config?.flowchart?.defaultRenderer === 'elk') {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have configured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram
|
// If we have configured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram
|
||||||
if (txt.match(/^\s*graph/) !== null) {
|
if (txt.match(/^\s*graph/) !== null && config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return txt.match(/^\s*flowchart/) !== null;
|
return txt.match(/^\s*flowchart/) !== null;
|
||||||
|
@@ -5,10 +5,10 @@ const id = 'flowchart';
|
|||||||
const detector: DiagramDetector = (txt, config) => {
|
const detector: DiagramDetector = (txt, config) => {
|
||||||
// If we have conferred to only use new flow charts this function should always return false
|
// If we have conferred to only use new flow charts this function should always return false
|
||||||
// as in not signalling true for a legacy flowchart
|
// as in not signalling true for a legacy flowchart
|
||||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
|
if (
|
||||||
return false;
|
config?.flowchart?.defaultRenderer === 'dagre-wrapper' ||
|
||||||
}
|
config?.flowchart?.defaultRenderer === 'elk'
|
||||||
if (config?.flowchart?.defaultRenderer === 'elk') {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return txt.match(/^\s*graph/) !== null;
|
return txt.match(/^\s*graph/) !== null;
|
||||||
|
@@ -12,6 +12,7 @@ import type { ParseErrorFunction } from './Diagram';
|
|||||||
import { isDetailedError } from './utils';
|
import { isDetailedError } from './utils';
|
||||||
import type { DetailedError } from './utils';
|
import type { DetailedError } from './utils';
|
||||||
import { ExternalDiagramDefinition } from './diagram-api/types';
|
import { ExternalDiagramDefinition } from './diagram-api/types';
|
||||||
|
import { UnknownDiagramError } from './errors';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
MermaidConfig,
|
MermaidConfig,
|
||||||
@@ -20,6 +21,7 @@ export type {
|
|||||||
ParseErrorFunction,
|
ParseErrorFunction,
|
||||||
RenderResult,
|
RenderResult,
|
||||||
ParseOptions,
|
ParseOptions,
|
||||||
|
UnknownDiagramError,
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface RunOptions {
|
export interface RunOptions {
|
||||||
|
@@ -678,7 +678,7 @@ describe('mermaidAPI', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
mermaidAPI.parse('this is not a mermaid diagram definition')
|
mermaidAPI.parse('this is not a mermaid diagram definition')
|
||||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'"No diagram type detected for text: this is not a mermaid diagram definition"'
|
'"No diagram type detected matching given configuration for text: this is not a mermaid diagram definition"'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('returns false for invalid definition with silent option', async () => {
|
it('returns false for invalid definition with silent option', async () => {
|
||||||
|
Reference in New Issue
Block a user