Merge: lib/markdown: add some tests for xml parsing inside a markdown block.
[nit.git] / lib / markdown / test_markdown.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Test suites for module `markdown`
16 module test_markdown is test_suite
17
18 import test_suite
19 intrude import markdown
20
21 class TestMarkdownProcessor
22 super TestSuite
23
24 fun test_process_empty do
25 var test = ""
26 var exp = ""
27 var res = test.md_to_html.write_to_string
28 assert res == exp
29 end
30
31 fun test_process_tabs do
32 var test = """
33 some code
34 """
35 var exp = """<pre><code>some code
36 </code></pre>
37 """
38 var res = test.md_to_html.write_to_string
39 assert res == exp
40 end
41
42
43 fun test_process_par1 do
44 var test = "test"
45 var exp = "<p>test</p>\n"
46 var res = test.md_to_html.write_to_string
47 assert res == exp
48 end
49
50 fun test_process_par2 do
51 var test = """
52 line1
53 line2
54
55 line3 line4
56
57 line5"""
58 var exp = """
59 <p>line1
60 line2</p>
61 <p>line3 line4</p>
62 <p>line5</p>
63 """
64 var res = test.md_to_html.write_to_string
65 assert res == exp
66 end
67
68 fun test_process_par3 do
69 var test = """
70 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
71 Aliquam hendrerit mi posuere lectus.
72 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
73
74 Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
75 id sem consectetuer libero luctus adipiscing.
76 """
77 var exp = """
78 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
79 Aliquam hendrerit mi posuere lectus.
80 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
81 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
82 id sem consectetuer libero luctus adipiscing.</p>
83 """
84 var res = test.md_to_html.write_to_string
85 assert res == exp
86 end
87
88 fun test_process_headings_1 do
89 var test = """
90 This is a H1
91 =============
92
93 This is a H2
94 -------------
95 """
96 var exp = """
97 <h1 id="This_is_a_H1">This is a H1</h1>
98 <h2 id="This_is_a_H2">This is a H2</h2>
99 """
100 var res = test.md_to_html.write_to_string
101 assert res == exp
102 end
103
104 fun test_process_headings_2 do
105 var test = """
106 # This is a H1
107
108 ## This is a H2
109 ###### This is a H6
110 """
111 var exp = """
112 <h1 id="This_is_a_H1">This is a H1</h1>
113 <h2 id="This_is_a_H2">This is a H2</h2>
114 <h6 id="This_is_a_H6">This is a H6</h6>
115 """
116 var res = test.md_to_html.write_to_string
117 assert res == exp
118 end
119
120 fun test_process_headings_3 do
121 var test = """
122 # This is a H1 #
123
124 ## This is a H2 ##
125
126 ### This is a H3 ######
127 """
128 var exp = """
129 <h1 id="This_is_a_H1">This is a H1</h1>
130 <h2 id="This_is_a_H2">This is a H2</h2>
131 <h3 id="This_is_a_H3">This is a H3</h3>
132 """
133 var res = test.md_to_html.write_to_string
134 assert res == exp
135 end
136
137 fun test_process_hr do
138 var test = """
139 * * *
140
141 ***
142
143 *****
144
145 - - -
146
147 ---------------------------------------
148 """
149 var exp = "<hr/>\n<hr/>\n<hr/>\n<hr/>\n<hr/>\n"
150 var res = test.md_to_html.write_to_string
151 assert res == exp
152 end
153
154 fun test_process_bquote1 do
155 var test = """
156 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
157 > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
158 > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
159 >
160 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
161 > id sem consectetuer libero luctus adipiscing.
162 """
163 var exp = """<blockquote>
164 <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
165 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
166 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
167 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
168 id sem consectetuer libero luctus adipiscing.</p>
169 </blockquote>
170 """
171 var res = test.md_to_html.write_to_string
172 assert res == exp
173 end
174
175 fun test_process_bquote2 do
176 var test = """
177 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
178 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
179 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
180
181 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
182 id sem consectetuer libero luctus adipiscing.
183 """
184 var exp = """<blockquote>
185 <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
186 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
187 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
188 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
189 id sem consectetuer libero luctus adipiscing.</p>
190 </blockquote>
191 """
192 var res = test.md_to_html.write_to_string
193 assert res == exp
194 end
195
196 fun test_process_bquote3 do
197 var test = """
198 > This is the first level of quoting.
199 >
200 > > This is nested blockquote.
201 >
202 > Back to the first level.
203 """
204 var exp = """<blockquote>
205 <p>This is the first level of quoting.</p>
206 <blockquote>
207 <p>This is nested blockquote.</p>
208 </blockquote>
209 <p>Back to the first level.</p>
210 </blockquote>
211 """
212 var res = test.md_to_html.write_to_string
213 assert res == exp
214 end
215
216 fun test_process_list1 do
217 var test = """
218 * Red
219 * Green
220 * Blue
221 """
222 var exp = """<ul>
223 <li>Red</li>
224 <li>Green</li>
225 <li>Blue</li>
226 </ul>
227 """
228 var res = test.md_to_html.write_to_string
229 assert res == exp
230 end
231
232 fun test_process_list2 do
233 var test = """
234 + Red
235 + Green
236 + Blue
237 """
238 var exp = """<ul>
239 <li>Red</li>
240 <li>Green</li>
241 <li>Blue</li>
242 </ul>
243 """
244 var res = test.md_to_html.write_to_string
245 assert res == exp
246 end
247
248 fun test_process_list3 do
249 var test = """
250 - Red
251 - Green
252 - Blue
253 """
254 var exp = """<ul>
255 <li>Red</li>
256 <li>Green</li>
257 <li>Blue</li>
258 </ul>
259 """
260 var res = test.md_to_html.write_to_string
261 assert res == exp
262 end
263
264 fun test_process_list4 do
265 var test = """
266 1. Bird
267 2. McHale
268 3. Parish
269 """
270 var exp = """<ol>
271 <li>Bird</li>
272 <li>McHale</li>
273 <li>Parish</li>
274 </ol>
275 """
276 var res = test.md_to_html.write_to_string
277 assert res == exp
278 end
279
280 fun test_process_list5 do
281 var test = """
282 3. Bird
283 1. McHale
284 8. Parish
285 """
286 var exp = """<ol>
287 <li>Bird</li>
288 <li>McHale</li>
289 <li>Parish</li>
290 </ol>
291 """
292 var res = test.md_to_html.write_to_string
293 assert res == exp
294 end
295
296 fun test_process_list6 do
297 var test = """
298 * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
299 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
300 viverra nec, fringilla in, laoreet vitae, risus.
301 * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
302 Suspendisse id sem consectetuer libero luctus adipiscing.
303 """
304 var exp = """
305 <ul>
306 <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
307 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
308 viverra nec, fringilla in, laoreet vitae, risus.</li>
309 <li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
310 Suspendisse id sem consectetuer libero luctus adipiscing.</li>
311 </ul>
312 """
313 var res = test.md_to_html.write_to_string
314 assert res == exp
315 end
316
317 fun test_process_list7 do
318 var test = """
319 * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
320 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
321 viverra nec, fringilla in, laoreet vitae, risus.
322 * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
323 Suspendisse id sem consectetuer libero luctus adipiscing.
324 """
325 var exp = """
326 <ul>
327 <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
328 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
329 viverra nec, fringilla in, laoreet vitae, risus.</li>
330 <li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
331 Suspendisse id sem consectetuer libero luctus adipiscing.</li>
332 </ul>
333 """
334 var res = test.md_to_html.write_to_string
335 assert res == exp
336 end
337
338 fun test_process_list8 do
339 var test = """
340 * Bird
341
342 * Magic
343 """
344 var exp = """
345 <ul>
346 <li><p>Bird</p>
347 </li>
348 <li><p>Magic</p>
349 </li>
350 </ul>
351 """
352 var res = test.md_to_html.write_to_string
353 assert res == exp
354 end
355
356 fun test_process_list9 do
357 var test = """
358 1. This is a list item with two paragraphs. Lorem ipsum dolor
359 sit amet, consectetuer adipiscing elit. Aliquam hendrerit
360 mi posuere lectus.
361
362 Vestibulum enim wisi, viverra nec, fringilla in, laoreet
363 vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
364 sit amet velit.
365
366 2. Suspendisse id sem consectetuer libero luctus adipiscing.
367 """
368 var exp = """
369 <ol>
370 <li><p>This is a list item with two paragraphs. Lorem ipsum dolor
371 sit amet, consectetuer adipiscing elit. Aliquam hendrerit
372 mi posuere lectus.</p>
373 <p>Vestibulum enim wisi, viverra nec, fringilla in, laoreet
374 vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
375 sit amet velit.</p>
376 </li>
377 <li><p>Suspendisse id sem consectetuer libero luctus adipiscing.</p>
378 </li>
379 </ol>
380 """
381 var res = test.md_to_html.write_to_string
382 assert res == exp
383 end
384
385 fun test_process_list10 do
386 var test = """
387 * This is a list item with two paragraphs.
388
389 This is the second paragraph in the list item. You're
390 only required to indent the first line. Lorem ipsum dolor
391 sit amet, consectetuer adipiscing elit.
392
393 * Another item in the same list.
394 """
395 var exp = """
396 <ul>
397 <li><p>This is a list item with two paragraphs.</p>
398 <p>This is the second paragraph in the list item. You're
399 only required to indent the first line. Lorem ipsum dolor
400 sit amet, consectetuer adipiscing elit.</p>
401 </li>
402 <li><p>Another item in the same list.</p>
403 </li>
404 </ul>
405 """
406 var res = test.md_to_html.write_to_string
407 assert res == exp
408 end
409
410 fun test_process_list11 do
411 var test = """
412 This is a paragraph
413 * and this is not a list
414 """
415 var exp = """
416 <p>This is a paragraph
417 * and this is not a list</p>
418 """
419 var proc = new MarkdownProcessor
420 proc.ext_mode = false
421 var res = proc.process(test).write_to_string
422 assert res == exp
423 end
424
425 fun test_process_list_ext do
426 var test = """
427 This is a paragraph
428 * and this is not a list
429 """
430 var exp = """
431 <p>This is a paragraph</p>
432 <ul>
433 <li>and this is not a list</li>
434 </ul>
435 """
436 var res = test.md_to_html.write_to_string
437 assert res == exp
438 end
439
440 fun test_process_code1 do
441 var test = """
442 This is a normal paragraph:
443
444 This is a code block.
445 """
446 var exp = """<p>This is a normal paragraph:</p>
447 <pre><code>This is a code block.
448 </code></pre>
449 """
450 var res = test.md_to_html.write_to_string
451 assert res == exp
452 end
453
454 fun test_process_code2 do
455 var test = """
456 Here is an example of AppleScript:
457
458 tell application "Foo"
459 beep
460 end tell
461
462 <div class="footer">
463 &copy; 2004 Foo Corporation
464 </div>
465 """
466 var exp = """
467 <p>Here is an example of AppleScript:</p>
468 <pre><code>tell application "Foo"
469 beep
470 end tell
471
472 &lt;div class="footer"&gt;
473 &amp;copy; 2004 Foo Corporation
474 &lt;/div&gt;
475 </code></pre>
476 """
477 var res = test.md_to_html.write_to_string
478 assert res == exp
479 end
480
481 fun test_process_code_ext1 do
482 var test = """
483 Here is an example of AppleScript:
484 ~~~
485 tell application "Foo"
486 beep
487 end tell
488
489 <div class="footer">
490 &copy; 2004 Foo Corporation
491 </div>
492 ~~~
493 """
494 var exp = """
495 <p>Here is an example of AppleScript:</p>
496 <pre><code>tell application "Foo"
497 beep
498 end tell
499
500 &lt;div class="footer"&gt;
501 &amp;copy; 2004 Foo Corporation
502 &lt;/div&gt;
503 </code></pre>
504 """
505 var res = test.md_to_html.write_to_string
506 assert res == exp
507 end
508
509 fun test_process_code_ext2 do
510 var test = """
511 Here is an example of AppleScript:
512 ```
513 tell application "Foo"
514 beep
515 end tell
516
517 <div class="footer">
518 &copy; 2004 Foo Corporation
519 </div>
520 ```
521 """
522 var exp = """
523 <p>Here is an example of AppleScript:</p>
524 <pre><code>tell application "Foo"
525 beep
526 end tell
527
528 &lt;div class="footer"&gt;
529 &amp;copy; 2004 Foo Corporation
530 &lt;/div&gt;
531 </code></pre>
532 """
533 var res = test.md_to_html.write_to_string
534 assert res == exp
535 end
536
537 fun test_process_code_ext3 do
538 var proc = new MarkdownProcessor
539 proc.ext_mode = false
540
541 var test = """
542 Here is an example of AppleScript:
543 beep
544 """
545 var exp = """
546 <p>Here is an example of AppleScript:
547 beep</p>
548 """
549 var res = proc.process(test).write_to_string
550 assert res == exp
551 end
552
553 fun test_process_code_ext4 do
554 var test = """
555 Here is an example of AppleScript:
556 beep
557 """
558 var exp = """
559 <p>Here is an example of AppleScript:</p>
560 <pre><code>beep
561 </code></pre>
562 """
563 var res = test.md_to_html.write_to_string
564 assert res == exp
565 end
566
567 fun test_process_code_ext5 do
568 var test = """
569 ```nit
570 print "Hello World!"
571 ```
572 """
573 var exp = """
574 <pre class="nit"><code>print "Hello World!"
575 </code></pre>
576 """
577 var res = test.md_to_html.write_to_string
578 assert res == exp
579 end
580
581 fun test_process_code_ext6 do
582 var test = """
583 ~~~
584 print "Hello"
585 ~~~
586 ~~~
587 print "World"
588 ~~~
589 """
590 var exp = """
591 <pre><code>print "Hello"
592 </code></pre>
593 <pre><code>print "World"
594 </code></pre>
595 """
596 var res = test.md_to_html.write_to_string
597 assert res == exp
598 end
599
600 fun test_process_code_ext7 do
601 var test = """
602 ~~~
603 print "Hello"
604 ~~~
605 ~~~
606 print "World"
607 ~~~
608 """
609 var exp = """
610 <pre><code>print "Hello"
611 </code></pre>
612 <pre><code>print "World"
613 </code></pre>
614 """
615 var res = test.md_to_html.write_to_string
616 assert res == exp
617 end
618
619 fun test_process_nesting1 do
620 var test = """
621 > ## This is a header.
622 >
623 > 1. This is the first list item.
624 > 2. This is the second list item.
625 >
626 > Here's some example code:
627 >
628 > return shell_exec("echo $input | $markdown_script");
629 """
630 var exp = """
631 <blockquote>
632 <h2 id="This_is_a_header.">This is a header.</h2>
633 <ol>
634 <li>This is the first list item.</li>
635 <li>This is the second list item.</li>
636 </ol>
637 <p>Here's some example code:</p>
638 <pre><code>return shell_exec("echo $input | $markdown_script");
639 </code></pre>
640 </blockquote>
641 """
642 var res = test.md_to_html.write_to_string
643 assert res == exp
644 end
645
646 fun test_process_nesting2 do
647 var test = """
648 * A list item with a blockquote:
649
650 > This is a blockquote
651 > inside a list item.
652 """
653 var exp = """
654 <ul>
655 <li><p>A list item with a blockquote:</p>
656 <blockquote>
657 <p>This is a blockquote
658 inside a list item.</p>
659 </blockquote>
660 </li>
661 </ul>
662 """
663 var res = test.md_to_html.write_to_string
664 assert res == exp
665 end
666
667 fun test_process_nesting3 do
668 var test = """
669 * A list item with a code block:
670
671 <code goes here>
672 """
673 var exp = """
674 <ul>
675 <li><p>A list item with a code block:</p>
676 <pre><code>&lt;code goes here&gt;
677 </code></pre>
678 </li>
679 </ul>
680 """
681 var res = test.md_to_html.write_to_string
682 assert res == exp
683 end
684
685 fun test_process_nesting4 do
686 var test = """
687 * Tab
688 * Tab
689 * Tab
690 """
691 var exp = """
692 <ul>
693 <li>Tab<ul>
694 <li>Tab<ul>
695 <li>Tab</li>
696 </ul>
697 </li>
698 </ul>
699 </li>
700 </ul>
701 """
702 var res = test.md_to_html.write_to_string
703 assert res == exp
704 end
705
706 # TODO
707 # fun test_process_nesting5 do
708 # var test = """
709 # * this
710 #
711 # * sub
712 #
713 # that
714 # """
715 # var exp = """
716 # <ul>
717 # <li><p>this</p>
718 # <ul>
719 # <li>sub</li>
720 # </ul>
721 # <p>that</p>
722 # </li>
723 # </ul>
724 # """
725 # var res = test.md_to_html.write_to_string
726 # assert res == exp
727 # end
728
729 fun test_process_emph1 do
730 var test = """
731 *single asterisks*
732
733 _single underscores_
734
735 **double asterisks**
736
737 __double underscores__
738 """
739 var exp = """<p><em>single asterisks</em></p>
740 <p><em>single underscores</em></p>
741 <p><strong>double asterisks</strong></p>
742 <p><strong>double underscores</strong></p>
743 """
744 var res = test.md_to_html.write_to_string
745 assert res == exp
746 end
747
748 fun test_process_emph2 do
749 var test = "un*frigging*believable"
750 var exp = "<p>un<em>frigging</em>believable</p>\n"
751 var res = test.md_to_html.write_to_string
752 assert res == exp
753 end
754
755 fun test_process_emph3 do
756 var proc = new MarkdownProcessor
757 proc.ext_mode = false
758 var test = "Con_cat_this"
759 var exp = "<p>Con<em>cat</em>this</p>\n"
760 var res = proc.process(test).write_to_string
761 assert res == exp
762 end
763
764 fun test_process_emph_ext do
765 var test = "Con_cat_this"
766 var exp = "<p>Con_cat_this</p>\n"
767 var res = test.md_to_html.write_to_string
768 assert res == exp
769 end
770
771 fun test_process_xml1 do
772 var test = """
773 This is a regular paragraph.
774
775 <table>
776 <tr>
777 <td>Foo</td>
778 </tr>
779 </table>
780
781 This is another regular paragraph.
782 """
783 var exp = """
784 <p>This is a regular paragraph.</p>
785 <table>
786 <tr>
787 <td>Foo</td>
788 </tr>
789 </table>
790 <p>This is another regular paragraph.</p>
791 """
792 var res = test.md_to_html.write_to_string
793 assert res == exp
794 end
795
796 fun test_process_xml2 do
797 var test = """
798 This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
799 """
800 var exp = """<p>This is an image <img src="foo/bar" alt="baz" /> in a regular paragraph.</p>
801 """
802 var res = test.md_to_html.write_to_string
803 assert res == exp
804 end
805
806 fun test_process_xml3 do
807 var test = """
808 <div style=">"/>
809 """
810 var exp = """
811 <div style=">"/>
812 """
813 var res = test.md_to_html.write_to_string
814 assert res == exp
815 end
816
817 fun test_process_xml4 do
818 var test = """
819 <p>This is an example of a block element that should be escaped.</p>
820 <p>Idem for the second paragraph.</p>
821 """
822 var exp = test
823 var res = test.md_to_html.write_to_string
824 assert res == exp
825 end
826
827 fun test_process_xml5 do
828 var test = """
829 # Some more XML tests
830
831 <p>This is an example of a block element that should be escaped.</p>
832 <p>Idem for the second paragraph.</p>
833
834 With a *md paragraph*!
835 """
836 var exp = """
837 <h1 id="Some_more_XML_tests">Some more XML tests</h1>
838 <p>This is an example of a block element that should be escaped.</p>
839 <p>Idem for the second paragraph.</p>
840 <p>With a <em>md paragraph</em>!</p>
841 """
842 var res = test.md_to_html.write_to_string
843 print res
844 assert res == exp
845 end
846
847 fun test_process_span_code1 do
848 var test = "Use the `printf()` function."
849 var exp = "<p>Use the <code>printf()</code> function.</p>\n"
850 var res = test.md_to_html.write_to_string
851 assert res == exp
852 end
853
854 fun test_process_span_code2 do
855 var test = "``There is a literal backtick (`) here.``"
856 var exp = "<p><code>There is a literal backtick (`) here.</code></p>\n"
857 var res = test.md_to_html.write_to_string
858 assert res == exp
859 end
860
861 fun test_process_span_code3 do
862 var test = """
863 A single backtick in a code span: `` ` ``
864
865 A backtick-delimited string in a code span: `` `foo` ``
866 """
867 var exp = """
868 <p>A single backtick in a code span: <code>`</code></p>
869 <p>A backtick-delimited string in a code span: <code>`foo`</code></p>
870 """
871 var res = test.md_to_html.write_to_string
872 assert res == exp
873 end
874
875 fun test_process_span_code4 do
876 var test = "Please don't use any `<blink>` tags."
877 var exp = "<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>\n"
878 var res = test.md_to_html.write_to_string
879 assert res == exp
880 end
881
882 fun test_process_span_code5 do
883 var test = "`&#8212;` is the decimal-encoded equivalent of `&mdash;`."
884 var exp = "<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>\n"
885 var res = test.md_to_html.write_to_string
886 assert res == exp
887 end
888
889 fun test_process_escape1 do
890 var test = "\\*this text is surrounded by literal asterisks\\*"
891 var exp = "<p>*this text is surrounded by literal asterisks*</p>\n"
892 var res = test.md_to_html.write_to_string
893 assert res == exp
894 end
895
896 fun test_process_escape2 do
897 var test = "1986\\. What a great season."
898 var exp = "<p>1986. What a great season.</p>\n"
899 var res = test.md_to_html.write_to_string
900 assert res == exp
901 end
902
903 fun test_process_escape3 do
904 var test = "Ben & Lux"
905 var exp = "<p>Ben &amp; Lux</p>\n"
906 var res = test.md_to_html.write_to_string
907 assert res == exp
908 end
909
910 fun test_process_link1 do
911 var test = """
912 This is [an example](http://example.com/ "Title") inline link.
913
914 [This link](http://example.net/) has no title attribute.
915 """
916 var exp = """<p>This is <a href="http://example.com/" title="Title">an example</a> inline link.</p>
917 <p><a href="http://example.net/">This link</a> has no title attribute.</p>
918 """
919 var res = test.md_to_html.write_to_string
920 assert res == exp
921 end
922
923 fun test_process_link2 do
924 var test = "See my [About](/about/) page for details."
925 var exp = "<p>See my <a href=\"/about/\">About</a> page for details.</p>\n"
926 var res = test.md_to_html.write_to_string
927 assert res == exp
928 end
929
930 fun test_process_link3 do
931 var test = """
932 This is [an example][id] reference-style link.
933
934 This is [an example] [id] reference-style link.
935
936 Some lorem ipsum
937
938 [id]: http://example.com/ "Optional Title Here"
939
940 Some other lipsum
941 """
942 var exp = """
943 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
944 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
945 <p>Some lorem ipsum</p>
946 <p>Some other lipsum</p>
947 """
948 var res = test.md_to_html.write_to_string
949 assert res == exp
950 end
951
952 fun test_process_link4 do
953 var test = """
954 This is multiple examples: [foo][1], [bar][2], [baz][3].
955
956 [1]: http://example.com/ "Optional Title Here"
957 [2]: http://example.com/ 'Optional Title Here'
958 [3]: http://example.com/ (Optional Title Here)
959 """
960 var exp = """
961 <p>This is multiple examples: <a href="http://example.com/" title="Optional Title Here">foo</a>, <a href="http://example.com/" title="Optional Title Here">bar</a>, <a href="http://example.com/" title="Optional Title Here">baz</a>.</p>
962 """
963 var res = test.md_to_html.write_to_string
964 assert res == exp
965 end
966
967 fun test_process_link5 do
968 var test = """
969 This is multiple examples: [foo][a], [bar][A], [a].
970
971 [a]: http://example.com/ "Optional Title Here"
972 """
973 var exp = """<p>This is multiple examples: <a href="http://example.com/" title="Optional Title Here">foo</a>, <a href="http://example.com/" title="Optional Title Here">bar</a>, <a href="http://example.com/" title="Optional Title Here">a</a>.</p>
974 """
975 var res = test.md_to_html.write_to_string
976 assert res == exp
977 end
978
979 fun test_process_link6 do
980 var test = """
981 I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
982
983 [Google]: http://google.com/ "Google"
984 [Yahoo]: http://search.yahoo.com/ "Yahoo Search"
985 [MSN]: http://search.msn.com/ "MSN Search"
986 """
987 var exp = """<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
988 """
989 var res = test.md_to_html.write_to_string
990 assert res == exp
991 end
992
993 fun test_process_link7 do
994 var test = """
995 Visit [Daring Fireball][] for more information.
996
997 [Daring Fireball]: http://daringfireball.net/
998 """
999 var exp = """<p>Visit <a href="http://daringfireball.net/">Daring Fireball</a> for more information.</p>
1000 """
1001 var res = test.md_to_html.write_to_string
1002 assert res == exp
1003 end
1004
1005 fun test_process_link8 do
1006 var test = """
1007 This one has a [line
1008 break].
1009
1010 This one has a [line
1011 break] with a line-ending space.
1012
1013 [line break]: /foo
1014 """
1015 var exp = """
1016 <p>This one has a <a href="/foo">line
1017 break</a>.</p>
1018 <p>This one has a <a href="/foo">line
1019 break</a> with a line-ending space.</p>
1020 """
1021 var res = test.md_to_html.write_to_string
1022 assert res == exp
1023 end
1024
1025 # FIXME unignore test once escape strings fixed
1026 # fun test_process_link9 do
1027 # var test = """
1028 # Foo [bar][].
1029 #
1030 # Foo [bar](/url/ "Title with \"quotes\" inside").
1031 #
1032 #
1033 # [bar]: /url/ "Title with \"quotes\" inside"
1034 # """
1035 # var exp = """
1036 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
1037 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
1038 # """
1039 # var res = test.md_to_html.write_to_string
1040 # assert res == exp
1041 # end
1042
1043 fun test_process_img1 do
1044 var test = """
1045 ![Alt text](/path/to/img.jpg)
1046
1047 ![Alt text](/path/to/img.jpg "Optional title")
1048 """
1049 var exp = """<p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1050 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1051 """
1052 var res = test.md_to_html.write_to_string
1053 assert res == exp
1054 end
1055
1056 fun test_process_img2 do
1057 var test = """
1058 ![Alt text][id]
1059
1060 [id]: url/to/image "Optional title attribute"
1061 """
1062 var exp = """<p><img src="url/to/image" alt="Alt text" title="Optional title attribute"/></p>
1063 """
1064 var res = test.md_to_html.write_to_string
1065 assert res == exp
1066 end
1067
1068 fun test_process_strike do
1069 var proc = new MarkdownProcessor
1070 proc.ext_mode = false
1071 var test = "This is how you ~~strike text~~"
1072 var exp = "<p>This is how you ~~strike text~~</p>\n"
1073 var res = proc.process(test).write_to_string
1074 assert exp == res
1075 end
1076
1077 fun test_process_strike_ext do
1078 var test = "This is how you ~~strike text~~"
1079 var exp = "<p>This is how you <del>strike text</del></p>\n"
1080 var res = test.md_to_html.write_to_string
1081 assert exp == res
1082 end
1083
1084 fun test_escape_bad_html do
1085 var test = "-1 if < , +1 if > and 0 otherwise"
1086 var exp = "<p>-1 if &lt; , +1 if > and 0 otherwise</p>\n"
1087 var res = test.md_to_html.write_to_string
1088 assert exp == res
1089 end
1090
1091 fun test_daring_encoding do
1092 var test = """
1093 AT&T has an ampersand in their name.
1094
1095 AT&amp;T is another way to write it.
1096
1097 This & that.
1098
1099 4 < 5.
1100
1101 6 > 5.
1102
1103 Here's a [link] [1] with an ampersand in the URL.
1104
1105 Here's a link with an amersand in the link text: [AT&T] [2].
1106
1107 Here's an inline [link](/script?foo=1&bar=2).
1108
1109 Here's an inline [link](</script?foo=1&bar=2>).
1110
1111
1112 [1]: http://example.com/?foo=1&bar=2
1113 [2]: http://att.com/ "AT&T"
1114 """
1115
1116 var exp = """
1117 <p>AT&amp;T has an ampersand in their name.</p>
1118 <p>AT&amp;T is another way to write it.</p>
1119 <p>This &amp; that.</p>
1120 <p>4 &lt; 5.</p>
1121 <p>6 > 5.</p>
1122 <p>Here's a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
1123 <p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&amp;T">AT&amp;T</a>.</p>
1124 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1125 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1126 """
1127 var res = test.md_to_html.write_to_string
1128 assert res == exp
1129
1130 end
1131
1132 fun test_daring_autolinks do
1133 var test = """
1134 Link: <http://example.com/>.
1135
1136 With an ampersand: <http://example.com/?foo=1&bar=2>
1137
1138 * In a list?
1139 * <http://example.com/>
1140 * It should.
1141
1142 > Blockquoted: <http://example.com/>
1143
1144 Auto-links should not occur here: `<http://example.com/>`
1145
1146 or here: <http://example.com/>
1147 """
1148
1149 var exp = """
1150 <p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
1151 <p>With an ampersand: <a href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</a></p>
1152 <ul>
1153 <li>In a list?</li>
1154 <li><a href="http://example.com/">http://example.com/</a></li>
1155 <li>It should.</li>
1156 </ul>
1157 <blockquote>
1158 <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
1159 </blockquote>
1160 <p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
1161 <pre><code>or here: &lt;http://example.com/&gt;
1162 </code></pre>
1163 """
1164 var res = test.md_to_html.write_to_string
1165 assert res == exp
1166 end
1167
1168 fun test_daring_escape do
1169 var test = """
1170 These should all get escaped:
1171
1172 Backslash: \\
1173
1174 Backtick: \`
1175
1176 Asterisk: \*
1177
1178 Underscore: \_
1179
1180 Left brace: \{
1181
1182 Right brace: \}
1183
1184 Left bracket: \[
1185
1186 Right bracket: \]
1187
1188 Left paren: \(
1189
1190 Right paren: \)
1191
1192 Greater-than: \>
1193
1194 Hash: \#
1195
1196 Period: \.
1197
1198 Bang: \!
1199
1200 Plus: \+
1201
1202 Minus: \-
1203
1204
1205 These should not, because they occur within a code block:
1206
1207 Backslash: \\
1208
1209 Backtick: \`
1210
1211 Asterisk: \*
1212
1213 Underscore: \_
1214
1215 Left brace: \{
1216
1217 Right brace: \}
1218
1219 Left bracket: \[
1220
1221 Right bracket: \]
1222
1223 Left paren: \(
1224
1225 Right paren: \)
1226
1227 Greater-than: \>
1228
1229 Hash: \#
1230
1231 Period: \.
1232
1233 Bang: \!
1234
1235 Plus: \+
1236
1237 Minus: \-
1238
1239 Nor should these, which occur in code spans:
1240
1241 Backslash: `\\`
1242
1243 Backtick: `` \` ``
1244
1245 Asterisk: `\*`
1246
1247 Underscore: `\_`
1248
1249 Left brace: `\{`
1250
1251 Right brace: `\}`
1252
1253 Left bracket: `\[`
1254
1255 Right bracket: `\]`
1256
1257 Left paren: `\(`
1258
1259 Right paren: `\)`
1260
1261 Greater-than: `\>`
1262
1263 Hash: `\#`
1264
1265 Period: `\.`
1266
1267 Bang: `\!`
1268
1269 Plus: `\+`
1270
1271 Minus: `\-`
1272
1273 These should get escaped, even though they're matching pairs for
1274 other Markdown constructs:
1275
1276 \\\*asterisks\\\*
1277
1278 \\\_underscores\\\_
1279
1280 \\\`backticks\\\`
1281
1282 This is a code span with a literal backslash-backtick sequence: `` \` ``
1283
1284 This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
1285
1286 This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.
1287 """
1288 var exp = """
1289 <p>These should all get escaped:</p>
1290 <p>Backslash: \\</p>
1291 <p>Backtick: \`</p>
1292 <p>Asterisk: \*</p>
1293 <p>Underscore: \_</p>
1294 <p>Left brace: \{</p>
1295 <p>Right brace: \}</p>
1296 <p>Left bracket: \[</p>
1297 <p>Right bracket: \]</p>
1298 <p>Left paren: \(</p>
1299 <p>Right paren: \)</p>
1300 <p>Greater-than: \></p>
1301 <p>Hash: \#</p>
1302 <p>Period: \.</p>
1303 <p>Bang: \!</p>
1304 <p>Plus: \+</p>
1305 <p>Minus: \-</p>
1306 <p>These should not, because they occur within a code block:</p>
1307 <pre><code>Backslash: \\
1308
1309 Backtick: \`
1310
1311 Asterisk: \*
1312
1313 Underscore: \_
1314
1315 Left brace: \{
1316
1317 Right brace: \}
1318
1319 Left bracket: \[
1320
1321 Right bracket: \]
1322
1323 Left paren: \(
1324
1325 Right paren: \)
1326
1327 Greater-than: \&gt;
1328
1329 Hash: \#
1330
1331 Period: \.
1332
1333 Bang: \!
1334
1335 Plus: \+
1336
1337 Minus: \-
1338 </code></pre>
1339 <p>Nor should these, which occur in code spans:</p>
1340 <p>Backslash: <code>\\</code></p>
1341 <p>Backtick: <code>\`</code></p>
1342 <p>Asterisk: <code>\*</code></p>
1343 <p>Underscore: <code>\_</code></p>
1344 <p>Left brace: <code>\{</code></p>
1345 <p>Right brace: <code>\}</code></p>
1346 <p>Left bracket: <code>\[</code></p>
1347 <p>Right bracket: <code>\]</code></p>
1348 <p>Left paren: <code>\(</code></p>
1349 <p>Right paren: <code>\)</code></p>
1350 <p>Greater-than: <code>\&gt;</code></p>
1351 <p>Hash: <code>\#</code></p>
1352 <p>Period: <code>\.</code></p>
1353 <p>Bang: <code>\!</code></p>
1354 <p>Plus: <code>\+</code></p>
1355 <p>Minus: <code>\-</code></p>
1356 <p>These should get escaped, even though they're matching pairs for
1357 other Markdown constructs:</p>
1358 <p>*asterisks*</p>
1359 <p>_underscores_</p>
1360 <p>`backticks`</p>
1361 <p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
1362 <p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
1363 <p>This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.</p>
1364 """
1365
1366 var res = test.md_to_html.write_to_string
1367 assert res == exp
1368 end
1369
1370 fun test_daring_blockquotes do
1371 var test = """
1372 > Example:
1373 >
1374 > sub status {
1375 > print "working";
1376 > }
1377 >
1378 > Or:
1379 >
1380 > sub status {
1381 > return "working";
1382 > }
1383 """
1384
1385 var exp = """
1386 <blockquote>
1387 <p>Example:</p>
1388 <pre><code>sub status {
1389 print "working";
1390 }
1391 </code></pre>
1392 <p>Or:</p>
1393 <pre><code>sub status {
1394 return "working";
1395 }
1396 </code></pre>
1397 </blockquote>
1398 """
1399 var res = test.md_to_html.write_to_string
1400 assert res == exp
1401 end
1402
1403 fun test_daring_code_blocks do
1404 var test = """
1405 code block on the first line
1406
1407 Regular text.
1408
1409 code block indented by spaces
1410
1411 Regular text.
1412
1413 the lines in this block
1414 all contain trailing spaces
1415
1416 Regular Text.
1417
1418 code block on the last line
1419 """
1420
1421 var exp = """
1422 <pre><code>code block on the first line
1423 </code></pre>
1424 <p>Regular text.</p>
1425 <pre><code>code block indented by spaces
1426 </code></pre>
1427 <p>Regular text.</p>
1428 <pre><code>the lines in this block
1429 all contain trailing spaces
1430 </code></pre>
1431 <p>Regular Text.</p>
1432 <pre><code>code block on the last line
1433 </code></pre>
1434 """
1435 var res = test.md_to_html.write_to_string
1436 assert res == exp
1437 end
1438
1439 fun test_daring_code_spans do
1440 var test = """
1441 `<test a="` content of attribute `">`
1442
1443 Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
1444
1445 Here's how you put `` `backticks` `` in a code span.
1446 """
1447
1448 var exp = """
1449 <p><code>&lt;test a="</code> content of attribute <code>"&gt;</code></p>
1450 <p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
1451 <p>Here's how you put <code>`backticks`</code> in a code span.</p>
1452 """
1453 var res = test.md_to_html.write_to_string
1454 assert res == exp
1455 end
1456
1457 fun test_daring_pars do
1458 var proc = new MarkdownProcessor
1459 proc.ext_mode = false
1460
1461 var test = """
1462 In Markdown 1.0.0 and earlier. Version
1463 8. This line turns into a list item.
1464 Because a hard-wrapped line in the
1465 middle of a paragraph looked like a
1466 list item.
1467
1468 Here's one with a bullet.
1469 * criminey.
1470 """
1471
1472 var exp = """
1473 <p>In Markdown 1.0.0 and earlier. Version
1474 8. This line turns into a list item.
1475 Because a hard-wrapped line in the
1476 middle of a paragraph looked like a
1477 list item.</p>
1478 <p>Here's one with a bullet.
1479 * criminey.</p>
1480 """
1481 var res = proc.process(test).write_to_string
1482 assert res == exp
1483 end
1484
1485 fun test_daring_rules do
1486 var test = """
1487 Dashes:
1488
1489 ---
1490
1491 ---
1492
1493 ---
1494
1495 ---
1496
1497 ---
1498
1499 - - -
1500
1501 - - -
1502
1503 - - -
1504
1505 - - -
1506
1507 - - -
1508
1509
1510 Asterisks:
1511
1512 ***
1513
1514 ***
1515
1516 ***
1517
1518 ***
1519
1520 ***
1521
1522 * * *
1523
1524 * * *
1525
1526 * * *
1527
1528 * * *
1529
1530 * * *
1531
1532
1533 Underscores:
1534
1535 ___
1536
1537 ___
1538
1539 ___
1540
1541 ___
1542
1543 ___
1544
1545 _ _ _
1546
1547 _ _ _
1548
1549 _ _ _
1550
1551 _ _ _
1552
1553 _ _ _
1554 """
1555
1556 var exp = """
1557 <p>Dashes:</p>
1558 <hr/>
1559 <hr/>
1560 <hr/>
1561 <hr/>
1562 <pre><code>---
1563 </code></pre>
1564 <hr/>
1565 <hr/>
1566 <hr/>
1567 <hr/>
1568 <pre><code>- - -
1569 </code></pre>
1570 <p>Asterisks:</p>
1571 <hr/>
1572 <hr/>
1573 <hr/>
1574 <hr/>
1575 <pre><code>***
1576 </code></pre>
1577 <hr/>
1578 <hr/>
1579 <hr/>
1580 <hr/>
1581 <pre><code>* * *
1582 </code></pre>
1583 <p>Underscores:</p>
1584 <hr/>
1585 <hr/>
1586 <hr/>
1587 <hr/>
1588 <pre><code>___
1589 </code></pre>
1590 <hr/>
1591 <hr/>
1592 <hr/>
1593 <hr/>
1594 <pre><code>_ _ _
1595 </code></pre>
1596 """
1597 var res = test.md_to_html.write_to_string
1598 assert res == exp
1599 end
1600
1601 fun test_daring_images do
1602 var test = """
1603 ![Alt text](/path/to/img.jpg)
1604
1605 ![Alt text](/path/to/img.jpg "Optional title")
1606
1607 Inline within a paragraph: [alt text](/url/).
1608
1609 ![alt text](/url/ "title preceded by two spaces")
1610
1611 ![alt text](/url/ "title has spaces afterward" )
1612
1613 ![alt text](</url/>)
1614
1615 ![alt text](</url/> "with a title").
1616
1617 ![Empty]()
1618
1619 ![this is a stupid URL](http://example.com/(parens).jpg)
1620
1621
1622 ![alt text][foo]
1623
1624 [foo]: /url/
1625
1626 ![alt text][bar]
1627
1628 [bar]: /url/ "Title here"
1629 """
1630
1631 var exp = """
1632 <p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1633 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1634 <p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
1635 <p><img src="/url/" alt="alt text" title="title preceded by two spaces"/></p>
1636 <p><img src="/url/" alt="alt text" title="title has spaces afterward"/></p>
1637 <p><img src="/url/" alt="alt text"/></p>
1638 <p><img src="/url/" alt="alt text" title="with a title"/>.</p>
1639 <p><img src="" alt="Empty"/></p>
1640 <p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL"/></p>
1641 <p><img src="/url/" alt="alt text"/></p>
1642 <p><img src="/url/" alt="alt text" title="Title here"/></p>
1643 """
1644 var res = test.md_to_html.write_to_string
1645 assert res == exp
1646 end
1647
1648 fun test_daring_inline_html1 do
1649 var test = """
1650 Here's a simple block:
1651
1652 <div>
1653 foo
1654 </div>
1655
1656 This should be a code block, though:
1657
1658 <div>
1659 foo
1660 </div>
1661
1662 As should this:
1663
1664 <div>foo</div>
1665
1666 Now, nested:
1667
1668 <div>
1669 <div>
1670 <div>
1671 foo
1672 </div>
1673 </div>
1674 </div>
1675
1676 This should just be an HTML comment:
1677
1678 <!-- Comment -->
1679
1680 Multiline:
1681
1682 <!--
1683 Blah
1684 Blah
1685 -->
1686
1687 Code block:
1688
1689 <!-- Comment -->
1690
1691 Just plain comment, with trailing spaces on the line:
1692
1693 <!-- foo -->
1694
1695 Code:
1696
1697 <hr />
1698
1699 Hr's:
1700
1701 <hr>
1702
1703 <hr/>
1704
1705 <hr />
1706
1707 <hr>
1708
1709 <hr/>
1710
1711 <hr />
1712
1713 <hr class="foo" id="bar" />
1714
1715 <hr class="foo" id="bar"/>
1716
1717 <hr class="foo" id="bar" >
1718 """
1719
1720 var exp = """
1721 <p>Here's a simple block:</p>
1722 <div>
1723 foo
1724 </div>
1725 <p>This should be a code block, though:</p>
1726 <pre><code>&lt;div&gt;
1727 foo
1728 &lt;/div&gt;
1729 </code></pre>
1730 <p>As should this:</p>
1731 <pre><code>&lt;div&gt;foo&lt;/div&gt;
1732 </code></pre>
1733 <p>Now, nested:</p>
1734 <div>
1735 <div>
1736 <div>
1737 foo
1738 </div>
1739 </div>
1740 </div>
1741 <p>This should just be an HTML comment:</p>
1742 <!-- Comment -->
1743 <p>Multiline:</p>
1744 <!--
1745 Blah
1746 Blah
1747 -->
1748 <p>Code block:</p>
1749 <pre><code>&lt;!-- Comment --&gt;
1750 </code></pre>
1751 <p>Just plain comment, with trailing spaces on the line:</p>
1752 <!-- foo -->
1753 <p>Code:</p>
1754 <pre><code>&lt;hr /&gt;
1755 </code></pre>
1756 <p>Hr's:</p>
1757 <hr>
1758 <hr/>
1759 <hr />
1760 <hr>
1761 <hr/>
1762 <hr />
1763 <hr class="foo" id="bar" />
1764 <hr class="foo" id="bar"/>
1765 <hr class="foo" id="bar" >
1766 """
1767 var res = test.md_to_html.write_to_string
1768 assert res == exp
1769 end
1770
1771 fun test_daring_inline_html2 do
1772 var test = """
1773 Simple block on one line:
1774
1775 <div>foo</div>
1776
1777 And nested without indentation:
1778
1779 <div>
1780 <div>
1781 <div>
1782 foo
1783 </div>
1784 <div style=">"/>
1785 </div>
1786 <div>bar</div>
1787 </div>
1788
1789 And with attributes:
1790
1791 <div>
1792 <div id="foo">
1793 </div>
1794 </div>
1795
1796 This was broken in 1.0.2b7:
1797
1798 <div class="inlinepage">
1799 <div class="toggleableend">
1800 foo
1801 </div>
1802 </div>
1803 """
1804
1805 var exp = """
1806 <p>Simple block on one line:</p>
1807 <div>foo</div>
1808 <p>And nested without indentation:</p>
1809 <div>
1810 <div>
1811 <div>
1812 foo
1813 </div>
1814 <div style=">"/>
1815 </div>
1816 <div>bar</div>
1817 </div>
1818 <p>And with attributes:</p>
1819 <div>
1820 <div id="foo">
1821 </div>
1822 </div>
1823 <p>This was broken in 1.0.2b7:</p>
1824 <div class="inlinepage">
1825 <div class="toggleableend">
1826 foo
1827 </div>
1828 </div>
1829 """
1830 var res = test.md_to_html.write_to_string
1831 assert res == exp
1832 end
1833
1834 fun test_daring_inline_html3 do
1835 var test = """
1836 Paragraph one.
1837
1838 <!-- This is a simple comment -->
1839
1840 <!--
1841 This is another comment.
1842 -->
1843
1844 Paragraph two.
1845
1846 <!-- one comment block -- -- with two comments -->
1847
1848 The end.
1849 """
1850
1851 var exp = """
1852 <p>Paragraph one.</p>
1853 <!-- This is a simple comment -->
1854 <!--
1855 This is another comment.
1856 -->
1857 <p>Paragraph two.</p>
1858 <!-- one comment block -- -- with two comments -->
1859 <p>The end.</p>
1860 """
1861 var res = test.md_to_html.write_to_string
1862 assert res == exp
1863 end
1864
1865 fun test_daring_links1 do
1866 var test = """
1867 Just a [URL](/url/).
1868
1869 [URL and title](/url/ "title").
1870
1871 [URL and title](/url/ "title preceded by two spaces").
1872
1873 [URL and title](/url/ "title preceded by a tab").
1874
1875 [URL and title](/url/ "title has spaces afterward" ).
1876
1877 [URL wrapped in angle brackets](</url/>).
1878
1879 [URL w/ angle brackets + title](</url/> "Here's the title").
1880
1881 [Empty]().
1882
1883 [With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
1884
1885 (With outer parens and [parens in url](/foo(bar)))
1886
1887
1888 [With parens in the URL](/foo(bar) "and a title")
1889
1890 (With outer parens and [parens in url](/foo(bar) "and a title"))
1891 """
1892
1893 var exp = """
1894 <p>Just a <a href="/url/">URL</a>.</p>
1895 <p><a href="/url/" title="title">URL and title</a>.</p>
1896 <p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
1897 <p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
1898 <p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
1899 <p><a href="/url/">URL wrapped in angle brackets</a>.</p>
1900 <p><a href="/url/" title="Here&apos;s the title">URL w/ angle brackets + title</a>.</p>
1901 <p><a href="">Empty</a>.</p>
1902 <p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
1903 <p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
1904 <p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
1905 <p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>
1906 """
1907 var res = test.md_to_html.write_to_string
1908 assert res == exp
1909 end
1910
1911 fun test_daring_links2 do
1912 var test = """
1913 Foo [bar] [1].
1914
1915 Foo [bar][1].
1916
1917 Foo [bar]
1918 [1].
1919
1920 [1]: /url/ "Title"
1921
1922
1923 With [embedded [brackets]] [b].
1924
1925
1926 Indented [once][].
1927
1928 Indented [twice][].
1929
1930 Indented [thrice][].
1931
1932 Indented [four][] times.
1933
1934 [once]: /url
1935
1936 [twice]: /url
1937
1938 [thrice]: /url
1939
1940 [four]: /url
1941
1942
1943 [b]: /url/
1944
1945 * * *
1946
1947 [this] [this] should work
1948
1949 So should [this][this].
1950
1951 And [this] [].
1952
1953 And [this][].
1954
1955 And [this].
1956
1957 But not [that] [].
1958
1959 Nor [that][].
1960
1961 Nor [that].
1962
1963 [Something in brackets like [this][] should work]
1964
1965 [Same with [this].]
1966
1967 In this case, [this](/somethingelse/) points to something else.
1968
1969 Backslashing should suppress \\\[this] and [this\\\].
1970
1971 [this]: foo
1972
1973
1974 * * *
1975
1976 Here's one where the [link
1977 breaks] across lines.
1978
1979 Here's another where the [link
1980 breaks] across lines, but with a line-ending space.
1981
1982
1983 [link breaks]: /url/
1984 """
1985
1986 var exp = """
1987 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1988 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1989 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1990 <p>With <a href="/url/">embedded [brackets]</a>.</p>
1991 <p>Indented <a href="/url">once</a>.</p>
1992 <p>Indented <a href="/url">twice</a>.</p>
1993 <p>Indented <a href="/url">thrice</a>.</p>
1994 <p>Indented [four][] times.</p>
1995 <pre><code>[four]: /url
1996 </code></pre>
1997 <hr/>
1998 <p><a href="foo">this</a> should work</p>
1999 <p>So should <a href="foo">this</a>.</p>
2000 <p>And <a href="foo">this</a>.</p>
2001 <p>And <a href="foo">this</a>.</p>
2002 <p>And <a href="foo">this</a>.</p>
2003 <p>But not [that] [].</p>
2004 <p>Nor [that][].</p>
2005 <p>Nor [that].</p>
2006 <p>[Something in brackets like <a href="foo">this</a> should work]</p>
2007 <p>[Same with <a href="foo">this</a>.]</p>
2008 <p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
2009 <p>Backslashing should suppress [this] and [this].</p>
2010 <hr/>
2011 <p>Here's one where the <a href="/url/">link
2012 breaks</a> across lines.</p>
2013 <p>Here's another where the <a href="/url/">link
2014 breaks</a> across lines, but with a line-ending space.</p>
2015 """
2016 var res = test.md_to_html.write_to_string
2017 assert res == exp
2018 end
2019
2020 fun test_daring_links3 do
2021 var test = """
2022 This is the [simple case].
2023
2024 [simple case]: /simple
2025
2026
2027
2028 This one has a [line
2029 break].
2030
2031 This one has a [line
2032 break] with a line-ending space.
2033
2034 [line break]: /foo
2035
2036
2037 [this] [that] and the [other]
2038
2039 [this]: /this
2040 [that]: /that
2041 [other]: /other
2042 """
2043
2044 var exp = """
2045 <p>This is the <a href="/simple">simple case</a>.</p>
2046 <p>This one has a <a href="/foo">line
2047 break</a>.</p>
2048 <p>This one has a <a href="/foo">line
2049 break</a> with a line-ending space.</p>
2050 <p><a href="/that">this</a> and the <a href="/other">other</a></p>
2051 """
2052 var res = test.md_to_html.write_to_string
2053 assert res == exp
2054 end
2055
2056 fun test_daring_nested do
2057 var test = """
2058 > foo
2059 >
2060 > > bar
2061 >
2062 > foo
2063 """
2064
2065 var exp = """
2066 <blockquote>
2067 <p>foo</p>
2068 <blockquote>
2069 <p>bar</p>
2070 </blockquote>
2071 <p>foo</p>
2072 </blockquote>
2073 """
2074 var res = test.md_to_html.write_to_string
2075 assert res == exp
2076 end
2077
2078 fun test_daring_list do
2079 var test = """
2080 ## Unordered
2081
2082 Asterisks tight:
2083
2084 * asterisk 1
2085 * asterisk 2
2086 * asterisk 3
2087
2088
2089 Asterisks loose:
2090
2091 * asterisk 1
2092
2093 * asterisk 2
2094
2095 * asterisk 3
2096
2097 * * *
2098
2099 Pluses tight:
2100
2101 + Plus 1
2102 + Plus 2
2103 + Plus 3
2104
2105
2106 Pluses loose:
2107
2108 + Plus 1
2109
2110 + Plus 2
2111
2112 + Plus 3
2113
2114 * * *
2115
2116
2117 Minuses tight:
2118
2119 - Minus 1
2120 - Minus 2
2121 - Minus 3
2122
2123
2124 Minuses loose:
2125
2126 - Minus 1
2127
2128 - Minus 2
2129
2130 - Minus 3
2131
2132
2133 ## Ordered
2134
2135 Tight:
2136
2137 1. First
2138 2. Second
2139 3. Third
2140
2141 and:
2142
2143 1. One
2144 2. Two
2145 3. Three
2146
2147
2148 Loose using tabs:
2149
2150 1. First
2151
2152 2. Second
2153
2154 3. Third
2155
2156 and using spaces:
2157
2158 1. One
2159
2160 2. Two
2161
2162 3. Three
2163
2164 Multiple paragraphs:
2165
2166 1. Item 1, graf one.
2167
2168 Item 2. graf two. The quick brown fox jumped over the lazy dog's
2169 back.
2170
2171 2. Item 2.
2172
2173 3. Item 3.
2174
2175
2176
2177 ## Nested
2178
2179 * Tab
2180 * Tab
2181 * Tab
2182
2183 Here's another:
2184
2185 1. First
2186 2. Second:
2187 * Fee
2188 * Fie
2189 * Foe
2190 3. Third
2191
2192 Same thing but with paragraphs:
2193
2194 1. First
2195
2196 2. Second:
2197 * Fee
2198 * Fie
2199 * Foe
2200
2201 3. Third
2202 """
2203
2204 var exp = """
2205 <h2 id="Unordered">Unordered</h2>
2206 <p>Asterisks tight:</p>
2207 <ul>
2208 <li>asterisk 1</li>
2209 <li>asterisk 2</li>
2210 <li>asterisk 3</li>
2211 </ul>
2212 <p>Asterisks loose:</p>
2213 <ul>
2214 <li><p>asterisk 1</p>
2215 </li>
2216 <li><p>asterisk 2</p>
2217 </li>
2218 <li><p>asterisk 3</p>
2219 </li>
2220 </ul>
2221 <hr/>
2222 <p>Pluses tight:</p>
2223 <ul>
2224 <li>Plus 1</li>
2225 <li>Plus 2</li>
2226 <li>Plus 3</li>
2227 </ul>
2228 <p>Pluses loose:</p>
2229 <ul>
2230 <li><p>Plus 1</p>
2231 </li>
2232 <li><p>Plus 2</p>
2233 </li>
2234 <li><p>Plus 3</p>
2235 </li>
2236 </ul>
2237 <hr/>
2238 <p>Minuses tight:</p>
2239 <ul>
2240 <li>Minus 1</li>
2241 <li>Minus 2</li>
2242 <li>Minus 3</li>
2243 </ul>
2244 <p>Minuses loose:</p>
2245 <ul>
2246 <li><p>Minus 1</p>
2247 </li>
2248 <li><p>Minus 2</p>
2249 </li>
2250 <li><p>Minus 3</p>
2251 </li>
2252 </ul>
2253 <h2 id="Ordered">Ordered</h2>
2254 <p>Tight:</p>
2255 <ol>
2256 <li>First</li>
2257 <li>Second</li>
2258 <li>Third</li>
2259 </ol>
2260 <p>and:</p>
2261 <ol>
2262 <li>One</li>
2263 <li>Two</li>
2264 <li>Three</li>
2265 </ol>
2266 <p>Loose using tabs:</p>
2267 <ol>
2268 <li><p>First</p>
2269 </li>
2270 <li><p>Second</p>
2271 </li>
2272 <li><p>Third</p>
2273 </li>
2274 </ol>
2275 <p>and using spaces:</p>
2276 <ol>
2277 <li><p>One</p>
2278 </li>
2279 <li><p>Two</p>
2280 </li>
2281 <li><p>Three</p>
2282 </li>
2283 </ol>
2284 <p>Multiple paragraphs:</p>
2285 <ol>
2286 <li><p>Item 1, graf one.</p>
2287 <p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
2288 back.</p>
2289 </li>
2290 <li><p>Item 2.</p>
2291 </li>
2292 <li><p>Item 3.</p>
2293 </li>
2294 </ol>
2295 <h2 id="Nested">Nested</h2>
2296 <ul>
2297 <li>Tab<ul>
2298 <li>Tab<ul>
2299 <li>Tab</li>
2300 </ul>
2301 </li>
2302 </ul>
2303 </li>
2304 </ul>
2305 <p>Here's another:</p>
2306 <ol>
2307 <li>First</li>
2308 <li>Second:<ul>
2309 <li>Fee</li>
2310 <li>Fie</li>
2311 <li>Foe</li>
2312 </ul>
2313 </li>
2314 <li>Third</li>
2315 </ol>
2316 <p>Same thing but with paragraphs:</p>
2317 <ol>
2318 <li><p>First</p>
2319 </li>
2320 <li><p>Second:</p>
2321 <ul>
2322 <li>Fee</li>
2323 <li>Fie</li>
2324 <li>Foe</li>
2325 </ul>
2326 </li>
2327 <li><p>Third</p>
2328 </li>
2329 </ol>
2330 """
2331 var res = test.md_to_html.write_to_string
2332 assert res == exp
2333 end
2334
2335 fun test_daring_strong_em do
2336 var test = """
2337 ***This is strong and em.***
2338
2339 So is ***this*** word.
2340
2341 ___This is strong and em.___
2342
2343 So is ___this___ word.
2344 """
2345
2346 var exp = """
2347 <p><strong><em>This is strong and em.</em></strong></p>
2348 <p>So is <strong><em>this</em></strong> word.</p>
2349 <p><strong><em>This is strong and em.</em></strong></p>
2350 <p>So is <strong><em>this</em></strong> word.</p>
2351 """
2352 var res = test.md_to_html.write_to_string
2353 assert res == exp
2354 end
2355
2356 fun test_daring_tabs do
2357 var test = """
2358 + this is a list item
2359 indented with tabs
2360
2361 + this is a list item
2362 indented with spaces
2363
2364 Code:
2365
2366 this code block is indented by one tab
2367
2368 And:
2369
2370 this code block is indented by two tabs
2371
2372 And:
2373
2374 + this is an example list item
2375 indented with tabs
2376
2377 + this is an example list item
2378 indented with spaces
2379 """
2380
2381 var exp = """
2382 <ul>
2383 <li><p>this is a list item
2384 indented with tabs</p>
2385 </li>
2386 <li><p>this is a list item
2387 indented with spaces</p>
2388 </li>
2389 </ul>
2390 <p>Code:</p>
2391 <pre><code>this code block is indented by one tab
2392 </code></pre>
2393 <p>And:</p>
2394 <pre><code> this code block is indented by two tabs
2395 </code></pre>
2396 <p>And:</p>
2397 <pre><code>+ this is an example list item
2398 indented with tabs
2399
2400 + this is an example list item
2401 indented with spaces
2402 </code></pre>
2403 """
2404 var res = test.md_to_html.write_to_string
2405 assert res == exp
2406 end
2407
2408 fun test_daring_tidyness do
2409 var test = """
2410 > A list within a blockquote:
2411 >
2412 > * asterisk 1
2413 > * asterisk 2
2414 > * asterisk 3
2415 """
2416
2417 var exp = """
2418 <blockquote>
2419 <p>A list within a blockquote:</p>
2420 <ul>
2421 <li>asterisk 1</li>
2422 <li>asterisk 2</li>
2423 <li>asterisk 3</li>
2424 </ul>
2425 </blockquote>
2426 """
2427 var res = test.md_to_html.write_to_string
2428 assert res == exp
2429 end
2430
2431
2432 end
2433
2434 class TestBlock
2435 super TestSuite
2436
2437 # A dummy location for testing purposes.
2438 var loc = new MDLocation(0, 0, 0, 0)
2439
2440 fun test_has_blocks do
2441 var subject = new MDBlock(loc)
2442 assert not subject.has_blocks
2443 subject.first_block = new MDBlock(loc)
2444 assert subject.has_blocks
2445 end
2446
2447 fun test_count_blocks do
2448 var subject = new MDBlock(loc)
2449 assert subject.count_blocks == 0
2450 subject.first_block = new MDBlock(loc)
2451 assert subject.count_blocks == 1
2452 subject.first_block.next = new MDBlock(loc)
2453 assert subject.count_blocks == 2
2454 end
2455
2456 fun test_has_lines do
2457 var subject = new MDBlock(loc)
2458 assert not subject.has_lines
2459 subject.first_line = new MDLine(loc, "")
2460 assert subject.has_lines
2461 end
2462
2463 fun test_count_lines do
2464 var subject = new MDBlock(loc)
2465 assert subject.count_lines == 0
2466 subject.first_line = new MDLine(loc, "")
2467 assert subject.count_lines == 1
2468 subject.first_line.next = new MDLine(loc, "")
2469 assert subject.count_lines == 2
2470 end
2471
2472 fun test_split do
2473 var line1 = new MDLine(loc, "line1")
2474 var line2 = new MDLine(loc, "line2")
2475 var line3 = new MDLine(loc, "line3")
2476 var subject = new MDBlock(loc)
2477 subject.add_line line1
2478 subject.add_line line2
2479 subject.add_line line3
2480 var block = subject.split(line2)
2481 assert subject.count_blocks == 1
2482 assert subject.count_lines == 1
2483 assert subject.first_line == line3
2484 assert block.count_blocks == 0
2485 assert block.count_lines == 2
2486 assert block.first_line == line1
2487 assert block.last_line == line2
2488 end
2489
2490 fun test_add_line do
2491 var subject = new MDBlock(loc)
2492 assert subject.count_lines == 0
2493 subject.add_line new MDLine(loc, "")
2494 assert subject.count_lines == 1
2495 subject.add_line new MDLine(loc, "")
2496 assert subject.count_lines == 2
2497 end
2498
2499 fun test_remove_line do
2500 var line1 = new MDLine(loc, "line1")
2501 var line2 = new MDLine(loc, "line2")
2502 var line3 = new MDLine(loc, "line3")
2503 var subject = new MDBlock(loc)
2504 subject.add_line line1
2505 subject.add_line line2
2506 subject.add_line line3
2507 subject.remove_line(line2)
2508 assert subject.count_lines == 2
2509 subject.remove_line(line1)
2510 assert subject.count_lines == 1
2511 assert subject.first_line == line3
2512 assert subject.last_line == line3
2513 end
2514
2515 fun test_transform_headline1 do
2516 var subject = new MDBlock(loc)
2517 var kind = new BlockHeadline(subject)
2518 subject.add_line new MDLine(loc, " # Title 1 ")
2519 kind.transform_headline(subject)
2520 assert kind.depth == 1
2521 assert subject.first_line.value == "Title 1"
2522 end
2523
2524 fun test_transform_headline2 do
2525 var subject = new MDBlock(loc)
2526 var kind = new BlockHeadline(subject)
2527 subject.add_line new MDLine(loc, " #####Title 5 ")
2528 kind.transform_headline(subject)
2529 assert kind.depth == 5
2530 assert subject.first_line.value == "Title 5"
2531 end
2532
2533 fun test_remove_quote_prefix do
2534 var subject = new MDBlock(loc)
2535 var kind = new BlockQuote(subject)
2536 subject.add_line new MDLine(loc, " > line 1")
2537 subject.add_line new MDLine(loc, " > line 2")
2538 subject.add_line new MDLine(loc, " > line 3")
2539 kind.remove_block_quote_prefix(subject)
2540 assert subject.first_line.value == "line 1"
2541 assert subject.first_line.next.value == "line 2"
2542 assert subject.first_line.next.next.value == "line 3"
2543 end
2544
2545 fun test_remove_leading_empty_lines_1 do
2546 var block = new MDBlock(loc)
2547 block.add_line new MDLine(loc, "")
2548 block.add_line new MDLine(loc, "")
2549 block.add_line new MDLine(loc, "")
2550 block.add_line new MDLine(loc, "")
2551 block.add_line new MDLine(loc, " text")
2552 block.add_line new MDLine(loc, "")
2553 assert block.remove_leading_empty_lines
2554 assert block.first_line.value == " text"
2555 end
2556
2557 fun test_remove_leading_empty_lines_2 do
2558 var block = new MDBlock(loc)
2559 block.add_line new MDLine(loc, " text")
2560 block.remove_leading_empty_lines
2561 assert block.first_line.value == " text"
2562 end
2563
2564 fun test_remove_trailing_empty_lines_1 do
2565 var block = new MDBlock(loc)
2566 block.add_line new MDLine(loc, "")
2567 block.add_line new MDLine(loc, "text")
2568 block.add_line new MDLine(loc, "")
2569 block.add_line new MDLine(loc, "")
2570 block.add_line new MDLine(loc, "")
2571 block.add_line new MDLine(loc, "")
2572 assert block.remove_trailing_empty_lines
2573 assert block.last_line.value == "text"
2574 end
2575
2576 fun test_remove_trailing_empty_lines_2 do
2577 var block = new MDBlock(loc)
2578 block.add_line new MDLine(loc, "text ")
2579 assert not block.remove_trailing_empty_lines
2580 assert block.last_line.value == "text "
2581 end
2582
2583 fun test_remove_surrounding_empty_lines do
2584 var block = new MDBlock(loc)
2585 block.add_line new MDLine(loc, "")
2586 block.add_line new MDLine(loc, "text")
2587 block.add_line new MDLine(loc, "")
2588 block.add_line new MDLine(loc, "")
2589 block.add_line new MDLine(loc, "")
2590 block.add_line new MDLine(loc, "")
2591 assert block.remove_surrounding_empty_lines
2592 assert block.first_line.value == "text"
2593 assert block.last_line.value == "text"
2594 end
2595 end
2596
2597 class TestLine
2598 super TestSuite
2599
2600 # A dummy location for testing purposes.
2601 var loc = new MDLocation(0, 0, 0, 0)
2602
2603 var subject: MDLine
2604
2605 fun test_is_empty do
2606 subject = new MDLine(loc, "")
2607 assert subject.is_empty
2608 subject = new MDLine(loc, " ")
2609 assert subject.is_empty
2610 subject = new MDLine(loc, "test")
2611 assert not subject.is_empty
2612 subject = new MDLine(loc, " test")
2613 assert not subject.is_empty
2614 end
2615
2616 fun test_leading do
2617 subject = new MDLine(loc, "")
2618 assert subject.leading == 0
2619 subject = new MDLine(loc, " ")
2620 assert subject.leading == 4
2621 subject = new MDLine(loc, "test")
2622 assert subject.leading == 0
2623 subject = new MDLine(loc, " test")
2624 assert subject.leading == 4
2625 end
2626
2627 fun test_trailing do
2628 subject = new MDLine(loc, "")
2629 assert subject.trailing == 0
2630 subject = new MDLine(loc, " ")
2631 assert subject.trailing == 0
2632 subject = new MDLine(loc, "test ")
2633 assert subject.trailing == 3
2634 subject = new MDLine(loc, " test ")
2635 assert subject.trailing == 1
2636 end
2637
2638 fun test_line_type do
2639 var v = new MarkdownProcessor
2640 subject = new MDLine(loc, "")
2641 assert v.line_kind(subject) isa LineEmpty
2642 subject = new MDLine(loc, " ")
2643 assert v.line_kind(subject) isa LineEmpty
2644 subject = new MDLine(loc, "text ")
2645 assert v.line_kind(subject) isa LineOther
2646 subject = new MDLine(loc, " # Title")
2647 assert v.line_kind(subject) isa LineHeadline
2648 subject = new MDLine(loc, " ### Title")
2649 assert v.line_kind(subject) isa LineHeadline
2650 subject = new MDLine(loc, " code")
2651 assert v.line_kind(subject) isa LineCode
2652 subject = new MDLine(loc, " Title ")
2653 subject.next = new MDLine(loc, "== ")
2654 assert v.line_kind(subject) isa LineHeadline1
2655 subject = new MDLine(loc, " Title ")
2656 subject.next = new MDLine(loc, "-- ")
2657 assert v.line_kind(subject) isa LineHeadline2
2658 subject = new MDLine(loc, " * * * ")
2659 assert v.line_kind(subject) isa LineHR
2660 subject = new MDLine(loc, " *** ")
2661 assert v.line_kind(subject) isa LineHR
2662 subject = new MDLine(loc, "- -- ")
2663 assert v.line_kind(subject) isa LineHR
2664 subject = new MDLine(loc, "--------- ")
2665 assert v.line_kind(subject) isa LineHR
2666 subject = new MDLine(loc, " >")
2667 assert v.line_kind(subject) isa LineBlockquote
2668 subject = new MDLine(loc, "<p></p>")
2669 assert v.line_kind(subject) isa LineXML
2670 subject = new MDLine(loc, "<p>")
2671 assert v.line_kind(subject) isa LineOther
2672 subject = new MDLine(loc, " * foo")
2673 assert v.line_kind(subject) isa LineUList
2674 subject = new MDLine(loc, "- foo")
2675 assert v.line_kind(subject) isa LineUList
2676 subject = new MDLine(loc, "+ foo")
2677 assert v.line_kind(subject) isa LineUList
2678 subject = new MDLine(loc, "1. foo")
2679 assert v.line_kind(subject) isa LineOList
2680 subject = new MDLine(loc, " 11111. foo")
2681 assert v.line_kind(subject) isa LineOList
2682 end
2683
2684 fun test_line_type_ext do
2685 var v = new MarkdownProcessor
2686 subject = new MDLine(loc, " ~~~")
2687 assert v.line_kind(subject) isa LineFence
2688 subject = new MDLine(loc, " ```")
2689 assert v.line_kind(subject) isa LineFence
2690 subject = new MDLine(loc, "~~~raw")
2691 assert v.line_kind(subject) isa LineFence
2692 end
2693
2694 fun test_count_chars do
2695 subject = new MDLine(loc, "")
2696 assert subject.count_chars('*') == 0
2697 subject = new MDLine(loc, "* ")
2698 assert subject.count_chars('*') == 1
2699 subject = new MDLine(loc, " * text")
2700 assert subject.count_chars('*') == 0
2701 subject = new MDLine(loc, " * * *")
2702 assert subject.count_chars('*') == 3
2703 subject = new MDLine(loc, "text ** ")
2704 assert subject.count_chars('*') == 0
2705 end
2706
2707 fun test_count_chars_start do
2708 subject = new MDLine(loc, "")
2709 assert subject.count_chars_start('*') == 0
2710 subject = new MDLine(loc, "* ")
2711 assert subject.count_chars_start('*') == 1
2712 subject = new MDLine(loc, " * text")
2713 assert subject.count_chars_start('*') == 1
2714 subject = new MDLine(loc, " * * * text")
2715 assert subject.count_chars_start('*') == 3
2716 subject = new MDLine(loc, "text ** ")
2717 assert subject.count_chars_start('*') == 0
2718 end
2719 end
2720
2721 class TestHTMLDecorator
2722 super TestSuite
2723
2724 fun test_headlines do
2725 var test = """
2726 # **a**
2727 ## a.a
2728 ### a.a.b
2729 ### a.a.b
2730 ## a.b
2731 # [b](test)
2732 ## b.a
2733 ### b.a.c
2734 ## b.b
2735 ## b.c
2736 # c
2737 """
2738 var proc = new MarkdownProcessor
2739 var decorator = proc.emitter.decorator.as(HTMLDecorator)
2740 proc.process(test)
2741 var res = ""
2742 for id, headline in decorator.headlines do
2743 res += "{headline.title}:{id}\n"
2744 end
2745 var exp = """
2746 **a**:a
2747 a.a:a.a
2748 a.a.b:a.a.b
2749 a.a.b:a.a.b_1
2750 a.b:a.b
2751 [b](test):btest
2752 b.a:b.a
2753 b.a.c:b.a.c
2754 b.b:b.b
2755 b.c:b.c
2756 c:c
2757 """
2758 assert res == exp
2759 end
2760 end
2761
2762 class TestTokenLocation
2763 super TestSuite
2764
2765 fun test_token_location1 do
2766 var string = "**Hello** `World`"
2767 var stack = [
2768 "TokenStrongStar at 1,1--1,1",
2769 "TokenStrongStar at 1,8--1,8",
2770 "TokenCodeSingle at 1,11--1,11",
2771 "TokenCodeSingle at 1,17--1,17"]
2772 (new TestTokenProcessor(stack)).process(string)
2773 end
2774
2775 fun test_token_location2 do
2776 var string = "**Hello**\n`World`\n*Bonjour*\n[le monde]()"
2777 var stack = [
2778 "TokenStrongStar at 1,1--1,1",
2779 "TokenStrongStar at 1,8--1,8",
2780 "TokenCodeSingle at 2,1--2,1",
2781 "TokenCodeSingle at 2,7--2,7",
2782 "TokenEmStar at 3,1--3,1",
2783 "TokenEmStar at 3,9--3,9",
2784 "TokenLink at 4,1--4,1"]
2785 (new TestTokenProcessor(stack)).process(string)
2786 end
2787
2788 fun test_token_location3 do
2789 var string = """**Hello**
2790 `World`
2791 *Bonjour*
2792 [le monde]()"""
2793 var stack = [
2794 "TokenStrongStar at 1,1--1,1",
2795 "TokenStrongStar at 1,8--1,8",
2796 "TokenCodeSingle at 2,1--2,1",
2797 "TokenCodeSingle at 2,7--2,7",
2798 "TokenEmStar at 3,1--3,1",
2799 "TokenEmStar at 3,9--3,9",
2800 "TokenLink at 4,1--4,1"]
2801 (new TestTokenProcessor(stack)).process(string)
2802 end
2803 end
2804
2805 class TestTokenProcessor
2806 super MarkdownProcessor
2807
2808 var test_stack: Array[String]
2809
2810 redef fun token_at(input, pos) do
2811 var token = super
2812 if token isa TokenNone then return token
2813 var res = "{token.class_name} at {token.location}"
2814 print res
2815 var exp = test_stack.shift
2816 assert exp == res
2817 return token
2818 end
2819 end
2820
2821 class TestBlockLocation
2822 super TestSuite
2823
2824 var proc = new MarkdownProcessor
2825
2826 fun test_block_location1 do
2827 var stack = [
2828 "BlockHeadline: 1,1--1,8",
2829 "BlockListItem: 2,1--2,6",
2830 "BlockListItem: 3,1--3,5"
2831 ]
2832 var string =
2833 "# Title\n* li1\n* li2"
2834 proc.emitter.decorator = new TestBlockDecorator(stack)
2835 proc.process(string)
2836 end
2837
2838 fun test_block_location2 do
2839 var stack = [
2840 "BlockHeadline: 1,1--1,11",
2841 "BlockFence: 3,1--5,4",
2842 "BlockListItem: 7,1--7,7",
2843 "BlockListItem: 8,1--8,6"]
2844 var string ="""#### Title
2845
2846 ~~~fence
2847 some code
2848 ~~~
2849
2850 1. li1
2851 1. li2"""
2852 proc.emitter.decorator = new TestBlockDecorator(stack)
2853 proc.process(string)
2854 end
2855 end
2856
2857 class TestBlockDecorator
2858 super HTMLDecorator
2859
2860 var stack: Array[String]
2861
2862 redef fun add_headline(v, block) do
2863 super
2864 check_res(block)
2865 end
2866
2867 redef fun add_listitem(v, block) do
2868 super
2869 check_res(block)
2870 end
2871
2872 redef fun add_blockquote(v, block) do
2873 super
2874 check_res(block)
2875 end
2876
2877 redef fun add_code(v, block) do
2878 super
2879 check_res(block)
2880 end
2881
2882 fun check_res(block: Block) do
2883 var res = "{block.class_name}: {block.block.location}"
2884 var exp = stack.shift
2885 assert res == exp
2886 end
2887 end