snapshot of https://github.com/excalidraw/excalidraw.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Tests / test (push) Failing after 15s
Some checks failed
Tests / test (push) Failing after 15s
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
import { isValidMermaidSyntax } from "./mermaidValidation";
|
||||
|
||||
describe("isValidMermaidSyntax", () => {
|
||||
describe("empty and whitespace content", () => {
|
||||
it("should return false for empty string", () => {
|
||||
expect(isValidMermaidSyntax("")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for whitespace-only content", () => {
|
||||
expect(isValidMermaidSyntax(" ")).toBe(false);
|
||||
expect(isValidMermaidSyntax("\n\n")).toBe(false);
|
||||
expect(isValidMermaidSyntax("\t\t")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("balanced brackets, braces, and parentheses", () => {
|
||||
it("should return true for content with balanced brackets", () => {
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA[Start]")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A[Node] --> B[End]")).toBe(true);
|
||||
expect(isValidMermaidSyntax("[[nested]]")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for content with balanced braces", () => {
|
||||
expect(isValidMermaidSyntax("graph TD\nA{Decision}")).toBe(true);
|
||||
expect(isValidMermaidSyntax("{{nested}}")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for content with balanced parentheses", () => {
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA(Round)")).toBe(true);
|
||||
expect(isValidMermaidSyntax("((nested))")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for content with multiple balanced delimiters", () => {
|
||||
expect(isValidMermaidSyntax("A[Node] --> B{Decision} --> C(End)")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
isValidMermaidSyntax("flowchart\nA[Start] --> B{Check} --> C(Done)"),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unbalanced brackets", () => {
|
||||
it("should return false for single unclosed bracket", () => {
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA[Start")).toBe(false);
|
||||
expect(isValidMermaidSyntax("A[Node")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for multiple unclosed brackets", () => {
|
||||
expect(isValidMermaidSyntax("A[Node\nB[Another")).toBe(false);
|
||||
expect(isValidMermaidSyntax("[[[text")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when closing brackets outnumber opening brackets", () => {
|
||||
expect(isValidMermaidSyntax("A]")).toBe(false);
|
||||
expect(isValidMermaidSyntax("text]]]")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unbalanced braces", () => {
|
||||
it("should return false for single unclosed brace", () => {
|
||||
expect(isValidMermaidSyntax("graph TD\nA{Decision")).toBe(false);
|
||||
expect(isValidMermaidSyntax("A{Node")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for multiple unclosed braces", () => {
|
||||
expect(isValidMermaidSyntax("A{Node\nB{Another")).toBe(false);
|
||||
expect(isValidMermaidSyntax("{{{text")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when closing braces outnumber opening braces", () => {
|
||||
expect(isValidMermaidSyntax("A}")).toBe(false);
|
||||
expect(isValidMermaidSyntax("text}}}")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unbalanced parentheses", () => {
|
||||
it("should return false for single unclosed parenthesis", () => {
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA(Round")).toBe(false);
|
||||
expect(isValidMermaidSyntax("A(Node")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for multiple unclosed parentheses", () => {
|
||||
expect(isValidMermaidSyntax("A(Node\nB(Another")).toBe(false);
|
||||
expect(isValidMermaidSyntax("(((text")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when closing parentheses outnumber opening parentheses", () => {
|
||||
expect(isValidMermaidSyntax("A)")).toBe(false);
|
||||
expect(isValidMermaidSyntax("text)))")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("incomplete patterns at end of line", () => {
|
||||
it("should return false for arrow patterns", () => {
|
||||
expect(isValidMermaidSyntax("A -->")).toBe(false);
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA --")).toBe(false);
|
||||
expect(isValidMermaidSyntax("B --.")).toBe(false);
|
||||
expect(isValidMermaidSyntax("C ==>")).toBe(false);
|
||||
expect(isValidMermaidSyntax("D ==")).toBe(false);
|
||||
expect(isValidMermaidSyntax("E ~~")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for colon patterns", () => {
|
||||
expect(isValidMermaidSyntax("A::")).toBe(false);
|
||||
expect(isValidMermaidSyntax("B:")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for pipe and ampersand patterns", () => {
|
||||
expect(isValidMermaidSyntax("A|")).toBe(false);
|
||||
expect(isValidMermaidSyntax("B&")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true when incomplete patterns are not at the end", () => {
|
||||
expect(isValidMermaidSyntax("A --> B")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A -- text --> B")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A: complete")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A & B")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A | B")).toBe(true);
|
||||
});
|
||||
|
||||
it("should only check the last line for incomplete patterns", () => {
|
||||
expect(isValidMermaidSyntax("A -->\nB --> C")).toBe(true);
|
||||
expect(isValidMermaidSyntax("A:\nB --> C")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("complex real-world scenarios", () => {
|
||||
it("should return true for valid flowchart", () => {
|
||||
const mermaid = `flowchart TD
|
||||
Start[Start] --> Decision{Is it?}
|
||||
Decision -->|Yes| End1[End 1]
|
||||
Decision -->|No| End2[End 2]`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true for valid sequence diagram", () => {
|
||||
const mermaid = `sequenceDiagram
|
||||
Alice->>John: Hello John
|
||||
John-->>Alice: Great!`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for incomplete flowchart (unclosed bracket)", () => {
|
||||
const mermaid = `flowchart TD
|
||||
Start[Start --> Decision{Is it?}
|
||||
Decision -->|Yes| End[End]`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for flowchart with incomplete arrow at end", () => {
|
||||
const mermaid = `flowchart TD
|
||||
Start[Start] --> Decision{Is it?}
|
||||
Decision -->`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true for diagram with multiple node types", () => {
|
||||
const mermaid = `graph LR
|
||||
A[Square] --> B(Round)
|
||||
B --> C{Diamond}
|
||||
C --> D[Square]`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for streaming content that is incomplete", () => {
|
||||
// Simulates partial AI-generated content during streaming
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA[Start] --")).toBe(false);
|
||||
expect(isValidMermaidSyntax("flowchart LR\nA[Start")).toBe(false);
|
||||
expect(isValidMermaidSyntax("graph TD\nA{Decision")).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true for complete multi-line diagram", () => {
|
||||
const mermaid = `graph TB
|
||||
subgraph one
|
||||
a1[First]
|
||||
end
|
||||
subgraph two
|
||||
a2[Second]
|
||||
end
|
||||
a1 --> a2`;
|
||||
expect(isValidMermaidSyntax(mermaid)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("edge cases", () => {
|
||||
it("should handle content with only delimiters", () => {
|
||||
expect(isValidMermaidSyntax("[]")).toBe(true);
|
||||
expect(isValidMermaidSyntax("{}")).toBe(true);
|
||||
expect(isValidMermaidSyntax("()")).toBe(true);
|
||||
expect(isValidMermaidSyntax("[")).toBe(false);
|
||||
expect(isValidMermaidSyntax("{")).toBe(false);
|
||||
expect(isValidMermaidSyntax("(")).toBe(false);
|
||||
});
|
||||
|
||||
it("should handle mixed valid and invalid scenarios", () => {
|
||||
expect(isValidMermaidSyntax("A[B] -->")).toBe(false);
|
||||
expect(isValidMermaidSyntax("A[B --")).toBe(false);
|
||||
expect(isValidMermaidSyntax("A{B:")).toBe(false);
|
||||
});
|
||||
|
||||
it("should handle strings with special characters", () => {
|
||||
expect(isValidMermaidSyntax("A[Node with spaces]")).toBe(true);
|
||||
expect(
|
||||
isValidMermaidSyntax("A[Node with 'quotes' and numbers 123]"),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("should trim content before validation", () => {
|
||||
expect(isValidMermaidSyntax(" A[Node] \n")).toBe(true);
|
||||
expect(isValidMermaidSyntax("\n\nA[Node]\n\n")).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user