markdown: fix token location in multilines input
[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_span_code1 do
818 var test = "Use the `printf()` function."
819 var exp = "<p>Use the <code>printf()</code> function.</p>\n"
820 var res = test.md_to_html.write_to_string
821 assert res == exp
822 end
823
824 fun test_process_span_code2 do
825 var test = "``There is a literal backtick (`) here.``"
826 var exp = "<p><code>There is a literal backtick (`) here.</code></p>\n"
827 var res = test.md_to_html.write_to_string
828 assert res == exp
829 end
830
831 fun test_process_span_code3 do
832 var test = """
833 A single backtick in a code span: `` ` ``
834
835 A backtick-delimited string in a code span: `` `foo` ``
836 """
837 var exp = """
838 <p>A single backtick in a code span: <code>`</code></p>
839 <p>A backtick-delimited string in a code span: <code>`foo`</code></p>
840 """
841 var res = test.md_to_html.write_to_string
842 assert res == exp
843 end
844
845 fun test_process_span_code4 do
846 var test = "Please don't use any `<blink>` tags."
847 var exp = "<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>\n"
848 var res = test.md_to_html.write_to_string
849 assert res == exp
850 end
851
852 fun test_process_span_code5 do
853 var test = "`&#8212;` is the decimal-encoded equivalent of `&mdash;`."
854 var exp = "<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>\n"
855 var res = test.md_to_html.write_to_string
856 assert res == exp
857 end
858
859 fun test_process_escape1 do
860 var test = "\\*this text is surrounded by literal asterisks\\*"
861 var exp = "<p>*this text is surrounded by literal asterisks*</p>\n"
862 var res = test.md_to_html.write_to_string
863 assert res == exp
864 end
865
866 fun test_process_escape2 do
867 var test = "1986\\. What a great season."
868 var exp = "<p>1986. What a great season.</p>\n"
869 var res = test.md_to_html.write_to_string
870 assert res == exp
871 end
872
873 fun test_process_escape3 do
874 var test = "Ben & Lux"
875 var exp = "<p>Ben &amp; Lux</p>\n"
876 var res = test.md_to_html.write_to_string
877 assert res == exp
878 end
879
880 fun test_process_link1 do
881 var test = """
882 This is [an example](http://example.com/ "Title") inline link.
883
884 [This link](http://example.net/) has no title attribute.
885 """
886 var exp = """<p>This is <a href="http://example.com/" title="Title">an example</a> inline link.</p>
887 <p><a href="http://example.net/">This link</a> has no title attribute.</p>
888 """
889 var res = test.md_to_html.write_to_string
890 assert res == exp
891 end
892
893 fun test_process_link2 do
894 var test = "See my [About](/about/) page for details."
895 var exp = "<p>See my <a href=\"/about/\">About</a> page for details.</p>\n"
896 var res = test.md_to_html.write_to_string
897 assert res == exp
898 end
899
900 fun test_process_link3 do
901 var test = """
902 This is [an example][id] reference-style link.
903
904 This is [an example] [id] reference-style link.
905
906 Some lorem ipsum
907
908 [id]: http://example.com/ "Optional Title Here"
909
910 Some other lipsum
911 """
912 var exp = """
913 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
914 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
915 <p>Some lorem ipsum</p>
916 <p>Some other lipsum</p>
917 """
918 var res = test.md_to_html.write_to_string
919 assert res == exp
920 end
921
922 fun test_process_link4 do
923 var test = """
924 This is multiple examples: [foo][1], [bar][2], [baz][3].
925
926 [1]: http://example.com/ "Optional Title Here"
927 [2]: http://example.com/ 'Optional Title Here'
928 [3]: http://example.com/ (Optional Title Here)
929 """
930 var exp = """
931 <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>
932 """
933 var res = test.md_to_html.write_to_string
934 assert res == exp
935 end
936
937 fun test_process_link5 do
938 var test = """
939 This is multiple examples: [foo][a], [bar][A], [a].
940
941 [a]: http://example.com/ "Optional Title Here"
942 """
943 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>
944 """
945 var res = test.md_to_html.write_to_string
946 assert res == exp
947 end
948
949 fun test_process_link6 do
950 var test = """
951 I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
952
953 [Google]: http://google.com/ "Google"
954 [Yahoo]: http://search.yahoo.com/ "Yahoo Search"
955 [MSN]: http://search.msn.com/ "MSN Search"
956 """
957 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>
958 """
959 var res = test.md_to_html.write_to_string
960 assert res == exp
961 end
962
963 fun test_process_link7 do
964 var test = """
965 Visit [Daring Fireball][] for more information.
966
967 [Daring Fireball]: http://daringfireball.net/
968 """
969 var exp = """<p>Visit <a href="http://daringfireball.net/">Daring Fireball</a> for more information.</p>
970 """
971 var res = test.md_to_html.write_to_string
972 assert res == exp
973 end
974
975 fun test_process_link8 do
976 var test = """
977 This one has a [line
978 break].
979
980 This one has a [line
981 break] with a line-ending space.
982
983 [line break]: /foo
984 """
985 var exp = """
986 <p>This one has a <a href="/foo">line
987 break</a>.</p>
988 <p>This one has a <a href="/foo">line
989 break</a> with a line-ending space.</p>
990 """
991 var res = test.md_to_html.write_to_string
992 assert res == exp
993 end
994
995 # FIXME unignore test once escape strings fixed
996 # fun test_process_link9 do
997 # var test = """
998 # Foo [bar][].
999 #
1000 # Foo [bar](/url/ "Title with \"quotes\" inside").
1001 #
1002 #
1003 # [bar]: /url/ "Title with \"quotes\" inside"
1004 # """
1005 # var exp = """
1006 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
1007 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
1008 # """
1009 # var res = test.md_to_html.write_to_string
1010 # assert res == exp
1011 # end
1012
1013 fun test_process_img1 do
1014 var test = """
1015 ![Alt text](/path/to/img.jpg)
1016
1017 ![Alt text](/path/to/img.jpg "Optional title")
1018 """
1019 var exp = """<p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1020 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1021 """
1022 var res = test.md_to_html.write_to_string
1023 assert res == exp
1024 end
1025
1026 fun test_process_img2 do
1027 var test = """
1028 ![Alt text][id]
1029
1030 [id]: url/to/image "Optional title attribute"
1031 """
1032 var exp = """<p><img src="url/to/image" alt="Alt text" title="Optional title attribute"/></p>
1033 """
1034 var res = test.md_to_html.write_to_string
1035 assert res == exp
1036 end
1037
1038 fun test_process_strike do
1039 var proc = new MarkdownProcessor
1040 proc.ext_mode = false
1041 var test = "This is how you ~~strike text~~"
1042 var exp = "<p>This is how you ~~strike text~~</p>\n"
1043 var res = proc.process(test).write_to_string
1044 assert exp == res
1045 end
1046
1047 fun test_process_strike_ext do
1048 var test = "This is how you ~~strike text~~"
1049 var exp = "<p>This is how you <del>strike text</del></p>\n"
1050 var res = test.md_to_html.write_to_string
1051 assert exp == res
1052 end
1053
1054 fun test_escape_bad_html do
1055 var test = "-1 if < , +1 if > and 0 otherwise"
1056 var exp = "<p>-1 if &lt; , +1 if > and 0 otherwise</p>\n"
1057 var res = test.md_to_html.write_to_string
1058 assert exp == res
1059 end
1060
1061 fun test_daring_encoding do
1062 var test = """
1063 AT&T has an ampersand in their name.
1064
1065 AT&amp;T is another way to write it.
1066
1067 This & that.
1068
1069 4 < 5.
1070
1071 6 > 5.
1072
1073 Here's a [link] [1] with an ampersand in the URL.
1074
1075 Here's a link with an amersand in the link text: [AT&T] [2].
1076
1077 Here's an inline [link](/script?foo=1&bar=2).
1078
1079 Here's an inline [link](</script?foo=1&bar=2>).
1080
1081
1082 [1]: http://example.com/?foo=1&bar=2
1083 [2]: http://att.com/ "AT&T"
1084 """
1085
1086 var exp = """
1087 <p>AT&amp;T has an ampersand in their name.</p>
1088 <p>AT&amp;T is another way to write it.</p>
1089 <p>This &amp; that.</p>
1090 <p>4 &lt; 5.</p>
1091 <p>6 > 5.</p>
1092 <p>Here's a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
1093 <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>
1094 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1095 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1096 """
1097 var res = test.md_to_html.write_to_string
1098 assert res == exp
1099
1100 end
1101
1102 fun test_daring_autolinks do
1103 var test = """
1104 Link: <http://example.com/>.
1105
1106 With an ampersand: <http://example.com/?foo=1&bar=2>
1107
1108 * In a list?
1109 * <http://example.com/>
1110 * It should.
1111
1112 > Blockquoted: <http://example.com/>
1113
1114 Auto-links should not occur here: `<http://example.com/>`
1115
1116 or here: <http://example.com/>
1117 """
1118
1119 var exp = """
1120 <p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
1121 <p>With an ampersand: <a href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</a></p>
1122 <ul>
1123 <li>In a list?</li>
1124 <li><a href="http://example.com/">http://example.com/</a></li>
1125 <li>It should.</li>
1126 </ul>
1127 <blockquote>
1128 <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
1129 </blockquote>
1130 <p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
1131 <pre><code>or here: &lt;http://example.com/&gt;
1132 </code></pre>
1133 """
1134 var res = test.md_to_html.write_to_string
1135 assert res == exp
1136 end
1137
1138 fun test_daring_escape do
1139 var test = """
1140 These should all get escaped:
1141
1142 Backslash: \\
1143
1144 Backtick: \`
1145
1146 Asterisk: \*
1147
1148 Underscore: \_
1149
1150 Left brace: \{
1151
1152 Right brace: \}
1153
1154 Left bracket: \[
1155
1156 Right bracket: \]
1157
1158 Left paren: \(
1159
1160 Right paren: \)
1161
1162 Greater-than: \>
1163
1164 Hash: \#
1165
1166 Period: \.
1167
1168 Bang: \!
1169
1170 Plus: \+
1171
1172 Minus: \-
1173
1174
1175 These should not, because they occur within a code block:
1176
1177 Backslash: \\
1178
1179 Backtick: \`
1180
1181 Asterisk: \*
1182
1183 Underscore: \_
1184
1185 Left brace: \{
1186
1187 Right brace: \}
1188
1189 Left bracket: \[
1190
1191 Right bracket: \]
1192
1193 Left paren: \(
1194
1195 Right paren: \)
1196
1197 Greater-than: \>
1198
1199 Hash: \#
1200
1201 Period: \.
1202
1203 Bang: \!
1204
1205 Plus: \+
1206
1207 Minus: \-
1208
1209 Nor should these, which occur in code spans:
1210
1211 Backslash: `\\`
1212
1213 Backtick: `` \` ``
1214
1215 Asterisk: `\*`
1216
1217 Underscore: `\_`
1218
1219 Left brace: `\{`
1220
1221 Right brace: `\}`
1222
1223 Left bracket: `\[`
1224
1225 Right bracket: `\]`
1226
1227 Left paren: `\(`
1228
1229 Right paren: `\)`
1230
1231 Greater-than: `\>`
1232
1233 Hash: `\#`
1234
1235 Period: `\.`
1236
1237 Bang: `\!`
1238
1239 Plus: `\+`
1240
1241 Minus: `\-`
1242
1243 These should get escaped, even though they're matching pairs for
1244 other Markdown constructs:
1245
1246 \\\*asterisks\\\*
1247
1248 \\\_underscores\\\_
1249
1250 \\\`backticks\\\`
1251
1252 This is a code span with a literal backslash-backtick sequence: `` \` ``
1253
1254 This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
1255
1256 This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.
1257 """
1258 var exp = """
1259 <p>These should all get escaped:</p>
1260 <p>Backslash: \\</p>
1261 <p>Backtick: \`</p>
1262 <p>Asterisk: \*</p>
1263 <p>Underscore: \_</p>
1264 <p>Left brace: \{</p>
1265 <p>Right brace: \}</p>
1266 <p>Left bracket: \[</p>
1267 <p>Right bracket: \]</p>
1268 <p>Left paren: \(</p>
1269 <p>Right paren: \)</p>
1270 <p>Greater-than: \></p>
1271 <p>Hash: \#</p>
1272 <p>Period: \.</p>
1273 <p>Bang: \!</p>
1274 <p>Plus: \+</p>
1275 <p>Minus: \-</p>
1276 <p>These should not, because they occur within a code block:</p>
1277 <pre><code>Backslash: \\
1278
1279 Backtick: \`
1280
1281 Asterisk: \*
1282
1283 Underscore: \_
1284
1285 Left brace: \{
1286
1287 Right brace: \}
1288
1289 Left bracket: \[
1290
1291 Right bracket: \]
1292
1293 Left paren: \(
1294
1295 Right paren: \)
1296
1297 Greater-than: \&gt;
1298
1299 Hash: \#
1300
1301 Period: \.
1302
1303 Bang: \!
1304
1305 Plus: \+
1306
1307 Minus: \-
1308 </code></pre>
1309 <p>Nor should these, which occur in code spans:</p>
1310 <p>Backslash: <code>\\</code></p>
1311 <p>Backtick: <code>\`</code></p>
1312 <p>Asterisk: <code>\*</code></p>
1313 <p>Underscore: <code>\_</code></p>
1314 <p>Left brace: <code>\{</code></p>
1315 <p>Right brace: <code>\}</code></p>
1316 <p>Left bracket: <code>\[</code></p>
1317 <p>Right bracket: <code>\]</code></p>
1318 <p>Left paren: <code>\(</code></p>
1319 <p>Right paren: <code>\)</code></p>
1320 <p>Greater-than: <code>\&gt;</code></p>
1321 <p>Hash: <code>\#</code></p>
1322 <p>Period: <code>\.</code></p>
1323 <p>Bang: <code>\!</code></p>
1324 <p>Plus: <code>\+</code></p>
1325 <p>Minus: <code>\-</code></p>
1326 <p>These should get escaped, even though they're matching pairs for
1327 other Markdown constructs:</p>
1328 <p>*asterisks*</p>
1329 <p>_underscores_</p>
1330 <p>`backticks`</p>
1331 <p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
1332 <p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
1333 <p>This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.</p>
1334 """
1335
1336 var res = test.md_to_html.write_to_string
1337 assert res == exp
1338 end
1339
1340 fun test_daring_blockquotes do
1341 var test = """
1342 > Example:
1343 >
1344 > sub status {
1345 > print "working";
1346 > }
1347 >
1348 > Or:
1349 >
1350 > sub status {
1351 > return "working";
1352 > }
1353 """
1354
1355 var exp = """
1356 <blockquote>
1357 <p>Example:</p>
1358 <pre><code>sub status {
1359 print "working";
1360 }
1361 </code></pre>
1362 <p>Or:</p>
1363 <pre><code>sub status {
1364 return "working";
1365 }
1366 </code></pre>
1367 </blockquote>
1368 """
1369 var res = test.md_to_html.write_to_string
1370 assert res == exp
1371 end
1372
1373 fun test_daring_code_blocks do
1374 var test = """
1375 code block on the first line
1376
1377 Regular text.
1378
1379 code block indented by spaces
1380
1381 Regular text.
1382
1383 the lines in this block
1384 all contain trailing spaces
1385
1386 Regular Text.
1387
1388 code block on the last line
1389 """
1390
1391 var exp = """
1392 <pre><code>code block on the first line
1393 </code></pre>
1394 <p>Regular text.</p>
1395 <pre><code>code block indented by spaces
1396 </code></pre>
1397 <p>Regular text.</p>
1398 <pre><code>the lines in this block
1399 all contain trailing spaces
1400 </code></pre>
1401 <p>Regular Text.</p>
1402 <pre><code>code block on the last line
1403 </code></pre>
1404 """
1405 var res = test.md_to_html.write_to_string
1406 assert res == exp
1407 end
1408
1409 fun test_daring_code_spans do
1410 var test = """
1411 `<test a="` content of attribute `">`
1412
1413 Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
1414
1415 Here's how you put `` `backticks` `` in a code span.
1416 """
1417
1418 var exp = """
1419 <p><code>&lt;test a="</code> content of attribute <code>"&gt;</code></p>
1420 <p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
1421 <p>Here's how you put <code>`backticks`</code> in a code span.</p>
1422 """
1423 var res = test.md_to_html.write_to_string
1424 assert res == exp
1425 end
1426
1427 fun test_daring_pars do
1428 var proc = new MarkdownProcessor
1429 proc.ext_mode = false
1430
1431 var test = """
1432 In Markdown 1.0.0 and earlier. Version
1433 8. This line turns into a list item.
1434 Because a hard-wrapped line in the
1435 middle of a paragraph looked like a
1436 list item.
1437
1438 Here's one with a bullet.
1439 * criminey.
1440 """
1441
1442 var exp = """
1443 <p>In Markdown 1.0.0 and earlier. Version
1444 8. This line turns into a list item.
1445 Because a hard-wrapped line in the
1446 middle of a paragraph looked like a
1447 list item.</p>
1448 <p>Here's one with a bullet.
1449 * criminey.</p>
1450 """
1451 var res = proc.process(test).write_to_string
1452 assert res == exp
1453 end
1454
1455 fun test_daring_rules do
1456 var test = """
1457 Dashes:
1458
1459 ---
1460
1461 ---
1462
1463 ---
1464
1465 ---
1466
1467 ---
1468
1469 - - -
1470
1471 - - -
1472
1473 - - -
1474
1475 - - -
1476
1477 - - -
1478
1479
1480 Asterisks:
1481
1482 ***
1483
1484 ***
1485
1486 ***
1487
1488 ***
1489
1490 ***
1491
1492 * * *
1493
1494 * * *
1495
1496 * * *
1497
1498 * * *
1499
1500 * * *
1501
1502
1503 Underscores:
1504
1505 ___
1506
1507 ___
1508
1509 ___
1510
1511 ___
1512
1513 ___
1514
1515 _ _ _
1516
1517 _ _ _
1518
1519 _ _ _
1520
1521 _ _ _
1522
1523 _ _ _
1524 """
1525
1526 var exp = """
1527 <p>Dashes:</p>
1528 <hr/>
1529 <hr/>
1530 <hr/>
1531 <hr/>
1532 <pre><code>---
1533 </code></pre>
1534 <hr/>
1535 <hr/>
1536 <hr/>
1537 <hr/>
1538 <pre><code>- - -
1539 </code></pre>
1540 <p>Asterisks:</p>
1541 <hr/>
1542 <hr/>
1543 <hr/>
1544 <hr/>
1545 <pre><code>***
1546 </code></pre>
1547 <hr/>
1548 <hr/>
1549 <hr/>
1550 <hr/>
1551 <pre><code>* * *
1552 </code></pre>
1553 <p>Underscores:</p>
1554 <hr/>
1555 <hr/>
1556 <hr/>
1557 <hr/>
1558 <pre><code>___
1559 </code></pre>
1560 <hr/>
1561 <hr/>
1562 <hr/>
1563 <hr/>
1564 <pre><code>_ _ _
1565 </code></pre>
1566 """
1567 var res = test.md_to_html.write_to_string
1568 assert res == exp
1569 end
1570
1571 fun test_daring_images do
1572 var test = """
1573 ![Alt text](/path/to/img.jpg)
1574
1575 ![Alt text](/path/to/img.jpg "Optional title")
1576
1577 Inline within a paragraph: [alt text](/url/).
1578
1579 ![alt text](/url/ "title preceded by two spaces")
1580
1581 ![alt text](/url/ "title has spaces afterward" )
1582
1583 ![alt text](</url/>)
1584
1585 ![alt text](</url/> "with a title").
1586
1587 ![Empty]()
1588
1589 ![this is a stupid URL](http://example.com/(parens).jpg)
1590
1591
1592 ![alt text][foo]
1593
1594 [foo]: /url/
1595
1596 ![alt text][bar]
1597
1598 [bar]: /url/ "Title here"
1599 """
1600
1601 var exp = """
1602 <p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1603 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1604 <p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
1605 <p><img src="/url/" alt="alt text" title="title preceded by two spaces"/></p>
1606 <p><img src="/url/" alt="alt text" title="title has spaces afterward"/></p>
1607 <p><img src="/url/" alt="alt text"/></p>
1608 <p><img src="/url/" alt="alt text" title="with a title"/>.</p>
1609 <p><img src="" alt="Empty"/></p>
1610 <p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL"/></p>
1611 <p><img src="/url/" alt="alt text"/></p>
1612 <p><img src="/url/" alt="alt text" title="Title here"/></p>
1613 """
1614 var res = test.md_to_html.write_to_string
1615 assert res == exp
1616 end
1617
1618 fun test_daring_inline_html1 do
1619 var test = """
1620 Here's a simple block:
1621
1622 <div>
1623 foo
1624 </div>
1625
1626 This should be a code block, though:
1627
1628 <div>
1629 foo
1630 </div>
1631
1632 As should this:
1633
1634 <div>foo</div>
1635
1636 Now, nested:
1637
1638 <div>
1639 <div>
1640 <div>
1641 foo
1642 </div>
1643 </div>
1644 </div>
1645
1646 This should just be an HTML comment:
1647
1648 <!-- Comment -->
1649
1650 Multiline:
1651
1652 <!--
1653 Blah
1654 Blah
1655 -->
1656
1657 Code block:
1658
1659 <!-- Comment -->
1660
1661 Just plain comment, with trailing spaces on the line:
1662
1663 <!-- foo -->
1664
1665 Code:
1666
1667 <hr />
1668
1669 Hr's:
1670
1671 <hr>
1672
1673 <hr/>
1674
1675 <hr />
1676
1677 <hr>
1678
1679 <hr/>
1680
1681 <hr />
1682
1683 <hr class="foo" id="bar" />
1684
1685 <hr class="foo" id="bar"/>
1686
1687 <hr class="foo" id="bar" >
1688 """
1689
1690 var exp = """
1691 <p>Here's a simple block:</p>
1692 <div>
1693 foo
1694 </div>
1695 <p>This should be a code block, though:</p>
1696 <pre><code>&lt;div&gt;
1697 foo
1698 &lt;/div&gt;
1699 </code></pre>
1700 <p>As should this:</p>
1701 <pre><code>&lt;div&gt;foo&lt;/div&gt;
1702 </code></pre>
1703 <p>Now, nested:</p>
1704 <div>
1705 <div>
1706 <div>
1707 foo
1708 </div>
1709 </div>
1710 </div>
1711 <p>This should just be an HTML comment:</p>
1712 <!-- Comment -->
1713 <p>Multiline:</p>
1714 <!--
1715 Blah
1716 Blah
1717 -->
1718 <p>Code block:</p>
1719 <pre><code>&lt;!-- Comment --&gt;
1720 </code></pre>
1721 <p>Just plain comment, with trailing spaces on the line:</p>
1722 <!-- foo -->
1723 <p>Code:</p>
1724 <pre><code>&lt;hr /&gt;
1725 </code></pre>
1726 <p>Hr's:</p>
1727 <hr>
1728 <hr/>
1729 <hr />
1730 <hr>
1731 <hr/>
1732 <hr />
1733 <hr class="foo" id="bar" />
1734 <hr class="foo" id="bar"/>
1735 <hr class="foo" id="bar" >
1736 """
1737 var res = test.md_to_html.write_to_string
1738 assert res == exp
1739 end
1740
1741 fun test_daring_inline_html2 do
1742 var test = """
1743 Simple block on one line:
1744
1745 <div>foo</div>
1746
1747 And nested without indentation:
1748
1749 <div>
1750 <div>
1751 <div>
1752 foo
1753 </div>
1754 <div style=">"/>
1755 </div>
1756 <div>bar</div>
1757 </div>
1758
1759 And with attributes:
1760
1761 <div>
1762 <div id="foo">
1763 </div>
1764 </div>
1765
1766 This was broken in 1.0.2b7:
1767
1768 <div class="inlinepage">
1769 <div class="toggleableend">
1770 foo
1771 </div>
1772 </div>
1773 """
1774
1775 var exp = """
1776 <p>Simple block on one line:</p>
1777 <div>foo</div>
1778 <p>And nested without indentation:</p>
1779 <div>
1780 <div>
1781 <div>
1782 foo
1783 </div>
1784 <div style=">"/>
1785 </div>
1786 <div>bar</div>
1787 </div>
1788 <p>And with attributes:</p>
1789 <div>
1790 <div id="foo">
1791 </div>
1792 </div>
1793 <p>This was broken in 1.0.2b7:</p>
1794 <div class="inlinepage">
1795 <div class="toggleableend">
1796 foo
1797 </div>
1798 </div>
1799 """
1800 var res = test.md_to_html.write_to_string
1801 assert res == exp
1802 end
1803
1804 fun test_daring_inline_html3 do
1805 var test = """
1806 Paragraph one.
1807
1808 <!-- This is a simple comment -->
1809
1810 <!--
1811 This is another comment.
1812 -->
1813
1814 Paragraph two.
1815
1816 <!-- one comment block -- -- with two comments -->
1817
1818 The end.
1819 """
1820
1821 var exp = """
1822 <p>Paragraph one.</p>
1823 <!-- This is a simple comment -->
1824 <!--
1825 This is another comment.
1826 -->
1827 <p>Paragraph two.</p>
1828 <!-- one comment block -- -- with two comments -->
1829 <p>The end.</p>
1830 """
1831 var res = test.md_to_html.write_to_string
1832 assert res == exp
1833 end
1834
1835 fun test_daring_links1 do
1836 var test = """
1837 Just a [URL](/url/).
1838
1839 [URL and title](/url/ "title").
1840
1841 [URL and title](/url/ "title preceded by two spaces").
1842
1843 [URL and title](/url/ "title preceded by a tab").
1844
1845 [URL and title](/url/ "title has spaces afterward" ).
1846
1847 [URL wrapped in angle brackets](</url/>).
1848
1849 [URL w/ angle brackets + title](</url/> "Here's the title").
1850
1851 [Empty]().
1852
1853 [With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
1854
1855 (With outer parens and [parens in url](/foo(bar)))
1856
1857
1858 [With parens in the URL](/foo(bar) "and a title")
1859
1860 (With outer parens and [parens in url](/foo(bar) "and a title"))
1861 """
1862
1863 var exp = """
1864 <p>Just a <a href="/url/">URL</a>.</p>
1865 <p><a href="/url/" title="title">URL and title</a>.</p>
1866 <p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
1867 <p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
1868 <p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
1869 <p><a href="/url/">URL wrapped in angle brackets</a>.</p>
1870 <p><a href="/url/" title="Here&apos;s the title">URL w/ angle brackets + title</a>.</p>
1871 <p><a href="">Empty</a>.</p>
1872 <p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
1873 <p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
1874 <p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
1875 <p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>
1876 """
1877 var res = test.md_to_html.write_to_string
1878 assert res == exp
1879 end
1880
1881 fun test_daring_links2 do
1882 var test = """
1883 Foo [bar] [1].
1884
1885 Foo [bar][1].
1886
1887 Foo [bar]
1888 [1].
1889
1890 [1]: /url/ "Title"
1891
1892
1893 With [embedded [brackets]] [b].
1894
1895
1896 Indented [once][].
1897
1898 Indented [twice][].
1899
1900 Indented [thrice][].
1901
1902 Indented [four][] times.
1903
1904 [once]: /url
1905
1906 [twice]: /url
1907
1908 [thrice]: /url
1909
1910 [four]: /url
1911
1912
1913 [b]: /url/
1914
1915 * * *
1916
1917 [this] [this] should work
1918
1919 So should [this][this].
1920
1921 And [this] [].
1922
1923 And [this][].
1924
1925 And [this].
1926
1927 But not [that] [].
1928
1929 Nor [that][].
1930
1931 Nor [that].
1932
1933 [Something in brackets like [this][] should work]
1934
1935 [Same with [this].]
1936
1937 In this case, [this](/somethingelse/) points to something else.
1938
1939 Backslashing should suppress \\\[this] and [this\\\].
1940
1941 [this]: foo
1942
1943
1944 * * *
1945
1946 Here's one where the [link
1947 breaks] across lines.
1948
1949 Here's another where the [link
1950 breaks] across lines, but with a line-ending space.
1951
1952
1953 [link breaks]: /url/
1954 """
1955
1956 var exp = """
1957 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1958 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1959 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1960 <p>With <a href="/url/">embedded [brackets]</a>.</p>
1961 <p>Indented <a href="/url">once</a>.</p>
1962 <p>Indented <a href="/url">twice</a>.</p>
1963 <p>Indented <a href="/url">thrice</a>.</p>
1964 <p>Indented [four][] times.</p>
1965 <pre><code>[four]: /url
1966 </code></pre>
1967 <hr/>
1968 <p><a href="foo">this</a> should work</p>
1969 <p>So should <a href="foo">this</a>.</p>
1970 <p>And <a href="foo">this</a>.</p>
1971 <p>And <a href="foo">this</a>.</p>
1972 <p>And <a href="foo">this</a>.</p>
1973 <p>But not [that] [].</p>
1974 <p>Nor [that][].</p>
1975 <p>Nor [that].</p>
1976 <p>[Something in brackets like <a href="foo">this</a> should work]</p>
1977 <p>[Same with <a href="foo">this</a>.]</p>
1978 <p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
1979 <p>Backslashing should suppress [this] and [this].</p>
1980 <hr/>
1981 <p>Here's one where the <a href="/url/">link
1982 breaks</a> across lines.</p>
1983 <p>Here's another where the <a href="/url/">link
1984 breaks</a> across lines, but with a line-ending space.</p>
1985 """
1986 var res = test.md_to_html.write_to_string
1987 assert res == exp
1988 end
1989
1990 fun test_daring_links3 do
1991 var test = """
1992 This is the [simple case].
1993
1994 [simple case]: /simple
1995
1996
1997
1998 This one has a [line
1999 break].
2000
2001 This one has a [line
2002 break] with a line-ending space.
2003
2004 [line break]: /foo
2005
2006
2007 [this] [that] and the [other]
2008
2009 [this]: /this
2010 [that]: /that
2011 [other]: /other
2012 """
2013
2014 var exp = """
2015 <p>This is the <a href="/simple">simple case</a>.</p>
2016 <p>This one has a <a href="/foo">line
2017 break</a>.</p>
2018 <p>This one has a <a href="/foo">line
2019 break</a> with a line-ending space.</p>
2020 <p><a href="/that">this</a> and the <a href="/other">other</a></p>
2021 """
2022 var res = test.md_to_html.write_to_string
2023 assert res == exp
2024 end
2025
2026 fun test_daring_nested do
2027 var test = """
2028 > foo
2029 >
2030 > > bar
2031 >
2032 > foo
2033 """
2034
2035 var exp = """
2036 <blockquote>
2037 <p>foo</p>
2038 <blockquote>
2039 <p>bar</p>
2040 </blockquote>
2041 <p>foo</p>
2042 </blockquote>
2043 """
2044 var res = test.md_to_html.write_to_string
2045 assert res == exp
2046 end
2047
2048 fun test_daring_list do
2049 var test = """
2050 ## Unordered
2051
2052 Asterisks tight:
2053
2054 * asterisk 1
2055 * asterisk 2
2056 * asterisk 3
2057
2058
2059 Asterisks loose:
2060
2061 * asterisk 1
2062
2063 * asterisk 2
2064
2065 * asterisk 3
2066
2067 * * *
2068
2069 Pluses tight:
2070
2071 + Plus 1
2072 + Plus 2
2073 + Plus 3
2074
2075
2076 Pluses loose:
2077
2078 + Plus 1
2079
2080 + Plus 2
2081
2082 + Plus 3
2083
2084 * * *
2085
2086
2087 Minuses tight:
2088
2089 - Minus 1
2090 - Minus 2
2091 - Minus 3
2092
2093
2094 Minuses loose:
2095
2096 - Minus 1
2097
2098 - Minus 2
2099
2100 - Minus 3
2101
2102
2103 ## Ordered
2104
2105 Tight:
2106
2107 1. First
2108 2. Second
2109 3. Third
2110
2111 and:
2112
2113 1. One
2114 2. Two
2115 3. Three
2116
2117
2118 Loose using tabs:
2119
2120 1. First
2121
2122 2. Second
2123
2124 3. Third
2125
2126 and using spaces:
2127
2128 1. One
2129
2130 2. Two
2131
2132 3. Three
2133
2134 Multiple paragraphs:
2135
2136 1. Item 1, graf one.
2137
2138 Item 2. graf two. The quick brown fox jumped over the lazy dog's
2139 back.
2140
2141 2. Item 2.
2142
2143 3. Item 3.
2144
2145
2146
2147 ## Nested
2148
2149 * Tab
2150 * Tab
2151 * Tab
2152
2153 Here's another:
2154
2155 1. First
2156 2. Second:
2157 * Fee
2158 * Fie
2159 * Foe
2160 3. Third
2161
2162 Same thing but with paragraphs:
2163
2164 1. First
2165
2166 2. Second:
2167 * Fee
2168 * Fie
2169 * Foe
2170
2171 3. Third
2172 """
2173
2174 var exp = """
2175 <h2 id="Unordered">Unordered</h2>
2176 <p>Asterisks tight:</p>
2177 <ul>
2178 <li>asterisk 1</li>
2179 <li>asterisk 2</li>
2180 <li>asterisk 3</li>
2181 </ul>
2182 <p>Asterisks loose:</p>
2183 <ul>
2184 <li><p>asterisk 1</p>
2185 </li>
2186 <li><p>asterisk 2</p>
2187 </li>
2188 <li><p>asterisk 3</p>
2189 </li>
2190 </ul>
2191 <hr/>
2192 <p>Pluses tight:</p>
2193 <ul>
2194 <li>Plus 1</li>
2195 <li>Plus 2</li>
2196 <li>Plus 3</li>
2197 </ul>
2198 <p>Pluses loose:</p>
2199 <ul>
2200 <li><p>Plus 1</p>
2201 </li>
2202 <li><p>Plus 2</p>
2203 </li>
2204 <li><p>Plus 3</p>
2205 </li>
2206 </ul>
2207 <hr/>
2208 <p>Minuses tight:</p>
2209 <ul>
2210 <li>Minus 1</li>
2211 <li>Minus 2</li>
2212 <li>Minus 3</li>
2213 </ul>
2214 <p>Minuses loose:</p>
2215 <ul>
2216 <li><p>Minus 1</p>
2217 </li>
2218 <li><p>Minus 2</p>
2219 </li>
2220 <li><p>Minus 3</p>
2221 </li>
2222 </ul>
2223 <h2 id="Ordered">Ordered</h2>
2224 <p>Tight:</p>
2225 <ol>
2226 <li>First</li>
2227 <li>Second</li>
2228 <li>Third</li>
2229 </ol>
2230 <p>and:</p>
2231 <ol>
2232 <li>One</li>
2233 <li>Two</li>
2234 <li>Three</li>
2235 </ol>
2236 <p>Loose using tabs:</p>
2237 <ol>
2238 <li><p>First</p>
2239 </li>
2240 <li><p>Second</p>
2241 </li>
2242 <li><p>Third</p>
2243 </li>
2244 </ol>
2245 <p>and using spaces:</p>
2246 <ol>
2247 <li><p>One</p>
2248 </li>
2249 <li><p>Two</p>
2250 </li>
2251 <li><p>Three</p>
2252 </li>
2253 </ol>
2254 <p>Multiple paragraphs:</p>
2255 <ol>
2256 <li><p>Item 1, graf one.</p>
2257 <p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
2258 back.</p>
2259 </li>
2260 <li><p>Item 2.</p>
2261 </li>
2262 <li><p>Item 3.</p>
2263 </li>
2264 </ol>
2265 <h2 id="Nested">Nested</h2>
2266 <ul>
2267 <li>Tab<ul>
2268 <li>Tab<ul>
2269 <li>Tab</li>
2270 </ul>
2271 </li>
2272 </ul>
2273 </li>
2274 </ul>
2275 <p>Here's another:</p>
2276 <ol>
2277 <li>First</li>
2278 <li>Second:<ul>
2279 <li>Fee</li>
2280 <li>Fie</li>
2281 <li>Foe</li>
2282 </ul>
2283 </li>
2284 <li>Third</li>
2285 </ol>
2286 <p>Same thing but with paragraphs:</p>
2287 <ol>
2288 <li><p>First</p>
2289 </li>
2290 <li><p>Second:</p>
2291 <ul>
2292 <li>Fee</li>
2293 <li>Fie</li>
2294 <li>Foe</li>
2295 </ul>
2296 </li>
2297 <li><p>Third</p>
2298 </li>
2299 </ol>
2300 """
2301 var res = test.md_to_html.write_to_string
2302 assert res == exp
2303 end
2304
2305 fun test_daring_strong_em do
2306 var test = """
2307 ***This is strong and em.***
2308
2309 So is ***this*** word.
2310
2311 ___This is strong and em.___
2312
2313 So is ___this___ word.
2314 """
2315
2316 var exp = """
2317 <p><strong><em>This is strong and em.</em></strong></p>
2318 <p>So is <strong><em>this</em></strong> word.</p>
2319 <p><strong><em>This is strong and em.</em></strong></p>
2320 <p>So is <strong><em>this</em></strong> word.</p>
2321 """
2322 var res = test.md_to_html.write_to_string
2323 assert res == exp
2324 end
2325
2326 fun test_daring_tabs do
2327 var test = """
2328 + this is a list item
2329 indented with tabs
2330
2331 + this is a list item
2332 indented with spaces
2333
2334 Code:
2335
2336 this code block is indented by one tab
2337
2338 And:
2339
2340 this code block is indented by two tabs
2341
2342 And:
2343
2344 + this is an example list item
2345 indented with tabs
2346
2347 + this is an example list item
2348 indented with spaces
2349 """
2350
2351 var exp = """
2352 <ul>
2353 <li><p>this is a list item
2354 indented with tabs</p>
2355 </li>
2356 <li><p>this is a list item
2357 indented with spaces</p>
2358 </li>
2359 </ul>
2360 <p>Code:</p>
2361 <pre><code>this code block is indented by one tab
2362 </code></pre>
2363 <p>And:</p>
2364 <pre><code> this code block is indented by two tabs
2365 </code></pre>
2366 <p>And:</p>
2367 <pre><code>+ this is an example list item
2368 indented with tabs
2369
2370 + this is an example list item
2371 indented with spaces
2372 </code></pre>
2373 """
2374 var res = test.md_to_html.write_to_string
2375 assert res == exp
2376 end
2377
2378 fun test_daring_tidyness do
2379 var test = """
2380 > A list within a blockquote:
2381 >
2382 > * asterisk 1
2383 > * asterisk 2
2384 > * asterisk 3
2385 """
2386
2387 var exp = """
2388 <blockquote>
2389 <p>A list within a blockquote:</p>
2390 <ul>
2391 <li>asterisk 1</li>
2392 <li>asterisk 2</li>
2393 <li>asterisk 3</li>
2394 </ul>
2395 </blockquote>
2396 """
2397 var res = test.md_to_html.write_to_string
2398 assert res == exp
2399 end
2400
2401
2402 end
2403
2404 class TestBlock
2405 super TestSuite
2406
2407 # A dummy location for testing purposes.
2408 var loc = new MDLocation(0, 0, 0, 0)
2409
2410 fun test_has_blocks do
2411 var subject = new MDBlock(loc)
2412 assert not subject.has_blocks
2413 subject.first_block = new MDBlock(loc)
2414 assert subject.has_blocks
2415 end
2416
2417 fun test_count_blocks do
2418 var subject = new MDBlock(loc)
2419 assert subject.count_blocks == 0
2420 subject.first_block = new MDBlock(loc)
2421 assert subject.count_blocks == 1
2422 subject.first_block.next = new MDBlock(loc)
2423 assert subject.count_blocks == 2
2424 end
2425
2426 fun test_has_lines do
2427 var subject = new MDBlock(loc)
2428 assert not subject.has_lines
2429 subject.first_line = new MDLine(loc, "")
2430 assert subject.has_lines
2431 end
2432
2433 fun test_count_lines do
2434 var subject = new MDBlock(loc)
2435 assert subject.count_lines == 0
2436 subject.first_line = new MDLine(loc, "")
2437 assert subject.count_lines == 1
2438 subject.first_line.next = new MDLine(loc, "")
2439 assert subject.count_lines == 2
2440 end
2441
2442 fun test_split do
2443 var line1 = new MDLine(loc, "line1")
2444 var line2 = new MDLine(loc, "line2")
2445 var line3 = new MDLine(loc, "line3")
2446 var subject = new MDBlock(loc)
2447 subject.add_line line1
2448 subject.add_line line2
2449 subject.add_line line3
2450 var block = subject.split(line2)
2451 assert subject.count_blocks == 1
2452 assert subject.count_lines == 1
2453 assert subject.first_line == line3
2454 assert block.count_blocks == 0
2455 assert block.count_lines == 2
2456 assert block.first_line == line1
2457 assert block.last_line == line2
2458 end
2459
2460 fun test_add_line do
2461 var subject = new MDBlock(loc)
2462 assert subject.count_lines == 0
2463 subject.add_line new MDLine(loc, "")
2464 assert subject.count_lines == 1
2465 subject.add_line new MDLine(loc, "")
2466 assert subject.count_lines == 2
2467 end
2468
2469 fun test_remove_line do
2470 var line1 = new MDLine(loc, "line1")
2471 var line2 = new MDLine(loc, "line2")
2472 var line3 = new MDLine(loc, "line3")
2473 var subject = new MDBlock(loc)
2474 subject.add_line line1
2475 subject.add_line line2
2476 subject.add_line line3
2477 subject.remove_line(line2)
2478 assert subject.count_lines == 2
2479 subject.remove_line(line1)
2480 assert subject.count_lines == 1
2481 assert subject.first_line == line3
2482 assert subject.last_line == line3
2483 end
2484
2485 fun test_transform_headline1 do
2486 var subject = new MDBlock(loc)
2487 var kind = new BlockHeadline(subject)
2488 subject.add_line new MDLine(loc, " # Title 1 ")
2489 kind.transform_headline(subject)
2490 assert kind.depth == 1
2491 assert subject.first_line.value == "Title 1"
2492 end
2493
2494 fun test_transform_headline2 do
2495 var subject = new MDBlock(loc)
2496 var kind = new BlockHeadline(subject)
2497 subject.add_line new MDLine(loc, " #####Title 5 ")
2498 kind.transform_headline(subject)
2499 assert kind.depth == 5
2500 assert subject.first_line.value == "Title 5"
2501 end
2502
2503 fun test_remove_quote_prefix do
2504 var subject = new MDBlock(loc)
2505 var kind = new BlockQuote(subject)
2506 subject.add_line new MDLine(loc, " > line 1")
2507 subject.add_line new MDLine(loc, " > line 2")
2508 subject.add_line new MDLine(loc, " > line 3")
2509 kind.remove_block_quote_prefix(subject)
2510 assert subject.first_line.value == "line 1"
2511 assert subject.first_line.next.value == "line 2"
2512 assert subject.first_line.next.next.value == "line 3"
2513 end
2514
2515 fun test_remove_leading_empty_lines_1 do
2516 var block = new MDBlock(loc)
2517 block.add_line new MDLine(loc, "")
2518 block.add_line new MDLine(loc, "")
2519 block.add_line new MDLine(loc, "")
2520 block.add_line new MDLine(loc, "")
2521 block.add_line new MDLine(loc, " text")
2522 block.add_line new MDLine(loc, "")
2523 assert block.remove_leading_empty_lines
2524 assert block.first_line.value == " text"
2525 end
2526
2527 fun test_remove_leading_empty_lines_2 do
2528 var block = new MDBlock(loc)
2529 block.add_line new MDLine(loc, " text")
2530 block.remove_leading_empty_lines
2531 assert block.first_line.value == " text"
2532 end
2533
2534 fun test_remove_trailing_empty_lines_1 do
2535 var block = new MDBlock(loc)
2536 block.add_line new MDLine(loc, "")
2537 block.add_line new MDLine(loc, "text")
2538 block.add_line new MDLine(loc, "")
2539 block.add_line new MDLine(loc, "")
2540 block.add_line new MDLine(loc, "")
2541 block.add_line new MDLine(loc, "")
2542 assert block.remove_trailing_empty_lines
2543 assert block.last_line.value == "text"
2544 end
2545
2546 fun test_remove_trailing_empty_lines_2 do
2547 var block = new MDBlock(loc)
2548 block.add_line new MDLine(loc, "text ")
2549 assert not block.remove_trailing_empty_lines
2550 assert block.last_line.value == "text "
2551 end
2552
2553 fun test_remove_surrounding_empty_lines do
2554 var block = new MDBlock(loc)
2555 block.add_line new MDLine(loc, "")
2556 block.add_line new MDLine(loc, "text")
2557 block.add_line new MDLine(loc, "")
2558 block.add_line new MDLine(loc, "")
2559 block.add_line new MDLine(loc, "")
2560 block.add_line new MDLine(loc, "")
2561 assert block.remove_surrounding_empty_lines
2562 assert block.first_line.value == "text"
2563 assert block.last_line.value == "text"
2564 end
2565 end
2566
2567 class TestLine
2568 super TestSuite
2569
2570 # A dummy location for testing purposes.
2571 var loc = new MDLocation(0, 0, 0, 0)
2572
2573 var subject: MDLine
2574
2575 fun test_is_empty do
2576 subject = new MDLine(loc, "")
2577 assert subject.is_empty
2578 subject = new MDLine(loc, " ")
2579 assert subject.is_empty
2580 subject = new MDLine(loc, "test")
2581 assert not subject.is_empty
2582 subject = new MDLine(loc, " test")
2583 assert not subject.is_empty
2584 end
2585
2586 fun test_leading do
2587 subject = new MDLine(loc, "")
2588 assert subject.leading == 0
2589 subject = new MDLine(loc, " ")
2590 assert subject.leading == 4
2591 subject = new MDLine(loc, "test")
2592 assert subject.leading == 0
2593 subject = new MDLine(loc, " test")
2594 assert subject.leading == 4
2595 end
2596
2597 fun test_trailing do
2598 subject = new MDLine(loc, "")
2599 assert subject.trailing == 0
2600 subject = new MDLine(loc, " ")
2601 assert subject.trailing == 0
2602 subject = new MDLine(loc, "test ")
2603 assert subject.trailing == 3
2604 subject = new MDLine(loc, " test ")
2605 assert subject.trailing == 1
2606 end
2607
2608 fun test_line_type do
2609 var v = new MarkdownProcessor
2610 subject = new MDLine(loc, "")
2611 assert v.line_kind(subject) isa LineEmpty
2612 subject = new MDLine(loc, " ")
2613 assert v.line_kind(subject) isa LineEmpty
2614 subject = new MDLine(loc, "text ")
2615 assert v.line_kind(subject) isa LineOther
2616 subject = new MDLine(loc, " # Title")
2617 assert v.line_kind(subject) isa LineHeadline
2618 subject = new MDLine(loc, " ### Title")
2619 assert v.line_kind(subject) isa LineHeadline
2620 subject = new MDLine(loc, " code")
2621 assert v.line_kind(subject) isa LineCode
2622 subject = new MDLine(loc, " Title ")
2623 subject.next = new MDLine(loc, "== ")
2624 assert v.line_kind(subject) isa LineHeadline1
2625 subject = new MDLine(loc, " Title ")
2626 subject.next = new MDLine(loc, "-- ")
2627 assert v.line_kind(subject) isa LineHeadline2
2628 subject = new MDLine(loc, " * * * ")
2629 assert v.line_kind(subject) isa LineHR
2630 subject = new MDLine(loc, " *** ")
2631 assert v.line_kind(subject) isa LineHR
2632 subject = new MDLine(loc, "- -- ")
2633 assert v.line_kind(subject) isa LineHR
2634 subject = new MDLine(loc, "--------- ")
2635 assert v.line_kind(subject) isa LineHR
2636 subject = new MDLine(loc, " >")
2637 assert v.line_kind(subject) isa LineBlockquote
2638 subject = new MDLine(loc, "<p></p>")
2639 assert v.line_kind(subject) isa LineXML
2640 subject = new MDLine(loc, "<p>")
2641 assert v.line_kind(subject) isa LineOther
2642 subject = new MDLine(loc, " * foo")
2643 assert v.line_kind(subject) isa LineUList
2644 subject = new MDLine(loc, "- foo")
2645 assert v.line_kind(subject) isa LineUList
2646 subject = new MDLine(loc, "+ foo")
2647 assert v.line_kind(subject) isa LineUList
2648 subject = new MDLine(loc, "1. foo")
2649 assert v.line_kind(subject) isa LineOList
2650 subject = new MDLine(loc, " 11111. foo")
2651 assert v.line_kind(subject) isa LineOList
2652 end
2653
2654 fun test_line_type_ext do
2655 var v = new MarkdownProcessor
2656 subject = new MDLine(loc, " ~~~")
2657 assert v.line_kind(subject) isa LineFence
2658 subject = new MDLine(loc, " ```")
2659 assert v.line_kind(subject) isa LineFence
2660 subject = new MDLine(loc, "~~~raw")
2661 assert v.line_kind(subject) isa LineFence
2662 end
2663
2664 fun test_count_chars do
2665 subject = new MDLine(loc, "")
2666 assert subject.count_chars('*') == 0
2667 subject = new MDLine(loc, "* ")
2668 assert subject.count_chars('*') == 1
2669 subject = new MDLine(loc, " * text")
2670 assert subject.count_chars('*') == 0
2671 subject = new MDLine(loc, " * * *")
2672 assert subject.count_chars('*') == 3
2673 subject = new MDLine(loc, "text ** ")
2674 assert subject.count_chars('*') == 0
2675 end
2676
2677 fun test_count_chars_start do
2678 subject = new MDLine(loc, "")
2679 assert subject.count_chars_start('*') == 0
2680 subject = new MDLine(loc, "* ")
2681 assert subject.count_chars_start('*') == 1
2682 subject = new MDLine(loc, " * text")
2683 assert subject.count_chars_start('*') == 1
2684 subject = new MDLine(loc, " * * * text")
2685 assert subject.count_chars_start('*') == 3
2686 subject = new MDLine(loc, "text ** ")
2687 assert subject.count_chars_start('*') == 0
2688 end
2689 end
2690
2691 class TestHTMLDecorator
2692 super TestSuite
2693
2694 fun test_headlines do
2695 var test = """
2696 # **a**
2697 ## a.a
2698 ### a.a.b
2699 ### a.a.b
2700 ## a.b
2701 # [b](test)
2702 ## b.a
2703 ### b.a.c
2704 ## b.b
2705 ## b.c
2706 # c
2707 """
2708 var proc = new MarkdownProcessor
2709 var decorator = proc.emitter.decorator.as(HTMLDecorator)
2710 proc.process(test)
2711 var res = ""
2712 for id, headline in decorator.headlines do
2713 res += "{headline.title}:{id}\n"
2714 end
2715 var exp = """
2716 **a**:a
2717 a.a:a.a
2718 a.a.b:a.a.b
2719 a.a.b:a.a.b_1
2720 a.b:a.b
2721 [b](test):btest
2722 b.a:b.a
2723 b.a.c:b.a.c
2724 b.b:b.b
2725 b.c:b.c
2726 c:c
2727 """
2728 assert res == exp
2729 end
2730 end
2731
2732 class TestTokenLocation
2733 super TestSuite
2734
2735 fun test_token_location1 do
2736 var string = "**Hello** `World`"
2737 var stack = [
2738 "TokenStrongStar at 1,1--1,1",
2739 "TokenStrongStar at 1,8--1,8",
2740 "TokenCodeSingle at 1,11--1,11",
2741 "TokenCodeSingle at 1,17--1,17"]
2742 (new TestTokenProcessor(stack)).process(string)
2743 end
2744
2745 fun test_token_location2 do
2746 var string = "**Hello**\n`World`\n*Bonjour*\n[le monde]()"
2747 var stack = [
2748 "TokenStrongStar at 1,1--1,1",
2749 "TokenStrongStar at 1,8--1,8",
2750 "TokenCodeSingle at 2,1--2,1",
2751 "TokenCodeSingle at 2,7--2,7",
2752 "TokenEmStar at 3,1--3,1",
2753 "TokenEmStar at 3,9--3,9",
2754 "TokenLink at 4,1--4,1"]
2755 (new TestTokenProcessor(stack)).process(string)
2756 end
2757
2758 fun test_token_location3 do
2759 var string = """**Hello**
2760 `World`
2761 *Bonjour*
2762 [le monde]()"""
2763 var stack = [
2764 "TokenStrongStar at 1,1--1,1",
2765 "TokenStrongStar at 1,8--1,8",
2766 "TokenCodeSingle at 2,1--2,1",
2767 "TokenCodeSingle at 2,7--2,7",
2768 "TokenEmStar at 3,1--3,1",
2769 "TokenEmStar at 3,9--3,9",
2770 "TokenLink at 4,1--4,1"]
2771 (new TestTokenProcessor(stack)).process(string)
2772 end
2773
2774 fun test_token_location4 do
2775 var string = "**Hello**\n\n`World`"
2776 var stack = [
2777 "TokenStrongStar at 1,1--1,1",
2778 "TokenStrongStar at 1,8--1,8",
2779 "TokenCodeSingle at 3,1--3,1",
2780 "TokenCodeSingle at 3,7--3,7"]
2781 (new TestTokenProcessor(stack)).process(string)
2782 end
2783
2784 fun test_token_location5 do
2785 var string = "# *Title1*\n\n# *Title2*"
2786 var stack = [
2787 "TokenEmStar at 1,3--1,3",
2788 "TokenEmStar at 1,10--1,10",
2789 "TokenEmStar at 3,3--3,3",
2790 "TokenEmStar at 3,10--3,10"]
2791 (new TestTokenProcessor(stack)).process(string)
2792 end
2793 end
2794
2795 class TestTokenProcessor
2796 super MarkdownProcessor
2797
2798 var test_stack: Array[String]
2799
2800 redef fun token_at(input, pos) do
2801 var token = super
2802 if token isa TokenNone then return token
2803 var res = "{token.class_name} at {token.location}"
2804 var exp = test_stack.shift
2805 print ""
2806 print "EXP {exp}"
2807 print "RES {res}"
2808 assert exp == res
2809 return token
2810 end
2811 end
2812
2813 class TestBlockLocation
2814 super TestSuite
2815
2816 var proc = new MarkdownProcessor
2817
2818 fun test_block_location1 do
2819 var stack = [
2820 "BlockHeadline: 1,1--1,8",
2821 "BlockListItem: 2,1--2,6",
2822 "BlockListItem: 3,1--3,5"
2823 ]
2824 var string =
2825 "# Title\n* li1\n* li2"
2826 proc.emitter.decorator = new TestBlockDecorator(stack)
2827 proc.process(string)
2828 end
2829
2830 fun test_block_location2 do
2831 var stack = [
2832 "BlockHeadline: 1,1--1,11",
2833 "BlockFence: 3,1--5,4",
2834 "BlockListItem: 7,1--7,7",
2835 "BlockListItem: 8,1--8,6"]
2836 var string ="""#### Title
2837
2838 ~~~fence
2839 some code
2840 ~~~
2841
2842 1. li1
2843 1. li2"""
2844 proc.emitter.decorator = new TestBlockDecorator(stack)
2845 proc.process(string)
2846 end
2847
2848 fun test_block_location3 do
2849 var stack = [
2850 "BlockHeadline: 1,1--1,8",
2851 "BlockHeadline: 3,1--3,10"]
2852 var string ="""# Title\n\n## Title 2"""
2853 proc.emitter.decorator = new TestBlockDecorator(stack)
2854 proc.process(string)
2855 end
2856 end
2857
2858 class TestBlockDecorator
2859 super HTMLDecorator
2860
2861 var stack: Array[String]
2862
2863 redef fun add_headline(v, block) do
2864 super
2865 check_res(block)
2866 end
2867
2868 redef fun add_listitem(v, block) do
2869 super
2870 check_res(block)
2871 end
2872
2873 redef fun add_blockquote(v, block) do
2874 super
2875 check_res(block)
2876 end
2877
2878 redef fun add_code(v, block) do
2879 super
2880 check_res(block)
2881 end
2882
2883 fun check_res(block: Block) do
2884 var res = "{block.class_name}: {block.block.location}"
2885 var exp = stack.shift
2886 assert res == exp
2887 end
2888 end