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
419 lines
11 KiB
TypeScript
419 lines
11 KiB
TypeScript
import { TableKit } from '@tiptap/extension-table'
|
|
import StarterKit from '@tiptap/starter-kit'
|
|
import { renderToMarkdown } from './markdown.js'
|
|
import { describe, expect, it } from 'vite-plus/test'
|
|
|
|
describe('static render json to string (no prosemirror)', () => {
|
|
it('should return empty string for empty content', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
expect(md).toBe('')
|
|
})
|
|
|
|
it('should render empty paragraph', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
expect(md).toBe('\n\n')
|
|
})
|
|
|
|
it('should render a simple paragraph', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Hello, world!',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
expect(md).toBe('\nHello, world!\n')
|
|
})
|
|
|
|
it('should render a simple table', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'table',
|
|
content: [
|
|
{
|
|
type: 'tableRow',
|
|
content: [
|
|
{
|
|
type: 'tableHeader',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Col 1',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableHeader',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Col 2',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableHeader',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Col 3',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableRow',
|
|
content: [
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Row 1 1',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: '112',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: '1334',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableRow',
|
|
content: [
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Row 2 1',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: '115',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'tableCell',
|
|
attrs: {
|
|
colspan: 1,
|
|
rowspan: 1,
|
|
colwidth: null,
|
|
},
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: '4',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({ content: json, extensions: [StarterKit, TableKit] })
|
|
|
|
expect(md).toBe(
|
|
'\n| Col 1 | Col 2 | Col 3 |\n| --- | --- | --- |\n| Row 1 1 | 112 | 1334 |\n| Row 2 1 | 115 | 4 |\n\n',
|
|
)
|
|
})
|
|
|
|
it('should render a table with merged cells (rowspan) without breaking the grid', () => {
|
|
const cell = (text: string, attrs: { colspan?: number; rowspan?: number } = {}) => ({
|
|
type: 'tableCell',
|
|
attrs: { colspan: 1, rowspan: 1, colwidth: null, ...attrs },
|
|
content: text
|
|
? [{ type: 'paragraph', content: [{ type: 'text', text }] }]
|
|
: [{ type: 'paragraph', content: [] }],
|
|
})
|
|
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'table',
|
|
content: [
|
|
{
|
|
// Row 0: "3" spans down into row 1, so row 0 has 3 real cells
|
|
type: 'tableRow',
|
|
content: [cell('1'), cell('3', { rowspan: 2 }), cell('-')],
|
|
},
|
|
{
|
|
// Row 1: only 2 real cells exist here, the 3rd column is covered by row 0's rowspan
|
|
type: 'tableRow',
|
|
content: [cell('2'), cell('4')],
|
|
},
|
|
{
|
|
// Row 2: back to 3 real (empty) cells
|
|
type: 'tableRow',
|
|
content: [cell(''), cell(''), cell('')],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
|
|
const md = renderToMarkdown({ content: json, extensions: [StarterKit, TableKit] })
|
|
|
|
// Every row must keep the same number of columns as the header separator row,
|
|
// with a blank placeholder standing in for the rowspan-covered slot.
|
|
expect(md).toBe('\n| 1 | 3 | - |\n| --- | --- | --- |\n| 2 | | 4 |\n| | | |\n\n')
|
|
})
|
|
|
|
it('should render a blockquote with trailing newline before a paragraph', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'blockquote',
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Quote',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'World',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
// The blockquote must have a trailing newline so "World" is not part of the blockquote
|
|
expect(md).toContain('> Quote\n\n')
|
|
})
|
|
|
|
it('should render a standalone blockquote with trailing newline', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'blockquote',
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Quote',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
expect(md).toBe('\n> Quote\n')
|
|
})
|
|
|
|
it('should render a blockquote with multiple paragraphs', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [
|
|
{
|
|
type: 'blockquote',
|
|
content: [
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'First',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'paragraph',
|
|
content: [
|
|
{
|
|
type: 'text',
|
|
text: 'Second',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
})
|
|
expect(md).toBe('\n> First\n> \n> Second\n')
|
|
})
|
|
|
|
it('accepts staticEditorOptions.textDirection without crashing', () => {
|
|
const json = {
|
|
type: 'doc',
|
|
content: [{ type: 'paragraph', content: [{ type: 'text', text: 'hello' }] }],
|
|
}
|
|
|
|
const md = renderToMarkdown({
|
|
content: json,
|
|
extensions: [StarterKit, TableKit],
|
|
staticEditorOptions: { textDirection: 'rtl' },
|
|
})
|
|
|
|
expect(md).toBe('\nhello\n')
|
|
})
|
|
})
|