File
Blob: tests/client/lib/lazy-highlight.test.ts
| 1 | import { Schema } from "@tiptap/pm/model"; |
| 2 | import { describe, expect, it } from "vitest"; |
| 3 | import { |
| 4 | codeBlockSnapshotChanged, |
| 5 | getCodeBlockSnapshot, |
| 6 | } from "@/client/components/editor/extensions/code-block/lazy-highlight"; |
| 7 | |
| 8 | const schema = new Schema({ |
| 9 | nodes: { |
| 10 | doc: { content: "block+" }, |
| 11 | paragraph: { |
| 12 | content: "text*", |
| 13 | group: "block", |
| 14 | }, |
| 15 | codeBlock: { |
| 16 | attrs: { language: { default: null } }, |
| 17 | code: true, |
| 18 | content: "text*", |
| 19 | group: "block", |
| 20 | marks: "", |
| 21 | }, |
| 22 | text: { group: "inline" }, |
| 23 | }, |
| 24 | }); |
| 25 | |
| 26 | function paragraph(text: string) { |
| 27 | return schema.node("paragraph", null, text ? [schema.text(text)] : []); |
| 28 | } |
| 29 | |
| 30 | function codeBlock(text: string, language?: string | null) { |
| 31 | return schema.node("codeBlock", { language: language ?? null }, text ? [schema.text(text)] : []); |
| 32 | } |
| 33 | |
| 34 | function doc(...content: ReturnType<typeof paragraph>[]) { |
| 35 | return schema.node("doc", null, content); |
| 36 | } |
| 37 | |
| 38 | describe("lazy code block snapshots", () => { |
| 39 | it("tracks code block text changes even when non-code selections stay elsewhere", () => { |
| 40 | const oldDoc = doc(paragraph("Before"), codeBlock("const count = 1", "ts")); |
| 41 | const newDoc = doc(paragraph("Before"), codeBlock("while (true) {}", "ts")); |
| 42 | |
| 43 | expect(codeBlockSnapshotChanged(oldDoc, newDoc, "codeBlock", "text")).toBe(true); |
| 44 | }); |
| 45 | |
| 46 | it("tracks code block language changes", () => { |
| 47 | const oldDoc = doc(paragraph("Before"), codeBlock("const count = 1", "text")); |
| 48 | const newDoc = doc(paragraph("Before"), codeBlock("const count = 1", "ts")); |
| 49 | |
| 50 | expect(codeBlockSnapshotChanged(oldDoc, newDoc, "codeBlock", "text")).toBe(true); |
| 51 | }); |
| 52 | |
| 53 | it("ignores unrelated non-code-block document edits", () => { |
| 54 | const oldDoc = doc(paragraph("Before"), codeBlock("const count = 1", "ts")); |
| 55 | const newDoc = doc(paragraph("Before now"), codeBlock("const count = 1", "ts")); |
| 56 | |
| 57 | expect(codeBlockSnapshotChanged(oldDoc, newDoc, "codeBlock", "text")).toBe(false); |
| 58 | }); |
| 59 | |
| 60 | it("normalizes empty languages through the default language", () => { |
| 61 | const snapshot = getCodeBlockSnapshot(doc(codeBlock("plain text")), "codeBlock", "text"); |
| 62 | |
| 63 | expect(snapshot).toEqual(["text\u0000plain text"]); |
| 64 | }); |
| 65 | }); |