Skip to content
File

Blob: tests/client/lib/lazy-highlight.test.ts

typescript66 lines
1import { Schema } from "@tiptap/pm/model";
2import { describe, expect, it } from "vitest";
3import {
4 codeBlockSnapshotChanged,
5 getCodeBlockSnapshot,
6} from "@/client/components/editor/extensions/code-block/lazy-highlight";
7 
8const 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 
26function paragraph(text: string) {
27 return schema.node("paragraph", null, text ? [schema.text(text)] : []);
28}
29 
30function codeBlock(text: string, language?: string | null) {
31 return schema.node("codeBlock", { language: language ?? null }, text ? [schema.text(text)] : []);
32}
33 
34function doc(...content: ReturnType<typeof paragraph>[]) {
35 return schema.node("doc", null, content);
36}
37 
38describe("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});