feat: paste as mermaid if applicable (#8116)

This commit is contained in:
David Luzar 2024-06-11 19:19:22 +02:00 committed by GitHub
parent 63dee03ef0
commit 22b39277f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 179 additions and 27 deletions

View file

@ -1,28 +1,12 @@
import { act, render, waitFor } from "./test-utils";
import { Excalidraw } from "../index";
import React from "react";
import { expect, vi } from "vitest";
import * as MermaidToExcalidraw from "@excalidraw/mermaid-to-excalidraw";
import { expect } from "vitest";
import { getTextEditor, updateTextEditor } from "./queries/dom";
import { mockMermaidToExcalidraw } from "./helpers/mocks";
vi.mock("@excalidraw/mermaid-to-excalidraw", async (importActual) => {
const module = (await importActual()) as any;
return {
__esModule: true,
...module,
};
});
const parseMermaidToExcalidrawSpy = vi.spyOn(
MermaidToExcalidraw,
"parseMermaidToExcalidraw",
);
parseMermaidToExcalidrawSpy.mockImplementation(
async (
definition: string,
options?: MermaidToExcalidraw.MermaidOptions | undefined,
) => {
mockMermaidToExcalidraw({
mockRef: true,
parseMermaidToExcalidraw: async (definition) => {
const firstLine = definition.split("\n")[0];
return new Promise((resolve, reject) => {
if (firstLine === "flowchart TD") {
@ -88,12 +72,6 @@ parseMermaidToExcalidrawSpy.mockImplementation(
}
});
},
);
vi.spyOn(React, "useRef").mockReturnValue({
current: {
parseMermaidToExcalidraw: parseMermaidToExcalidrawSpy,
},
});
describe("Test <MermaidToExcalidraw/>", () => {

View file

@ -13,6 +13,7 @@ import type { NormalizedZoomValue } from "../types";
import { API } from "./helpers/api";
import { createPasteEvent, serializeAsClipboardJSON } from "../clipboard";
import { arrayToMap } from "../utils";
import { mockMermaidToExcalidraw } from "./helpers/mocks";
const { h } = window;
@ -435,3 +436,83 @@ describe("pasting & frames", () => {
});
});
});
describe("clipboard - pasting mermaid definition", () => {
beforeAll(() => {
mockMermaidToExcalidraw({
parseMermaidToExcalidraw: async (definition) => {
const lines = definition.split("\n");
return new Promise((resolve, reject) => {
if (lines.some((line) => line === "flowchart TD")) {
resolve({
elements: [
{
id: "rect1",
type: "rectangle",
groupIds: [],
x: 0,
y: 0,
width: 69.703125,
height: 44,
strokeWidth: 2,
label: {
groupIds: [],
text: "A",
fontSize: 20,
},
link: null,
},
],
});
} else {
reject(new Error("ERROR"));
}
});
},
});
});
it("should detect and paste as mermaid", async () => {
const text = "flowchart TD\nA";
pasteWithCtrlCmdV(text);
await waitFor(() => {
expect(h.elements.length).toEqual(2);
expect(h.elements).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "rectangle" }),
expect.objectContaining({ type: "text", text: "A" }),
]),
);
});
});
it("should support directives", async () => {
const text = "%%{init: { **config** } }%%\nflowchart TD\nA";
pasteWithCtrlCmdV(text);
await waitFor(() => {
expect(h.elements.length).toEqual(2);
expect(h.elements).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "rectangle" }),
expect.objectContaining({ type: "text", text: "A" }),
]),
);
});
});
it("should paste as normal text if invalid mermaid", async () => {
const text = "flowchart TD xx\nA";
pasteWithCtrlCmdV(text);
await waitFor(() => {
expect(h.elements.length).toEqual(2);
expect(h.elements).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "text", text: "flowchart TD xx" }),
expect.objectContaining({ type: "text", text: "A" }),
]),
);
});
});
});

View file

@ -0,0 +1,32 @@
import { vi } from "vitest";
import * as MermaidToExcalidraw from "@excalidraw/mermaid-to-excalidraw";
import type { parseMermaidToExcalidraw } from "@excalidraw/mermaid-to-excalidraw";
import React from "react";
export const mockMermaidToExcalidraw = (opts: {
parseMermaidToExcalidraw: typeof parseMermaidToExcalidraw;
mockRef?: boolean;
}) => {
vi.mock("@excalidraw/mermaid-to-excalidraw", async (importActual) => {
const module = (await importActual()) as any;
return {
__esModule: true,
...module,
};
});
const parseMermaidToExcalidrawSpy = vi.spyOn(
MermaidToExcalidraw,
"parseMermaidToExcalidraw",
);
parseMermaidToExcalidrawSpy.mockImplementation(opts.parseMermaidToExcalidraw);
if (opts.mockRef) {
vi.spyOn(React, "useRef").mockReturnValue({
current: {
parseMermaidToExcalidraw: parseMermaidToExcalidrawSpy,
},
});
}
};