From 8447710c60c989c7be7e97585a424e95e54bbdcb Mon Sep 17 00:00:00 2001 From: Neil Date: Fri, 18 Sep 2026 04:15:59 -0700 Subject: [PATCH] test(editor): cover mounted markdown clipboard slices --- ...h-markdown-clipboard-serialization.test.ts | 60 ++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/components/editor/rich-markdown-clipboard-serialization.test.ts b/src/renderer/src/components/editor/rich-markdown-clipboard-serialization.test.ts index e71cea2aaa9..065b0ecf3e1 100644 --- a/src/renderer/src/components/editor/rich-markdown-clipboard-serialization.test.ts +++ b/src/renderer/src/components/editor/rich-markdown-clipboard-serialization.test.ts @@ -1,8 +1,12 @@ +// @vitest-environment happy-dom import { Editor } from '@tiptap/core' import { describe, expect, it } from 'vitest' import { encodeRawMarkdownHtmlForRichEditor } from './raw-markdown-html' import { createRichMarkdownExtensions } from './rich-markdown-extensions' -import { serializeRichMarkdownSliceAsMarkdown } from './rich-markdown-clipboard-serialization' +import { + serializeRichMarkdownSliceAsMarkdown, + serializeRichMarkdownSliceForClipboard +} from './rich-markdown-clipboard-serialization' import { createRichMarkdownEditorCodec } from './rich-markdown-source-transport' describe('rich Markdown clipboard serialization', () => { @@ -19,8 +23,9 @@ describe('rich Markdown clipboard serialization', () => { }) try { const slice = editor.state.doc.slice(0, editor.state.doc.content.size) - const markdown = serializeRichMarkdownSliceAsMarkdown(slice, (content) => - editor.markdown!.serialize(content) + const markdown = serializeRichMarkdownSliceAsMarkdown( + slice, + (content) => editor.markdown?.serialize(content) ?? '' ) expect(markdown).toContain('# Heading') expect(markdown).toContain('**bold**') @@ -30,4 +35,53 @@ describe('rich Markdown clipboard serialization', () => { editor.destroy() } }) + + it('serializes mounted partial selections without flattening structure', () => { + const codec = createRichMarkdownEditorCodec() + const editor = new Editor({ + element: document.createElement('div'), + extensions: createRichMarkdownExtensions({ codec }), + content: encodeRawMarkdownHtmlForRichEditor( + '- first item\n- second item\n\n```ts\nconst value = 1\n```\n', + codec + ), + contentType: 'markdown', + editorProps: { + clipboardTextSerializer: (slice) => { + const markdown = editor.markdown + return markdown + ? serializeRichMarkdownSliceAsMarkdown(slice, (content) => markdown.serialize(content)) + : '' + } + } + }) + try { + const { doc } = editor.state + const list = doc.firstChild + expect(list?.type.name).toBe('bulletList') + if (!list?.firstChild) { + throw new Error('expected a list item') + } + const firstItemStart = 2 + const firstItemEnd = firstItemStart + list.firstChild.nodeSize + const listSlice = doc.slice(firstItemStart, firstItemEnd) + const markdown = editor.view.someProp('clipboardTextSerializer', (serializer) => + serializer(listSlice, editor.view) + ) + expect(markdown).toContain('- first item') + expect(markdown).not.toContain('second item') + + const codeBlock = doc.lastChild + if (!codeBlock) { + throw new Error('expected a code block') + } + const codeStart = doc.content.size - codeBlock.nodeSize + const codeSlice = doc.slice(codeStart, doc.content.size) + const codeClipboard = serializeRichMarkdownSliceForClipboard(editor.view, codeSlice) + expect(codeClipboard.html).toContain('