Files
upstream-tiptap/packages/markdown/tests/integration/task-list-nested-siblings.test.ts
upstream-mirror 083a46e93b
Some checks failed
Verify / Install node dependencies (push) Failing after 2s
Verify / Build packages (push) Has been skipped
Verify / Check linting & formatting (push) Has been skipped
Verify / Run unit tests (push) Has been skipped
Verify / Run e2e tests (shard 1/4) (push) Has been skipped
Verify / Run e2e tests (shard 2/4) (push) Has been skipped
Verify / Run e2e tests (shard 3/4) (push) Has been skipped
Verify / Run e2e tests (shard 4/4) (push) Has been skipped
Publish / Resolve publish config (push) Failing after 2s
Publish / Send notification to Slack (push) Has been skipped
Publish / Send failure notification to Slack (push) Failing after 8s
Verify / Merge e2e reports (push) Has been skipped
Publish / Build (push) Has been skipped
Publish / Bump Versions OR Release to Registry (push) Has been skipped
snapshot of https://github.com/ueberdosis/tiptap.git (main, 2026-09-15; blobs > 131072B omitted)
2026-09-15 21:11:02 +05:00

183 lines
4.9 KiB
TypeScript

import { Document } from '@tiptap/extension-document'
import { BulletList, ListItem, TaskItem, TaskList } from '@tiptap/extension-list'
import { Paragraph } from '@tiptap/extension-paragraph'
import { Text } from '@tiptap/extension-text'
import { describe, expect, it } from 'vite-plus/test'
import { MarkdownManager } from '../../src/MarkdownManager.js'
const paragraph = (text: string) => ({
type: 'paragraph',
content: [{ type: 'text', text }],
})
const listItem = (text: string) => ({
type: 'listItem',
content: [paragraph(text)],
})
const taskItem = (text: string, ...nested: object[]) => ({
type: 'taskItem',
attrs: { checked: false },
content: [paragraph(text), ...nested],
})
describe('Task list with non-checkbox siblings in nested lists', () => {
const markdownManager = new MarkdownManager({
extensions: [
Document,
Paragraph,
Text,
BulletList,
ListItem,
TaskList,
TaskItem.configure({ nested: true }),
],
})
it('keeps a plain bullet that follows a checkbox item in a nested list', () => {
const markdown = ['- [ ] parent', ' - [ ] checkbox child', ' - plain child'].join('\n')
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem(
'parent',
{ type: 'taskList', content: [taskItem('checkbox child')] },
{ type: 'bulletList', content: [listItem('plain child')] },
),
],
},
],
})
})
it('keeps multiple trailing plain bullets in one bullet list', () => {
const markdown = ['- [ ] parent', ' - [ ] checkbox child', ' - plain 1', ' - plain 2'].join(
'\n',
)
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem(
'parent',
{ type: 'taskList', content: [taskItem('checkbox child')] },
{ type: 'bulletList', content: [listItem('plain 1'), listItem('plain 2')] },
),
],
},
],
})
})
it('keeps a plain bullet in a deeply nested task list', () => {
const markdown = [
'- [ ] parent',
' - [ ] level2',
' - [ ] level3',
' - deep plain',
].join('\n')
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem('parent', {
type: 'taskList',
content: [
taskItem(
'level2',
{ type: 'taskList', content: [taskItem('level3')] },
{ type: 'bulletList', content: [listItem('deep plain')] },
),
],
}),
],
},
],
})
})
it('keeps a trailing paragraph that follows a nested checkbox item', () => {
const markdown = ['- [ ] parent', ' - [ ] child', ' trailing paragraph'].join('\n')
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem(
'parent',
{ type: 'taskList', content: [taskItem('child')] },
paragraph('trailing paragraph'),
),
],
},
],
})
})
it('keeps a plain bullet that precedes a checkbox item in a nested list', () => {
const markdown = ['- [ ] parent', ' - plain first', ' - [ ] checkbox after'].join('\n')
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem(
'parent',
{ type: 'bulletList', content: [listItem('plain first')] },
{ type: 'taskList', content: [taskItem('checkbox after')] },
),
],
},
],
})
})
it('still parses a purely-checkbox nested list as a single task list', () => {
const markdown = ['- [ ] parent', ' - [ ] child 1', ' - [x] child 2'].join('\n')
expect(markdownManager.parse(markdown)).toEqual({
type: 'doc',
content: [
{
type: 'taskList',
content: [
taskItem('parent', {
type: 'taskList',
content: [
taskItem('child 1'),
{
type: 'taskItem',
attrs: { checked: true },
content: [paragraph('child 2')],
},
],
}),
],
},
],
})
})
it('round-trips the mixed nested list back to the original markdown', () => {
const markdown = ['- [ ] parent', ' - [ ] checkbox child', ' - plain child'].join('\n')
const json = markdownManager.parse(markdown)
expect(markdownManager.serialize(json).trim()).toBe(markdown)
})
})