memos/web/tests/memo-markdown-extension.test.ts

65 lines
2.5 KiB
TypeScript

import { markdown } from "@codemirror/lang-markdown";
import { EditorState } from "@codemirror/state";
import { parser as markdownParser } from "@lezer/markdown";
import { describe, expect, it } from "vitest";
import { findMarkdownTagMatches } from "@/components/MemoEditor/Editor/markdownTagRanges";
import { memoMarkdownExtensions } from "@/utils/memo-markdown-extension";
const sourceParser = markdownParser.configure(memoMarkdownExtensions);
function inlineMath(source: string): string[] {
const ranges: string[] = [];
sourceParser.parse(source).iterate({
enter(node) {
if (node.name === "InlineMath") ranges.push(source.slice(node.from, node.to));
},
});
return ranges;
}
describe("memo Markdown math", () => {
it("keeps the issue's multiline currency list as ordinary text", () => {
const source = `list of 10 houses
$140,000 max - buffer of ~10k
diy, add amount to down payment
no appliances covered
less than $1,000, client responsibilities
over $1,000 - owner responsibility
vacant is good to rent
for sale by owner
path to ownership -$50
rent insurance - my of`;
expect(inlineMath(source)).toEqual([]);
});
it("keeps two same-line currency amounts as ordinary text", () => {
expect(inlineMath("$20,000 and $30,000")).toEqual([]);
const source = "$20,000 #budget and $30,000";
const state = EditorState.create({ doc: source, extensions: [markdown({ extensions: memoMarkdownExtensions })] });
expect(findMarkdownTagMatches(state, 0, source.length).map((match) => match.value)).toEqual(["budget"]);
});
it("applies Pandoc-style boundaries to single-dollar inline math", () => {
expect(inlineMath("$ x$ and $x $ and $x$2")).toEqual([]);
expect(inlineMath("$\u0085x$ and $x\u0085$")).toEqual([]);
expect(inlineMath("$x$, then $y$")).toEqual(["$x$", "$y$"]);
});
it.each([
["$x $ and $y$", ["$y$"]],
["$x$2 and $y$", ["$y$"]],
["$20 and $30 then $x$", ["$x$"]],
])("retries after an invalid exact-size closer in %s", (source, expected) => {
expect(inlineMath(source)).toEqual(expected);
});
it("keeps valid and multi-dollar math opaque", () => {
const source = "$x$ and $#hidden$ and $$#also-hidden$$, then #visible";
const state = EditorState.create({ doc: source, extensions: [markdown({ extensions: memoMarkdownExtensions })] });
expect(inlineMath(source)).toEqual(["$x$", "$#hidden$", "$$#also-hidden$$"]);
expect(findMarkdownTagMatches(state, 0, source.length).map((match) => match.value)).toEqual(["visible"]);
});
});