forked from ProseMirror/prosemirror-markdown
/
test-parse.ts
209 lines (163 loc) · 7.02 KB
/
test-parse.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import {eq} from "prosemirror-test-builder"
import {Node} from "prosemirror-model"
import ist from "ist"
import {schema, defaultMarkdownParser, defaultMarkdownSerializer, MarkdownSerializer} from "prosemirror-markdown"
import {doc, blockquote, h1, h2, p, hr, li, ol, ol3, ul, pre, em, strong, code, a, link, br, img} from "./build.js"
function parse(text: string, doc: Node) {
ist(defaultMarkdownParser.parse(text), doc, eq)
}
function serialize(doc: Node, text: string) {
ist(defaultMarkdownSerializer.serialize(doc), text)
}
function same(text: string, doc: Node) {
parse(text, doc)
serialize(doc, text)
}
describe("markdown", () => {
it("parses a paragraph", () =>
same("hello!",
doc(p("hello!"))))
it("parses headings", () =>
same("# one\n\n## two\n\nthree",
doc(h1("one"), h2("two"), p("three"))))
it("parses a blockquote", () =>
same("> once\n\n> > twice",
doc(blockquote(p("once")), blockquote(blockquote(p("twice"))))))
// FIXME bring back testing for preserving bullets and tight attrs
// when supported again
it("parses a bullet list", () =>
same("* foo\n\n * bar\n\n * baz\n\n* quux",
doc(ul(li(p("foo"), ul(li(p("bar")), li(p("baz")))), li(p("quux"))))))
it("parses an ordered list", () =>
same("1. Hello\n\n2. Goodbye\n\n3. Nest\n\n 1. Hey\n\n 2. Aye",
doc(ol(li(p("Hello")), li(p("Goodbye")), li(p("Nest"), ol(li(p("Hey")), li(p("Aye"))))))))
it("preserves ordered list start number", () =>
same("3. Foo\n\n4. Bar",
doc(ol3(li(p("Foo")), li(p("Bar"))))))
it("parses a code block", () =>
same("Some code:\n\n```\nHere it is\n```\n\nPara",
doc(p("Some code:"), schema.node("code_block", {params: ""}, [schema.text("Here it is")]), p("Para"))))
it("parses an intended code block", () =>
parse("Some code:\n\n Here it is\n\nPara",
doc(p("Some code:"), pre("Here it is"), p("Para"))))
it("parses a fenced code block with info string", () =>
same("foo\n\n```javascript\n1\n```",
doc(p("foo"), schema.node("code_block", {params: "javascript"}, [schema.text("1")]))))
it("parses inline marks", () =>
same("Hello. Some *em* text, some **strong** text, and some `code`",
doc(p("Hello. Some ", em("em"), " text, some ", strong("strong"), " text, and some ", code("code")))))
it("parses overlapping inline marks", () =>
same("This is **strong *emphasized text with `code` in* it**",
doc(p("This is ", strong("strong ", em("emphasized text with ", code("code"), " in"), " it")))))
it("parses links inside strong text", () =>
same("**[link](foo) is bold**",
doc(p(strong(a("link"), " is bold")))))
it("parses code mark inside strong text", () =>
same("**`code` is bold**",
doc(p(strong(code("code"), " is bold")))))
it("parses code mark containing backticks", () =>
same("``` one backtick: ` two backticks: `` ```",
doc(p(code("one backtick: ` two backticks: ``")))))
it("parses code mark containing only whitespace", () =>
serialize(doc(p("Three spaces: ", code(" "))),
"Three spaces: ` `"))
it("parses links", () =>
same("My [link](foo) goes to foo",
doc(p("My ", a("link"), " goes to foo"))))
it("parses urls", () =>
same("Link to <https://prosemirror.net>",
doc(p("Link to ", link({href: "https://prosemirror.net"}, "https://prosemirror.net")))))
it("correctly serializes relative urls", () => {
same("[foo.html](foo.html)",
doc(p(link({href: "foo.html"}, "foo.html"))))
})
it("can handle link titles", () => {
same('[a](x.html "title \\"quoted\\"")',
doc(p(link({href: "x.html", title: 'title "quoted"'}, "a"))))
})
it("doesn't escape underscores in link", () => {
same('[link](http://foo.com/a_b_c)',
doc(p(link({href: "http://foo.com/a_b_c"}, "link"))))
})
it("parses emphasized urls", () =>
same("Link to *<https://prosemirror.net>*",
doc(p("Link to ", em(link({href: "https://prosemirror.net"}, "https://prosemirror.net"))))))
it("parses an image", () =>
same("Here's an image: ![x](img.png)",
doc(p("Here's an image: ", img()))))
it("parses a line break", () =>
same("line one\\\nline two",
doc(p("line one", br(), "line two"))))
it("parses a horizontal rule", () =>
same("one two\n\n---\n\nthree",
doc(p("one two"), hr(), p("three"))))
it("ignores HTML tags", () =>
same("Foo < img> bar",
doc(p("Foo < img> bar"))))
it("doesn't accidentally generate list markup", () =>
same("1\\. foo",
doc(p("1. foo"))))
it("doesn't fail with line break inside inline mark", () =>
same("**text1\ntext2**", doc(p(strong("text1\ntext2")))))
it("drops trailing hard breaks", () =>
serialize(doc(p("a", br(), br())), "a"))
it("expels enclosing whitespace from inside emphasis", () =>
serialize(doc(p("Some emphasized text with", strong(em(" whitespace ")), "surrounding the emphasis.")),
"Some emphasized text with ***whitespace*** surrounding the emphasis."))
it("drops nodes when all whitespace is expelled from them", () =>
serialize(doc(p("Text with", em(" "), "an emphasized space")),
"Text with an emphasized space"))
it("preserves list tightness", () => {
same("* foo\n* bar", doc(ul({tight: true}, li(p("foo")), li(p("bar")))))
same("1. foo\n2. bar", doc(ol({tight: true}, li(p("foo")), li(p("bar")))))
})
it("doesn't put a code block after a list item inside the list item", () =>
same("* list item\n\n```\ncode\n```",
doc(ul({tight: true}, li(p("list item"))), pre("code")))
)
it("doesn't escape characters in code", () =>
same("foo`*`", doc(p("foo", code("*"))))
)
it("doesn't escape underscores between word characters", () =>
same(
"abc_def",
doc(p("abc_def"))
)
)
it("doesn't escape strips of underscores between word characters", () =>
same(
"abc___def",
doc(p("abc___def"))
)
)
it("escapes underscores at word boundaries", () =>
same(
"\\_abc\\_",
doc(p("_abc_"))
)
)
it("escapes underscores surrounded by non-word characters", () =>
same(
"/\\_abc\\_)",
doc(p("/_abc_)"))
)
)
it("ensure no escapes in url", () =>
parse(
"[text](https://example.com/_file/#~anchor)",
doc(p(a({href: "https://example.com/_file/#~anchor"}, "text")))
)
)
it("ensure no escapes in autolinks", () =>
same(
"<https://example.com/_file/#~anchor>",
doc(p(a({href: "https://example.com/_file/#~anchor"}, "https://example.com/_file/#~anchor")))
)
)
it("escapes extra characters from options", () => {
let markdownSerializer = new MarkdownSerializer(defaultMarkdownSerializer.nodes,
defaultMarkdownSerializer.marks,
{escapeExtraCharacters: /[\|!]/g})
ist(markdownSerializer.serialize(doc(p("foo|bar!"))), "foo\\|bar\\!")
})
})