refactor: Refactor and add a test

This commit is contained in:
Daniel J. Geiger 2023-09-22 17:33:34 -05:00
parent 62f5475c4a
commit ec26aeead2
6 changed files with 52 additions and 18 deletions

View File

@ -1,6 +0,0 @@
declare module "mathjax-full/js/input/asciimath/mathjax2/legacy/MathJax";
declare module SREfeature {
function custom(locale: string): Promise<string>;
export = custom;
}

View File

@ -4,6 +4,12 @@ import { addSubtypeMethods } from "../";
import { getMathSubtypeRecord } from "./types"; import { getMathSubtypeRecord } from "./types";
import { prepareMathSubtype } from "./implementation"; import { prepareMathSubtype } from "./implementation";
declare global {
module SREfeature {
function custom(locale: string): Promise<string>;
}
}
export const MathJaxSubtype = "mathjax"; export const MathJaxSubtype = "mathjax";
// The main hook to use the MathJax subtype // The main hook to use the MathJax subtype

View File

@ -1,14 +1,20 @@
import { vi } from "vitest";
import { render } from "../../../../tests/test-utils"; import { render } from "../../../../tests/test-utils";
import { API } from "../../../../tests/helpers/api"; import { API } from "../../../../tests/helpers/api";
import { Excalidraw } from "../../../../packages/excalidraw/index"; import { Excalidraw } from "../../../../packages/excalidraw/index";
import { measureTextElement } from "../../../textElement"; import { measureTextElement } from "../../../textElement";
import { ensureSubtypesLoaded } from "../../"; import { ensureSubtypesLoaded } from "../../";
import { getMathSubtypeRecord } from "../types";
import { prepareMathSubtype } from "../implementation";
describe("mathjax", () => { describe("mathjax loaded", () => {
it("text-only measurements match", async () => { beforeEach(async () => {
await render(<Excalidraw />); await render(<Excalidraw />);
API.addSubtype(getMathSubtypeRecord(), prepareMathSubtype);
await ensureSubtypesLoaded(["math"]); await ensureSubtypesLoaded(["math"]);
});
it("text-only measurements match", async () => {
const text = "A quick brown fox jumps over the lazy dog."; const text = "A quick brown fox jumps over the lazy dog.";
const elements = [ const elements = [
API.createElement({ type: "text", id: "A", text, subtype: "math" }), API.createElement({ type: "text", id: "A", text, subtype: "math" }),
@ -19,8 +25,6 @@ describe("mathjax", () => {
expect(metrics1).toStrictEqual(metrics2); expect(metrics1).toStrictEqual(metrics2);
}); });
it("minimum height remains", async () => { it("minimum height remains", async () => {
await render(<Excalidraw />);
await ensureSubtypesLoaded(["math"]);
const elements = [ const elements = [
API.createElement({ type: "text", id: "A", text: "a" }), API.createElement({ type: "text", id: "A", text: "a" }),
API.createElement({ API.createElement({
@ -44,4 +48,30 @@ describe("mathjax", () => {
expect(height).toEqual(height1); expect(height).toEqual(height1);
expect(height).toEqual(height2); 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);
});
}); });

View File

@ -1,3 +1,4 @@
import { Subtype } from ".";
import { ExcalidrawImperativeAPI } from "../../types"; import { ExcalidrawImperativeAPI } from "../../types";
import { import {
MathJaxSubtype, MathJaxSubtype,
@ -5,13 +6,13 @@ import {
useMathJaxSubtype, useMathJaxSubtype,
} from "./mathjax"; } from "./mathjax";
const validSubtypes: readonly string[] = [MathJaxSubtype]; const validSubtypes: readonly Subtype[] = [MathJaxSubtype];
const subtypesUsed: string[] = []; const subtypesUsed: Subtype[] = [];
// The main invocation hook for use in the UI // The main invocation hook for use in the UI
export const useSubtypes = ( export const useSubtypes = (
api: ExcalidrawImperativeAPI | null, api: ExcalidrawImperativeAPI | null,
subtypes?: string[], subtypes?: Subtype[],
) => { ) => {
selectSubtypesToEnable(subtypes); selectSubtypesToEnable(subtypes);
useMathJaxSubtype(api); useMathJaxSubtype(api);
@ -19,8 +20,8 @@ export const useSubtypes = (
}; };
// This MUST be called before the `useSubtype` calls. // This MUST be called before the `useSubtype` calls.
const selectSubtypesToEnable = (subtypes?: string[]) => { const selectSubtypesToEnable = (subtypes?: Subtype[]) => {
const subtypeList: string[] = []; const subtypeList: Subtype[] = [];
if (subtypes === undefined) { if (subtypes === undefined) {
subtypeList.push(...validSubtypes); subtypeList.push(...validSubtypes);
} else { } else {

2
src/global.d.ts vendored
View File

@ -116,3 +116,5 @@ declare namespace jest {
toBeNonNaNNumber(): void; toBeNonNaNNumber(): void;
} }
} }
declare module "mathjax-full/js/input/asciimath/mathjax2/legacy/MathJax";

View File

@ -1,3 +1,4 @@
import { vi } from "vitest";
import fallbackLangData from "./helpers/locales/en.json"; import fallbackLangData from "./helpers/locales/en.json";
import { import {
SubtypeLoadedCb, SubtypeLoadedCb,
@ -458,9 +459,9 @@ describe("subtypes", () => {
return { width: 1, height: 0, baseline: 0 }; return { width: 1, height: 0, baseline: 0 };
}; };
jest vi.spyOn(textElementUtils, "measureText").mockImplementation(
.spyOn(textElementUtils, "measureText") mockMeasureText,
.mockImplementation(mockMeasureText); );
elements.forEach((el) => { elements.forEach((el) => {
if (isTextElement(el)) { if (isTextElement(el)) {