Spaces:
Paused
Paused
File size: 4,395 Bytes
fae625a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import { describe, expect, test } from "vitest";
import { parseIncompleteMarkdown } from "./parseIncompleteMarkdown";
describe("parseIncompleteMarkdown (remend)", () => {
describe("marker completion", () => {
test("completes incomplete bold", () => {
expect(parseIncompleteMarkdown("**hello")).toBe("**hello**");
});
test("completes incomplete italic", () => {
expect(parseIncompleteMarkdown("*hello")).toBe("*hello*");
});
test("completes incomplete inline code", () => {
expect(parseIncompleteMarkdown("`code")).toBe("`code`");
});
test("completes incomplete strikethrough", () => {
expect(parseIncompleteMarkdown("~~text")).toBe("~~text~~");
});
test("completes incomplete block math", () => {
expect(parseIncompleteMarkdown("$$\nx = 1")).toBe("$$\nx = 1\n$$");
});
test("completes a partial closing $ of block math with a single $", () => {
expect(parseIncompleteMarkdown("$$E=mc^2$")).toBe("$$E=mc^2$$");
});
});
describe("links and images", () => {
test("closes incomplete link text with placeholder URL", () => {
expect(parseIncompleteMarkdown("[link tex")).toBe("[link tex](streamdown:incomplete-link)");
});
test("replaces incomplete link URL with placeholder", () => {
expect(parseIncompleteMarkdown("[text](https://exa")).toBe(
"[text](streamdown:incomplete-link)"
);
});
test("removes images with incomplete URLs", () => {
const result = parseIncompleteMarkdown("before ;
expect(result).not.toContain(" end";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
});
describe("streaming flash guards", () => {
test("breaks a potential setext heading underline with a zero-width space", () => {
// Without this, "Some text" would flash as an <h2> while a list item streams in
expect(parseIncompleteMarkdown("Some text\n-")).toBe("Some text\n-");
});
test("escapes single tildes between word characters (no false strikethrough)", () => {
expect(parseIncompleteMarkdown("Temperature is 20~25°C")).toBe("Temperature is 20\\~25°C");
});
test("escapes > used as comparison operator in list items (no blockquote)", () => {
expect(parseIncompleteMarkdown("- > 25: high")).toBe("- \\> 25: high");
});
test("strips a half-typed trailing HTML tag", () => {
expect(parseIncompleteMarkdown("Hello <div cla")).toBe("Hello");
});
test("keeps complete HTML tags", () => {
const input = "Hello <b>hi</b>";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
});
describe("false-positive protection", () => {
test("does not close emphasis markers inside a complete inline code span", () => {
const input = "`**bold`";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
test("does not treat $$ inside inline code as math", () => {
const input = "run `echo $$` now";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
test("does not complete a lone $ (currency, inlineKatex disabled)", () => {
const input = "I have $20";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
test("does not treat asterisks inside math blocks as italics", () => {
const input = "$$a * b$$ and more";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
test("does not append underscores to word-internal underscores", () => {
const input = "snake_case_name";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
test("does not complete markers inside an open code fence", () => {
const input = "```js\nconst a = b ** 2;\nconst c = a **";
expect(parseIncompleteMarkdown(input)).toBe(input);
});
});
describe("whitespace handling", () => {
test("removes a single trailing space (mid-word streaming)", () => {
expect(parseIncompleteMarkdown("hello ")).toBe("hello");
});
test("preserves a double trailing space (markdown line break)", () => {
expect(parseIncompleteMarkdown("hello ")).toBe("hello ");
});
});
describe("input edge cases", () => {
test("returns empty string unchanged", () => {
expect(parseIncompleteMarkdown("")).toBe("");
});
test("returns plain text unchanged", () => {
expect(parseIncompleteMarkdown("just some plain text")).toBe("just some plain text");
});
});
});
|