UNPKG

@blocknote/core

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

121 lines (107 loc) 3.95 kB
import { describe, expect, it } from "vite-plus/test"; import { collectHighlightNodeTypes, SyntaxHighlightingExtension, } from "./SyntaxHighlighting.js"; /** * @vitest-environment jsdom */ describe("SyntaxHighlightingExtension", () => { // The extension only reads `editor.schema.blockSpecs` and // `inlineContentSpecs`, so a minimal stub is enough. const fakeEditor = () => ({ schema: { blockSpecs: { paragraph: { config: { type: "paragraph", content: "inline" } }, codeBlock: { config: { type: "codeBlock", content: "plain" } }, image: { config: { type: "image", content: "none" } }, }, inlineContentSpecs: {}, }, }) as any; const pluginsFor = (options: any) => SyntaxHighlightingExtension(options)({ editor: fakeEditor() }) .prosemirrorPlugins; // Whether highlighting is enabled at all is decided by the user (they choose // to add this extension to the editor's `extensions`), so the extension // itself always installs the plugin once created. it("installs a highlight plugin when a highlighter is configured", () => { const plugins = pluginsFor({ createHighlighter: async () => ({}) as any }); expect(plugins).toHaveLength(1); }); it("installs the plugin even without a highlighter (it no-ops at parse time)", () => { expect(pluginsFor({})).toHaveLength(1); }); }); describe("collectHighlightNodeTypes", () => { const highlight = () => "latex"; it("includes blocks with `content: plain` and a `meta.highlight`", () => { const types = collectHighlightNodeTypes({ blockSpecs: { // Highlightable: plain content + a highlight callback. mathBlock: { config: { type: "mathBlock", content: "plain" }, implementation: { meta: { highlight } }, }, // Not highlightable: no highlight callback. paragraph: { config: { type: "paragraph", content: "inline" }, implementation: { meta: {} }, }, // Not highlightable: `content: none` holds no editable text. image: { config: { type: "image", content: "none" }, implementation: { meta: { highlight } }, }, }, inlineContentSpecs: {}, }); expect(types).toEqual(["mathBlock"]); }); it("includes inline content with `content: plain` and a `meta.highlight`", () => { const types = collectHighlightNodeTypes({ blockSpecs: {}, inlineContentSpecs: { // Highlightable: plain (editable plain text) + a highlight callback. math: { config: { type: "math", content: "plain" }, implementation: { meta: { highlight } }, }, // Not highlightable: no highlight callback. mention: { config: { type: "mention", content: "plain" }, implementation: { meta: {} }, }, // Not highlightable: `content: none` holds no editable text. tag: { config: { type: "tag", content: "none" }, implementation: { meta: { highlight } }, }, // Built-in `text`/`link` specs have string configs, not objects. text: { config: "text", implementation: undefined }, link: { config: "link", implementation: undefined }, }, }); expect(types).toEqual(["math"]); }); it("collects both block and inline-content highlight types together", () => { const types = collectHighlightNodeTypes({ blockSpecs: { mathBlock: { config: { type: "mathBlock", content: "plain" }, implementation: { meta: { highlight } }, }, }, inlineContentSpecs: { math: { config: { type: "math", content: "plain" }, implementation: { meta: { highlight } }, }, }, }); expect(types).toContain("mathBlock"); expect(types).toContain("math"); expect(types).toHaveLength(2); }); });