UNPKG

15.8 kBJavaScriptView Raw
1var Markdown = require('Markdown').Markdown,
2 mk_block = Markdown.mk_block;
3
4var tests = {
5 meta: function(fn) {
6 return function() { fn( new Markdown ) }
7 }
8};
9
10tests = {
11 test_split_block: tests.meta(function(md) {
12 asserts.same(
13 md.split_blocks( "# h1 #\n\npara1\npara1L2\n \n\n\n\npara2\n" ),
14 [mk_block( "# h1 #", "\n\n", 1 ),
15 mk_block( "para1\npara1L2", "\n \n\n\n\n", 3 ),
16 mk_block( "para2", "\n", 9 )
17 ],
18 "split_block should record trailing newlines");
19
20 asserts.same(
21 md.split_blocks( "\n\n# heading #\n\npara\n" ),
22 [mk_block( "# heading #", "\n\n", 3 ),
23 mk_block( "para", "\n", 5 )
24 ],
25 "split_block should ignore leading newlines");
26 }),
27
28 test_headers: tests.meta(function(md) {
29 var h1 = md.dialect.block.atxHeader( "# h1 #\n\n", [] ),
30 h2;
31
32 asserts.same(
33 h1,
34 md.dialect.block.setextHeader( "h1\n===\n\n", [] ),
35 "Atx and Setext style H1s should produce the same output" );
36
37 asserts.same(
38 md.dialect.block.atxHeader("# h1\n\n"),
39 h1,
40 "Closing # optional on atxHeader");
41
42 asserts.same(
43 h2 = md.dialect.block.atxHeader( "## h2\n\n", [] ),
44 [["header", {level: 2}, "h2"]],
45 "Atx h2 has right level");
46
47 asserts.same(
48 h2,
49 md.dialect.block.setextHeader( "h2\n---\n\n", [] ),
50 "Atx and Setext style H2s should produce the same output" );
51
52 }),
53
54 test_code: tests.meta(function(md) {
55 var code = md.dialect.block.code,
56 next = [ mk_block("next") ];
57
58 asserts.same(
59 code.call( md, mk_block(" foo\n bar"), next ),
60 [["code_block", "foo\nbar" ]],
61 "Code block correct");
62
63 asserts.same(
64 next, [mk_block("next")],
65 "next untouched when its not code");
66
67 next = [];
68 asserts.same(
69 code.call( md, mk_block(" foo\n bar"), next ),
70 [["code_block", "foo" ]],
71 "Code block correct for abutting para");
72
73 asserts.same(
74 next, [mk_block(" bar")],
75 "paragraph put back into next block");
76
77 asserts.same(
78 code.call( md, mk_block(" foo"), [mk_block(" bar"), ] ),
79 [["code_block", "foo\n\nbar" ]],
80 "adjacent code blocks ");
81
82 asserts.same(
83 code.call( md, mk_block(" foo","\n \n \n"), [mk_block(" bar"), ] ),
84 [["code_block", "foo\n\n\nbar" ]],
85 "adjacent code blocks preserve correct number of empty lines");
86
87 }),
88
89 test_bulletlist: tests.meta(function(md) {
90 var bl = function() { return md.dialect.block.lists.apply(md, arguments) };
91
92 asserts.same(
93 bl( mk_block("* foo\n* bar"), [] ),
94 [ [ "bulletlist", [ "listitem", "foo" ], [ "listitem", "bar" ] ] ],
95 "single line bullets");
96
97 asserts.same(
98 bl( mk_block("* [text](url)" ), [] ),
99 [ [ "bulletlist", [ "listitem", [ "link", { href: "url" }, "text" ] ] ] ],
100 "link in bullet");
101
102 asserts.same(
103 bl( mk_block("* foo\nbaz\n* bar\nbaz"), [] ),
104 [ [ "bulletlist", [ "listitem", "foo\nbaz" ], [ "listitem", "bar\nbaz" ] ] ],
105 "multiline lazy bullets");
106
107 asserts.same(
108 bl( mk_block("* foo\n baz\n* bar\n baz"), [] ),
109 [ [ "bulletlist", [ "listitem", "foo\nbaz" ], [ "listitem", "bar\nbaz" ] ] ],
110 "multiline tidy bullets");
111
112 asserts.same(
113 bl( mk_block("* foo\n baz"), [] ),
114 [ [ "bulletlist", [ "listitem", "foo\n baz" ] ] ],
115 "only trim 4 spaces from the start of the line");
116
117 /* Test wrong: should end up with 3 nested lists here
118 asserts.same(
119 bl( mk_block(" * one\n * two\n * three" ), [] ),
120 [ [ "bulletlist", [ "listitem", "one" ], [ "listitem", "two" ], [ "listitem", "three" ] ] ],
121 "bullets can be indented up to three spaces");
122 */
123
124 asserts.same(
125 bl( mk_block(" * one"), [ mk_block(" two") ] ),
126 [ [ "bulletlist", [ "listitem", [ "para", "one" ], [ "para", "two" ] ] ] ],
127 "loose bullet lists can have multiple paragraphs");
128
129 /* Case: no space after bullet - not a list
130 | *↵
131 |foo
132 */
133 asserts.same(
134 bl( mk_block(" *\nfoo") ),
135 undefined,
136 "Space required after bullet to trigger list");
137
138 /* Case: note the space after the bullet
139 | *␣
140 |foo
141 |bar
142 */
143 asserts.same(
144 bl( mk_block(" * \nfoo\nbar"), [ ] ),
145 [ [ "bulletlist", [ "listitem", "foo\nbar" ] ] ],
146 "space+continuation lines");
147
148
149 /* Case I:
150 | * foo
151 | * bar
152 | * baz
153 */
154 asserts.same(
155 bl( mk_block(" * foo\n" +
156 " * bar\n" +
157 " * baz"),
158 [] ),
159 [ [ "bulletlist",
160 [ "listitem",
161 "foo",
162 [ "bulletlist",
163 [ "listitem",
164 "bar",
165 [ "bulletlist",
166 [ "listitem", "baz" ]
167 ]
168 ]
169 ]
170 ]
171 ] ],
172 "Interesting indented lists I");
173
174 /* Case II:
175 | * foo
176 | * bar
177 | * baz
178 */
179 asserts.same(
180 bl( mk_block(" * foo\n * bar\n * baz"), [] ),
181 [ [ "bulletlist",
182 [ "listitem",
183 "foo",
184 [ "bulletlist",
185 [ "listitem", "bar" ]
186 ]
187 ],
188 [ "listitem", "baz" ]
189 ] ],
190 "Interesting indented lists II");
191
192 /* Case III:
193 | * foo
194 | * bar
195 |* baz
196 | * fnord
197 */
198 asserts.same(
199 bl( mk_block(" * foo\n * bar\n* baz\n * fnord"), [] ),
200 [ [ "bulletlist",
201 [ "listitem",
202 "foo",
203 [ "bulletlist",
204 [ "listitem", "bar" ],
205 [ "listitem", "baz" ],
206 [ "listitem", "fnord" ]
207 ]
208 ]
209 ] ],
210 "Interesting indented lists III");
211
212 /* Case IV:
213 | * foo
214 |
215 | 1. bar
216 */
217 asserts.same(
218 bl( mk_block(" * foo"), [ mk_block(" 1. bar\n") ] ),
219 [ [ "bulletlist",
220 ["listitem", ["para", "foo"] ],
221 ["listitem", ["para", "bar"] ]
222 ] ],
223 "Different lists at same indent IV");
224
225 /* Case V:
226 | * foo
227 | * bar
228 | * baz
229 */
230 asserts.same(
231 bl( mk_block(" * foo\n * bar\n * baz"), [] ),
232 [ [ "bulletlist",
233 [ "listitem",
234 "foo",
235 [ "bulletlist",
236 ["listitem", "bar"],
237 ["listitem", "baz"],
238 ]
239 ]
240 ] ],
241 "Indenting Case V")
242
243 /* Case VI: deep nesting
244 |* one
245 | * two
246 | * three
247 | * four
248 */
249 asserts.same(
250 bl( mk_block("* one\n * two\n * three\n * four"), [] ),
251 [ [ "bulletlist",
252 [ "listitem",
253 "one",
254 [ "bulletlist",
255 [ "listitem",
256 "two",
257 [ "bulletlist",
258 [ "listitem",
259 "three",
260 [ "bulletlist",
261 [ "listitem", "four" ]
262 ]
263 ]
264 ]
265 ]
266 ]
267 ]
268 ] ],
269 "deep nested lists VI")
270
271 /* Case VII: This one is just fruity!
272 | * foo
273 | * bar
274 | * baz
275 |* HATE
276 | * flibble
277 | * quxx
278 | * nest?
279 | * where
280 | * am
281 | * i?
282 */
283 asserts.same(
284 bl( mk_block(" * foo\n" +
285 " * bar\n" +
286 " * baz\n" +
287 "* HATE\n" +
288 " * flibble\n" +
289 " * quxx\n" +
290 " * nest?\n" +
291 " * where\n" +
292 " * am\n" +
293 " * i?"),
294 [] ),
295 [ [ "bulletlist",
296 [ "listitem",
297 "foo",
298 [ "bulletlist",
299 ["listitem", "bar"],
300 ["listitem", "baz"],
301 ["listitem", "HATE"],
302 ["listitem", "flibble"]
303 ]
304 ],
305 [ "listitem",
306 "quxx",
307 [ "bulletlist",
308 [ "listitem",
309 "nest?",
310 [ "bulletlist",
311 ["listitem", "where"],
312 ["listitem", "am"],
313 ["listitem", "i?"]
314 ]
315 ]
316 ]
317 ]
318 ] ],
319 "Indenting Case VII");
320
321 /* Case VIII: Deep nesting + code block
322 | * one
323 | * two
324 | * three
325 | * four
326 |
327 | foo
328 */
329 asserts.same(
330 bl( mk_block(" * one\n" +
331 " 1. two\n" +
332 " * three\n" +
333 " * four",
334 "\n\n"),
335 [ mk_block(" foo") ] ),
336 [ [ "bulletlist",
337 [ "listitem",
338 ["para", "one"],
339 [ "numberlist",
340 [ "listitem",
341 ["para", "two"],
342 [ "bulletlist",
343 [ "listitem",
344 [ "para", "three\n * four"],
345 ["code_block", "foo"]
346 ]
347 ]
348 ]
349 ]
350 ]
351 ] ],
352 "Case VIII: Deep nesting and code block");
353
354 }),
355
356 test_horizRule: tests.meta(function(md) {
357 var hr = md.dialect.block.horizRule,
358 strs = ["---", "_ __", "** ** **", "--- "];
359 strs.forEach( function(s) {
360 asserts.same(
361 hr.call( md, mk_block(s), [] ),
362 [ [ "hr" ] ],
363 "simple hr from " + uneval(s));
364 });
365 }),
366
367 test_blockquote: tests.meta(function(md) {
368 var bq = md.dialect.block.blockquote;
369 asserts.same(
370 bq.call( md, mk_block("> foo\n> bar"), [] ),
371 [ ["blockquote", ["para", "foo\nbar"] ] ],
372 "simple blockquote");
373
374 // Note: this tests horizRule as well through block processing.
375 asserts.same(
376 bq.call( md, mk_block("> foo\n> bar\n>\n>- - - "), [] ),
377 [ ["blockquote",
378 ["para", "foo\nbar"],
379 ["hr"]
380 ] ],
381 "blockquote with interesting content");
382
383 }),
384
385 test_referenceDefn: tests.meta(function(md) {
386 var rd = md.dialect.block.referenceDefn;
387
388 [ '[id]: http://example.com/ "Optional Title Here"',
389 "[id]: http://example.com/ 'Optional Title Here'",
390 '[id]: http://example.com/ (Optional Title Here)'
391 ].forEach( function(s) {
392 md.tree = ["markdown"];
393
394 asserts.same(rd.call( md, mk_block(s) ), [], "ref processed");
395
396 asserts.same(md.tree[ 1 ].references,
397 { "id": { href: "http://example.com/", title: "Optional Title Here" } },
398 "reference extracted");
399 });
400
401 // Check a para abbuting a ref works right
402 md.tree = ["markdown"];
403 var next = [];
404 asserts.same(rd.call( md, mk_block("[id]: example.com\npara"), next ), [], "ref processed");
405 asserts.same(md.tree[ 1 ].references, { "id": { href: "example.com" } }, "reference extracted");
406 asserts.same(next, [ mk_block("para") ], "paragraph put back into blocks");
407
408 }),
409
410 test_inline_br: tests.meta(function(md) {
411 asserts.same(
412 md.processInline("foo \n\\[bar"),
413 [ "foo", ["linebreak"], "[bar" ], "linebreak+escape");
414 }),
415
416 test_inline_escape: tests.meta(function(md) {
417 asserts.same( md.processInline("\\bar"), [ "\\bar" ], "invalid escape" );
418 asserts.same( md.processInline("\\*foo*"), [ "*foo*" ], "escaped em" );
419 }),
420
421 test_inline_code: tests.meta(function(md) {
422 asserts.same( md.processInline("`bar`"), [ ["inlinecode", "bar" ] ], "code I" );
423 asserts.same( md.processInline("``b`ar``"), [ ["inlinecode", "b`ar" ] ], "code II" );
424 asserts.same( md.processInline("```bar``` baz"), [ ["inlinecode", "bar" ], " baz" ], "code III" );
425 }),
426
427 test_inline_strong_em: tests.meta(function(md) {
428 // Yay for horrible edge cases >_<
429 asserts.same( md.processInline("foo *abc* bar"), [ "foo ", ["em", "abc" ], " bar" ], "strong/em I" );
430 asserts.same( md.processInline("*abc `code`"), [ "*abc ", ["inlinecode", "code" ] ], "strong/em II" );
431 asserts.same( md.processInline("*abc**def* after"), [ ["em", "abc**def" ], " after" ], "strong/em III" );
432 asserts.same( md.processInline("*em **strong * wtf**"), [ ["em", "em **strong " ], " wtf**" ], "strong/em IV" );
433 asserts.same( md.processInline("*foo _b*a*r baz"), [ [ "em", "foo _b" ], "a*r baz" ], "strong/em V" );
434 }),
435
436 test_inline_img: tests.meta(function(md) {
437
438 asserts.same( md.processInline( "![alt] (url)" ),
439 [ [ "img", { href: "url", alt: "alt" } ] ],
440 "inline img I" );
441
442 asserts.same( md.processInline( "![alt](url 'title')" ),
443 [ [ "img", { href: "url", alt: "alt", title: "title" } ] ],
444 "inline img II" );
445
446 asserts.same( md.processInline( "![alt] (url 'tit'le') after')" ),
447 [ [ "img", { href: "url", alt: "alt", title: "tit'le" } ], " after')" ],
448 "inline img III" );
449
450 asserts.same( md.processInline( "![alt] (url \"title\")" ),
451 [ [ "img", { href: "url", alt: "alt", title: "title" } ] ],
452 "inline img IV" );
453
454 asserts.same( md.processInline( "![alt][id]" ),
455 [ [ "img_ref", { ref: "id", alt: "alt", text: "![alt][id]" } ] ],
456 "ref img I" );
457
458 asserts.same( md.processInline( "![alt] [id]" ),
459 [ [ "img_ref", { ref: "id", alt: "alt", text: "![alt] [id]" } ] ],
460 "ref img II" );
461 }),
462
463 test_inline_link: tests.meta(function(md) {
464
465 asserts.same( md.processInline( "[text] (url)" ),
466 [ [ "link", { href: "url" }, "text" ] ],
467 "inline link I" );
468
469 asserts.same( md.processInline( "[text](url 'title')" ),
470 [ [ "link", { href: "url", title: "title" }, "text" ] ],
471 "inline link II" );
472
473 asserts.same( md.processInline( "[text](url 'tit'le') after')" ),
474 [ [ "link", { href: "url", title: "tit'le" }, "text" ], " after')" ],
475 "inline link III" );
476
477 asserts.same( md.processInline( "[text](url \"title\")" ),
478 [ [ "link", { href: "url", title: "title" }, "text" ] ],
479 "inline link IV" );
480
481 asserts.same( md.processInline( "[text][id]" ),
482 [ [ "link_ref", { ref: "id", original: "[text][id]" }, "text" ] ],
483 "ref link I" );
484
485 asserts.same( md.processInline( "[text] [id]" ),
486 [ [ "link_ref", { ref: "id", original: "[text] [id]" }, "text" ] ],
487 "ref link II" );
488 }),
489
490 test_inline_autolink: tests.meta(function(md) {
491
492 asserts.same( md.processInline( "<http://foo.com>" ),
493 [ [ "link", { href: "http://foo.com" }, "http://foo.com" ] ],
494 "autolink I" );
495
496 asserts.same( md.processInline( "<mailto:foo@bar.com>" ),
497 [ [ "link", { href: "mailto:foo@bar.com" }, "foo@bar.com" ] ],
498 "autolink II" );
499
500 asserts.same( md.processInline( "<foo@bar.com>" ),
501 [ [ "link", { href: "mailto:foo@bar.com" }, "foo@bar.com" ] ],
502 "autolink III" );
503 }),
504}
505
506
507if (require.main === module) {
508 var asserts = require('test').asserts;
509 require('test').runner(tests);
510}