From ec26aeead231908f46ff2efaf4ee39c96e19805d Mon Sep 17 00:00:00 2001 From: "Daniel J. Geiger" <1852529+DanielJGeiger@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:33:34 -0500 Subject: [PATCH] refactor: Refactor and add a test --- src/element/subtypes/global.d.ts | 6 --- src/element/subtypes/mathjax/index.ts | 6 +++ .../mathjax/tests/implementation.test.tsx | 38 +++++++++++++++++-- src/element/subtypes/use.ts | 11 +++--- src/global.d.ts | 2 + src/tests/subtypes.test.tsx | 7 ++-- 6 files changed, 52 insertions(+), 18 deletions(-) delete mode 100644 src/element/subtypes/global.d.ts diff --git a/src/element/subtypes/global.d.ts b/src/element/subtypes/global.d.ts deleted file mode 100644 index 2b006549c..000000000 --- a/src/element/subtypes/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module "mathjax-full/js/input/asciimath/mathjax2/legacy/MathJax"; - -declare module SREfeature { - function custom(locale: string): Promise; - export = custom; -} diff --git a/src/element/subtypes/mathjax/index.ts b/src/element/subtypes/mathjax/index.ts index 8df4c8652..4cab7c208 100644 --- a/src/element/subtypes/mathjax/index.ts +++ b/src/element/subtypes/mathjax/index.ts @@ -4,6 +4,12 @@ import { addSubtypeMethods } from "../"; import { getMathSubtypeRecord } from "./types"; import { prepareMathSubtype } from "./implementation"; +declare global { + module SREfeature { + function custom(locale: string): Promise; + } +} + export const MathJaxSubtype = "mathjax"; // The main hook to use the MathJax subtype diff --git a/src/element/subtypes/mathjax/tests/implementation.test.tsx b/src/element/subtypes/mathjax/tests/implementation.test.tsx index c895c74ae..2cc1e53f0 100644 --- a/src/element/subtypes/mathjax/tests/implementation.test.tsx +++ b/src/element/subtypes/mathjax/tests/implementation.test.tsx @@ -1,14 +1,20 @@ +import { vi } from "vitest"; import { render } from "../../../../tests/test-utils"; import { API } from "../../../../tests/helpers/api"; import { Excalidraw } from "../../../../packages/excalidraw/index"; import { measureTextElement } from "../../../textElement"; import { ensureSubtypesLoaded } from "../../"; +import { getMathSubtypeRecord } from "../types"; +import { prepareMathSubtype } from "../implementation"; -describe("mathjax", () => { - it("text-only measurements match", async () => { +describe("mathjax loaded", () => { + beforeEach(async () => { await render(); + API.addSubtype(getMathSubtypeRecord(), prepareMathSubtype); await ensureSubtypesLoaded(["math"]); + }); + it("text-only measurements match", async () => { const text = "A quick brown fox jumps over the lazy dog."; const elements = [ API.createElement({ type: "text", id: "A", text, subtype: "math" }), @@ -19,8 +25,6 @@ describe("mathjax", () => { expect(metrics1).toStrictEqual(metrics2); }); it("minimum height remains", async () => { - await render(); - await ensureSubtypesLoaded(["math"]); const elements = [ API.createElement({ type: "text", id: "A", text: "a" }), API.createElement({ @@ -44,4 +48,30 @@ describe("mathjax", () => { expect(height).toEqual(height1); expect(height).toEqual(height2); }); + it("converts math to svgs", async () => { + const svgDim = 42; + vi.spyOn(SVGElement.prototype, "getBoundingClientRect").mockImplementation( + () => new DOMRect(0, 0, svgDim, svgDim), + ); + const elements = []; + const type = "text"; + const subtype = "math"; + let text = "Math "; + elements.push(API.createElement({ type, text })); + text = "Math \\(\\alpha\\)"; + elements.push( + API.createElement({ type, subtype, text, customData: { useTex: true } }), + ); + text = "Math `beta`"; + elements.push( + API.createElement({ type, subtype, text, customData: { useTex: false } }), + ); + const metrics = { + width: measureTextElement(elements[0]).width + svgDim, + height: svgDim, + baseline: 0, + }; + expect(measureTextElement(elements[1])).toStrictEqual(metrics); + expect(measureTextElement(elements[2])).toStrictEqual(metrics); + }); }); diff --git a/src/element/subtypes/use.ts b/src/element/subtypes/use.ts index 754d868d6..a090b254d 100644 --- a/src/element/subtypes/use.ts +++ b/src/element/subtypes/use.ts @@ -1,3 +1,4 @@ +import { Subtype } from "."; import { ExcalidrawImperativeAPI } from "../../types"; import { MathJaxSubtype, @@ -5,13 +6,13 @@ import { useMathJaxSubtype, } from "./mathjax"; -const validSubtypes: readonly string[] = [MathJaxSubtype]; -const subtypesUsed: string[] = []; +const validSubtypes: readonly Subtype[] = [MathJaxSubtype]; +const subtypesUsed: Subtype[] = []; // The main invocation hook for use in the UI export const useSubtypes = ( api: ExcalidrawImperativeAPI | null, - subtypes?: string[], + subtypes?: Subtype[], ) => { selectSubtypesToEnable(subtypes); useMathJaxSubtype(api); @@ -19,8 +20,8 @@ export const useSubtypes = ( }; // This MUST be called before the `useSubtype` calls. -const selectSubtypesToEnable = (subtypes?: string[]) => { - const subtypeList: string[] = []; +const selectSubtypesToEnable = (subtypes?: Subtype[]) => { + const subtypeList: Subtype[] = []; if (subtypes === undefined) { subtypeList.push(...validSubtypes); } else { diff --git a/src/global.d.ts b/src/global.d.ts index 76730c8de..af79408ce 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -116,3 +116,5 @@ declare namespace jest { toBeNonNaNNumber(): void; } } + +declare module "mathjax-full/js/input/asciimath/mathjax2/legacy/MathJax"; diff --git a/src/tests/subtypes.test.tsx b/src/tests/subtypes.test.tsx index b1cecfe98..d667d5082 100644 --- a/src/tests/subtypes.test.tsx +++ b/src/tests/subtypes.test.tsx @@ -1,3 +1,4 @@ +import { vi } from "vitest"; import fallbackLangData from "./helpers/locales/en.json"; import { SubtypeLoadedCb, @@ -458,9 +459,9 @@ describe("subtypes", () => { return { width: 1, height: 0, baseline: 0 }; }; - jest - .spyOn(textElementUtils, "measureText") - .mockImplementation(mockMeasureText); + vi.spyOn(textElementUtils, "measureText").mockImplementation( + mockMeasureText, + ); elements.forEach((el) => { if (isTextElement(el)) {