Skip to content

Commit

Permalink
test: add tests specifically for React static rendering (#6029)
Browse files Browse the repository at this point in the history
  • Loading branch information
nperez0111 authored Jan 17, 2025
1 parent 56994fe commit 4c995e4
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 2 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@commitlint/cli": "^19.6.1",
"@commitlint/config-conventional": "^19.6.0",
"@cypress/webpack-preprocessor": "^5.17.1",
"@testing-library/react": "16.2.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@typescript-eslint/eslint-plugin": "^8.19.0",
Expand All @@ -64,8 +65,9 @@
"lowlight": "^3.3.0",
"minimist": "^1.2.8",
"pkg-pr-new": "0.0.32",
"tinyglobby": "0.2.10",
"prettier": "3.3.3",
"react": "^18.0.0",
"tinyglobby": "0.2.10",
"ts-loader": "9.3.1",
"tsup": "^8.3.5",
"turbo": "2.3.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function renderToReactElement({
domOutputSpecToElement: domOutputSpecToReactElement,
mapDefinedTypes: {
// Map a doc node to concatenated children
doc: ({ children }) => <>{children}</>,
doc: ({ children }) => React.createElement(React.Fragment, {}, children),
// Map a text node to its text content
text: ({ node }) => node.text ?? '',
},
Expand Down
90 changes: 90 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

164 changes: 164 additions & 0 deletions tests/cypress/integration/static-renderer/react-string.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/// <reference types="cypress" />

import { prettyDOM, render } from '@testing-library/react'
import Bold from '@tiptap/extension-bold'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { Mark, Node } from '@tiptap/pm/model'
import { renderToReactElement } from '@tiptap/static-renderer/pm/react'
import React from 'react'

describe('static render json to react elements (with prosemirror)', () => {
it('generates a React element from JSON without an editor instance', () => {
const json = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Example Text',
marks: [
{
type: 'bold',
attrs: {},
},
],
},
],
},
],
attrs: {},
}

const view = render(
renderToReactElement({
content: json,
extensions: [Document, Paragraph, Text, Bold],
}),
)
const html = prettyDOM(view.container, undefined, { highlight: false })

expect(html).to.eq(`<div>
<p>
<strong>
Example Text
</strong>
</p>
</div>`)
})

it('supports custom mapping for nodes & marks', () => {
const json = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Example Text',
marks: [
{
type: 'bold',
attrs: {},
},
],
},
],
},
],
attrs: {},
}

const view = render(
renderToReactElement({
content: json,
extensions: [Document, Paragraph, Text, Bold],
options: {
nodeMapping: {
doc: ({ children }) => {
return React.createElement('doc', {}, children)
},
},
markMapping: {
bold: ({ children }) => {
return React.createElement('b', {}, children)
},
},
},
}),
)
const html = prettyDOM(view.container, undefined, { highlight: false })

expect(html).to.eq(`<div>
<doc>
<p>
<b>
Example Text
</b>
</p>
</doc>
</div>`)
})

it('gives access to a prosemirror node or mark instance', () => {
const json = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Example Text',
marks: [
{
type: 'bold',
attrs: {},
},
],
},
],
},
],
attrs: {},
}

const view = render(
renderToReactElement({
content: json,
extensions: [Document, Paragraph, Text, Bold],
options: {
nodeMapping: {
doc: ({ children, node }) => {
expect(node.type.name).to.eq('doc')
expect(node).to.be.instanceOf(Node)
return React.createElement('doc', {}, children)
},
},
markMapping: {
bold: ({ children, mark }) => {
expect(mark.type.name).to.eq('bold')
expect(mark).to.be.instanceOf(Mark)
return React.createElement('b', {}, children)
},
},
},
}),
)
const html = prettyDOM(view.container, undefined, { highlight: false })

expect(html).to.eq(`<div>
<doc>
<p>
<b>
Example Text
</b>
</p>
</doc>
</div>`)
})
})

0 comments on commit 4c995e4

Please sign in to comment.