1# coding: UTF-8
2
3require 'rubygems'
4require 'minitest/autorun'
5require 'pp'
6
7require 'rdoc'
8require 'rdoc/markup/block_quote'
9require 'rdoc/markdown'
10
11class TestRDocMarkdown < RDoc::TestCase
12
13  def setup
14    @RM = RDoc::Markup
15
16    @parser = RDoc::Markdown.new
17  end
18
19  def mu_pp obj
20    s = ''
21    s = PP.pp obj, s
22    s.force_encoding Encoding.default_external if defined? Encoding
23    s.chomp
24  end
25
26  def test_class_parse
27    doc = RDoc::Markdown.parse "hello\n\nworld"
28
29    expected = doc(para("hello"), para("world"))
30
31    assert_equal expected, doc
32  end
33
34  def test_emphasis
35    assert_equal '_word_',             @parser.emphasis('word')
36    assert_equal '<em>two words</em>', @parser.emphasis('two words')
37    assert_equal '<em>*bold*</em>',    @parser.emphasis('*bold*')
38  end
39
40  def test_parse_auto_link_email
41    doc = parse "Autolink: <nobody-0+_./!%~$@example>"
42
43    expected = doc(para("Autolink: mailto:nobody-0+_./!%~$@example"))
44
45    assert_equal expected, doc
46  end
47
48  def test_parse_auto_link_url
49    doc = parse "Autolink: <http://example>"
50
51    expected = doc(para("Autolink: http://example"))
52
53    assert_equal expected, doc
54  end
55
56  def test_parse_block_quote
57    doc = parse <<-BLOCK_QUOTE
58> this is
59> a block quote
60    BLOCK_QUOTE
61
62    expected =
63      doc(
64        block(
65          para("this is\na block quote")))
66
67    assert_equal expected, doc
68  end
69
70  def test_parse_block_quote_continue
71    doc = parse <<-BLOCK_QUOTE
72> this is
73a block quote
74    BLOCK_QUOTE
75
76    expected =
77      doc(
78        block(
79          para("this is\na block quote")))
80
81    assert_equal expected, doc
82  end
83
84  def test_parse_block_quote_list
85    doc = parse <<-BLOCK_QUOTE
86> text
87>
88> * one
89> * two
90    BLOCK_QUOTE
91
92    expected =
93      doc(
94        block(
95          para("text"),
96          list(:BULLET,
97            item(nil, para("one")),
98            item(nil, para("two")))))
99
100    assert_equal expected, doc
101  end
102
103  def test_parse_block_quote_newline
104    doc = parse <<-BLOCK_QUOTE
105> this is
106a block quote
107
108    BLOCK_QUOTE
109
110    expected =
111      doc(
112        block(
113          para("this is\na block quote")))
114
115    assert_equal expected, doc
116  end
117
118  def test_parse_block_quote_separate
119    doc = parse <<-BLOCK_QUOTE
120> this is
121a block quote
122
123> that continues
124    BLOCK_QUOTE
125
126    expected =
127      doc(
128        block(
129          para("this is\na block quote"),
130          para("that continues")))
131
132    assert_equal expected, doc
133  end
134
135  def test_parse_char_entity
136    doc = parse '&pi; &nn;'
137
138    expected = doc(para('�� &nn;'))
139
140    assert_equal expected, doc
141  end
142
143  def test_parse_code
144    doc = parse "Code: `text`"
145
146    expected = doc(para("Code: <code>text</code>"))
147
148    assert_equal expected, doc
149  end
150
151  def test_parse_code_github
152    doc = parse <<-MD
153Example:
154
155```
156code goes here
157```
158    MD
159
160    expected =
161      doc(
162        para("Example:"),
163        verb("code goes here\n"))
164
165    assert_equal expected, doc
166  end
167
168  def test_parse_code_github_format
169    doc = parse <<-MD
170Example:
171
172``` ruby
173code goes here
174```
175    MD
176
177    code = verb("code goes here\n")
178    code.format = :ruby
179
180    expected =
181      doc(
182        para("Example:"),
183        code)
184
185    assert_equal expected, doc
186  end
187
188  def test_parse_definition_list
189    doc = parse <<-MD
190one
191:   This is a definition
192
193two
194:   This is another definition
195    MD
196
197    expected = doc(
198      list(:NOTE,
199        item(%w[one], para("This is a definition")),
200        item(%w[two], para("This is another definition"))))
201
202    assert_equal expected, doc
203  end
204
205  def test_parse_definition_list_indents
206    doc = parse <<-MD
207zero
208: Indented zero characters
209
210one
211 : Indented one characters
212
213two
214  : Indented two characters
215
216three
217   : Indented three characters
218
219four
220    : Indented four characters
221
222    MD
223
224    expected = doc(
225      list(:NOTE,
226        item(%w[zero],  para("Indented zero characters")),
227        item(%w[one],   para("Indented one characters")),
228        item(%w[two],   para("Indented two characters")),
229        item(%w[three], para("Indented three characters"))),
230      para("four\n : Indented four characters"))
231
232    assert_equal expected, doc
233  end
234
235  def test_parse_definition_list_multi_description
236    doc = parse <<-MD
237label
238:   This is a definition
239
240:   This is another definition
241    MD
242
243    expected = doc(
244      list(:NOTE,
245        item(%w[label], para("This is a definition")),
246        item(nil,       para("This is another definition"))))
247
248    assert_equal expected, doc
249  end
250
251  def test_parse_definition_list_multi_label
252    doc = parse <<-MD
253one
254two
255:   This is a definition
256    MD
257
258    expected = doc(
259      list(:NOTE,
260        item(%w[one two], para("This is a definition"))))
261
262    assert_equal expected, doc
263  end
264
265  def test_parse_definition_list_multi_line
266    doc = parse <<-MD
267one
268:   This is a definition
269that extends to two lines
270
271two
272:   This is another definition
273that also extends to two lines
274    MD
275
276    expected = doc(
277      list(:NOTE,
278        item(%w[one],
279          para("This is a definition\nthat extends to two lines")),
280        item(%w[two],
281          para("This is another definition\nthat also extends to two lines"))))
282
283    assert_equal expected, doc
284  end
285
286  def test_parse_definition_list_no
287    @parser.definition_lists = false
288
289    doc = parse <<-MD
290one
291:   This is a definition
292
293two
294:   This is another definition
295    MD
296
297    expected = doc(
298        para("one\n: This is a definition"),
299        para("two\n: This is another definition"))
300
301    assert_equal expected, doc
302  end
303
304  def test_parse_entity_dec
305    doc = parse "Entity: &#65;"
306
307    expected = doc(para("Entity: A"))
308
309    assert_equal expected, doc
310  end
311
312  def test_parse_entity_hex
313    doc = parse "Entity: &#x41;"
314
315    expected = doc(para("Entity: A"))
316
317    assert_equal expected, doc
318  end
319
320  def test_parse_entity_named
321    doc = parse "Entity: &pi;"
322
323    expected = doc(para("Entity: ��"))
324
325    assert_equal expected, doc
326  end
327
328  def test_parse_emphasis_star
329    doc = parse "it *works*\n"
330
331    expected = @RM::Document.new(
332      @RM::Paragraph.new("it _works_"))
333
334    assert_equal expected, doc
335  end
336
337  def test_parse_emphasis_underscore
338    doc = parse "it _works_\n"
339
340    expected =
341      doc(
342        para("it _works_"))
343
344    assert_equal expected, doc
345  end
346
347  def test_parse_emphasis_underscore_embedded
348    doc = parse "foo_bar bar_baz\n"
349
350    expected =
351      doc(
352        para("foo_bar bar_baz"))
353
354    assert_equal expected, doc
355  end
356
357  def test_parse_emphasis_underscore_in_word
358    doc = parse "it foo_bar_baz\n"
359
360    expected =
361      doc(
362        para("it foo_bar_baz"))
363
364    assert_equal expected, doc
365  end
366
367  def test_parse_escape
368    assert_equal doc(para("Backtick: `")), parse("Backtick: \\`")
369
370    assert_equal doc(para("Backslash: \\")), parse("Backslash: \\\\")
371
372    assert_equal doc(para("Colon: :")), parse("Colon: \\:")
373  end
374
375  def test_parse_heading_atx
376    doc = parse "# heading\n"
377
378    expected = @RM::Document.new(
379      @RM::Heading.new(1, "heading"))
380
381    assert_equal expected, doc
382  end
383
384  def test_parse_heading_setext_dash
385    doc = parse <<-MD
386heading
387---
388    MD
389
390    expected = @RM::Document.new(
391      @RM::Heading.new(2, "heading"))
392
393    assert_equal expected, doc
394  end
395
396  def test_parse_heading_setext_equals
397    doc = parse <<-MD
398heading
399===
400    MD
401
402    expected = @RM::Document.new(
403      @RM::Heading.new(1, "heading"))
404
405    assert_equal expected, doc
406  end
407
408  def test_parse_html
409    @parser.html = true
410
411    doc = parse "<address>Links here</address>\n"
412
413    expected = doc(
414      @RM::Raw.new("<address>Links here</address>"))
415
416    assert_equal expected, doc
417  end
418
419  def test_parse_html_hr
420    @parser.html = true
421
422    doc = parse "<hr>\n"
423
424    expected = doc(raw("<hr>"))
425
426    assert_equal expected, doc
427  end
428
429  def test_parse_html_no_html
430    @parser.html = false
431
432    doc = parse "<address>Links here</address>\n"
433
434    expected = doc()
435
436    assert_equal expected, doc
437  end
438
439  def test_parse_image
440    doc = parse "image ![alt text](path/to/image.jpg)"
441
442    expected = doc(para("image {alt text}[path/to/image.jpg]"))
443
444    assert_equal expected, doc
445  end
446
447  def test_parse_line_break
448    doc = parse "Some text  \nwith extra lines"
449
450    expected = doc(
451      para("Some text", hard_break, "with extra lines"))
452
453    assert_equal expected, doc
454  end
455
456  def test_parse_link_reference_id
457    doc = parse <<-MD
458This is [an example][id] reference-style link.
459
460[id]: http://example.com "Optional Title Here"
461    MD
462
463    expected = doc(
464      para("This is {an example}[http://example.com] reference-style link."))
465
466    assert_equal expected, doc
467  end
468
469  def test_parse_link_reference_id_adjacent
470    doc = parse <<-MD
471[this] [this] should work
472
473[this]: example
474    MD
475
476    expected = doc(
477      para("{this}[example] should work"))
478
479    assert_equal expected, doc
480  end
481
482  def test_parse_link_reference_id_eof
483    doc = parse <<-MD.chomp
484This is [an example][id] reference-style link.
485
486[id]: http://example.com "Optional Title Here"
487    MD
488
489    expected = doc(
490      para("This is {an example}[http://example.com] reference-style link."))
491
492    assert_equal expected, doc
493  end
494
495  def test_parse_link_reference_id_many
496    doc = parse <<-MD
497This is [an example][id] reference-style link.
498
499And [another][id].
500
501[id]: http://example.com "Optional Title Here"
502    MD
503
504    expected = doc(
505      para("This is {an example}[http://example.com] reference-style link."),
506      para("And {another}[http://example.com]."))
507
508    assert_equal expected, doc
509  end
510
511  def test_parse_link_reference_implicit
512    doc = parse <<-MD
513This is [an example][] reference-style link.
514
515[an example]: http://example.com "Optional Title Here"
516    MD
517
518    expected = doc(
519      para("This is {an example}[http://example.com] reference-style link."))
520
521    assert_equal expected, doc
522  end
523
524  def test_parse_list_bullet
525    doc = parse <<-MD
526* one
527* two
528    MD
529
530    expected = doc(
531      list(:BULLET,
532        item(nil, para("one")),
533        item(nil, para("two"))))
534
535    assert_equal expected, doc
536  end
537
538  def test_parse_list_bullet_auto_link
539    doc = parse <<-MD
540* <http://example/>
541    MD
542
543    expected = doc(
544      list(:BULLET,
545        item(nil, para("http://example/"))))
546
547    assert_equal expected, doc
548  end
549
550  def test_parse_list_bullet_continue
551    doc = parse <<-MD
552* one
553
554* two
555    MD
556
557    expected = doc(
558      list(:BULLET,
559        item(nil, para("one")),
560        item(nil, para("two"))))
561
562    assert_equal expected, doc
563  end
564
565  def test_parse_list_bullet_multiline
566    doc = parse <<-MD
567* one
568  two
569    MD
570
571    expected = doc(
572      list(:BULLET,
573        item(nil, para("one\n two"))))
574
575    assert_equal expected, doc
576  end
577
578  def test_parse_list_bullet_nest
579    doc = parse <<-MD
580* outer
581    * inner
582    MD
583
584    expected = doc(
585      list(:BULLET,
586        item(nil,
587          para("outer"),
588          list(:BULLET,
589            item(nil,
590              para("inner"))))))
591
592    assert_equal expected, doc
593  end
594
595  def test_parse_list_bullet_nest_loose
596    doc = parse <<-MD
597* outer
598
599    * inner
600    MD
601
602    expected = doc(
603      list(:BULLET,
604        item(nil,
605          para("outer"),
606          list(:BULLET,
607            item(nil, para("inner"))))))
608
609    assert_equal expected, doc
610  end
611
612  def test_parse_list_bullet_nest_continue
613    doc = parse <<-MD
614* outer
615    * inner
616  continue inner
617* outer 2
618    MD
619
620    expected = doc(
621      list(:BULLET,
622        item(nil,
623          para("outer"),
624          list(:BULLET,
625            item(nil,
626              para("inner\n continue inner")))),
627        item(nil,
628          para("outer 2"))))
629
630    assert_equal expected, doc
631  end
632
633  def test_parse_list_number
634    doc = parse <<-MD
6351. one
6361. two
637    MD
638
639    expected = doc(
640      list(:NUMBER,
641        item(nil, para("one")),
642        item(nil, para("two"))))
643
644    assert_equal expected, doc
645  end
646
647  def test_parse_list_number_continue
648    doc = parse <<-MD
6491. one
650
6511. two
652    MD
653
654    expected = doc(
655      list(:NUMBER,
656        item(nil, para("one")),
657        item(nil, para("two"))))
658
659    assert_equal expected, doc
660  end
661
662  def test_parse_note
663    @parser.notes = true
664
665    doc = parse <<-MD
666Some text.[^1]
667
668[^1]: With a footnote
669    MD
670
671    expected = doc(
672      para("Some text.{*1}[rdoc-label:foottext-1:footmark-1]"),
673      @RM::Rule.new(1),
674      para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"))
675
676    assert_equal expected, doc
677  end
678
679  def test_parse_note_indent
680    @parser.notes = true
681
682    doc = parse <<-MD
683Some text.[^1]
684
685[^1]: With a footnote
686
687    more
688    MD
689
690    expected = doc(
691      para("Some text.{*1}[rdoc-label:foottext-1:footmark-1]"),
692      rule(1),
693      para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote\n\nmore"))
694
695    assert_equal expected, doc
696  end
697
698  def test_parse_note_inline
699    @parser.notes = true
700
701    doc = parse <<-MD
702Some text. ^[With a footnote]
703    MD
704
705    expected = doc(
706      para("Some text. {*1}[rdoc-label:foottext-1:footmark-1]"),
707      @RM::Rule.new(1),
708      para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"))
709
710    assert_equal expected, doc
711  end
712
713  def test_parse_note_no_notes
714    @parser.notes = false
715
716    assert_raises RuntimeError do # TODO use a real error
717      parse "Some text.[^1]"
718    end
719  end
720
721  def test_parse_note_multiple
722    @parser.notes = true
723
724    doc = parse <<-MD
725Some text[^1]
726with inline notes^[like this]
727and an extra note.[^2]
728
729[^1]: With a footnote
730
731[^2]: Which should be numbered correctly
732    MD
733
734    expected = doc(
735      para("Some text{*1}[rdoc-label:foottext-1:footmark-1]\n" +
736           "with inline notes{*2}[rdoc-label:foottext-2:footmark-2]\n" +
737           "and an extra note.{*3}[rdoc-label:foottext-3:footmark-3]"),
738
739      rule(1),
740
741      para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"),
742      para("{^2}[rdoc-label:footmark-2:foottext-2] like this"),
743      para("{^3}[rdoc-label:footmark-3:foottext-3] " +
744           "Which should be numbered correctly"))
745
746    assert_equal expected, doc
747  end
748
749  def test_parse_paragraph
750    doc = parse "it worked\n"
751
752    expected = doc(para("it worked"))
753
754    assert_equal expected, doc
755  end
756
757  def test_parse_paragraph_break_on_newline
758    @parser.break_on_newline = true
759
760    doc = parse "one\ntwo\n"
761
762    expected = doc(para("one", hard_break, "two"))
763
764    assert_equal expected, doc
765
766    doc = parse "one  \ntwo\nthree\n"
767
768    expected = doc(para("one", hard_break, "two", hard_break, "three"))
769
770    assert_equal expected, doc
771  end
772
773  def test_parse_paragraph_stars
774    doc = parse "it worked ****\n"
775
776    expected = @RM::Document.new(
777      @RM::Paragraph.new("it worked ****"))
778
779    assert_equal expected, doc
780  end
781
782  def test_parse_paragraph_html
783    @parser.html = true
784
785    doc = parse "<address>Links here</address>"
786
787    expected = doc(raw("<address>Links here</address>"))
788
789    assert_equal expected, doc
790  end
791
792  def test_parse_paragraph_html_no_html
793    @parser.html = false
794
795    doc = parse "<address>Links here</address>"
796
797    expected = doc()
798
799    assert_equal expected, doc
800  end
801
802  def test_parse_paragraph_indent_one
803    doc = parse <<-MD
804 text
805    MD
806
807    expected = doc(para("text"))
808
809    assert_equal expected, doc
810  end
811
812  def test_parse_paragraph_indent_two
813    doc = parse <<-MD
814  text
815    MD
816
817    expected = doc(para("text"))
818
819    assert_equal expected, doc
820  end
821
822  def test_parse_paragraph_indent_three
823    doc = parse <<-MD
824   text
825    MD
826
827    expected = doc(para("text"))
828
829    assert_equal expected, doc
830  end
831
832  def test_parse_paragraph_multiline
833    doc = parse "one\ntwo"
834
835    expected = doc(para("one\ntwo"))
836
837    assert_equal expected, doc
838  end
839
840  def test_parse_paragraph_two
841    doc = parse "one\n\ntwo"
842
843    expected = @RM::Document.new(
844      @RM::Paragraph.new("one"),
845      @RM::Paragraph.new("two"))
846
847    assert_equal expected, doc
848  end
849
850  def test_parse_plain
851    doc = parse "it worked"
852
853    expected = @RM::Document.new(
854      @RM::Paragraph.new("it worked"))
855
856    assert_equal expected, doc
857  end
858
859  def test_parse_reference_link_embedded_bracket
860    doc = parse "With [embedded [brackets]] [b].\n\n[b]: /url/\n"
861
862    expected =
863      doc(
864        para("With {embedded [brackets]}[/url/]."))
865
866    assert_equal expected, doc
867  end
868
869  def test_parse_rule_dash
870    doc = parse "- - -\n\n"
871
872    expected = @RM::Document.new(@RM::Rule.new(1))
873
874    assert_equal expected, doc
875  end
876
877  def test_parse_rule_underscore
878    doc = parse "_ _ _\n\n"
879
880    expected = @RM::Document.new(@RM::Rule.new(1))
881
882    assert_equal expected, doc
883  end
884
885  def test_parse_rule_star
886    doc = parse "* * *\n\n"
887
888    expected = @RM::Document.new(@RM::Rule.new(1))
889
890    assert_equal expected, doc
891  end
892
893  def test_parse_strong_star
894    doc = parse "it **works**\n"
895
896    expected = @RM::Document.new(
897      @RM::Paragraph.new("it *works*"))
898
899    assert_equal expected, doc
900  end
901
902  def test_parse_strong_underscore
903    doc = parse "it __works__\n"
904
905    expected = @RM::Document.new(
906      @RM::Paragraph.new("it *works*"))
907
908    assert_equal expected, doc
909  end
910
911  def test_parse_strong_emphasis_star
912    doc = parse "it ***works***\n"
913
914    expected = @RM::Document.new(
915      @RM::Paragraph.new("it <b>_works_</b>"))
916
917    assert_equal expected, doc
918  end
919
920  def test_parse_strong_emphasis_underscore
921    doc = parse "it ___works___\n"
922
923    expected = @RM::Document.new(
924      @RM::Paragraph.new("it <b>_works_</b>"))
925
926    assert_equal expected, doc
927  end
928
929  def test_parse_style
930    @parser.css = true
931
932    doc = parse "<style>h1 { color: red }</style>\n"
933
934    expected = doc(
935      @RM::Raw.new("<style>h1 { color: red }</style>"))
936
937    assert_equal expected, doc
938  end
939
940  def test_parse_style_disabled
941    doc = parse "<style>h1 { color: red }</style>\n"
942
943    expected = doc()
944
945    assert_equal expected, doc
946  end
947
948  def test_parse_verbatim
949    doc = parse <<-MD
950    text
951    MD
952
953    expected = doc(verb("text\n"))
954
955    assert_equal expected, doc
956  end
957
958  def test_parse_verbatim_eof
959    doc = parse "    text"
960
961    expected = doc(verb("text\n"))
962
963    assert_equal expected, doc
964  end
965
966  def test_strong
967    assert_equal '*word*',            @parser.strong('word')
968    assert_equal '<b>two words</b>',  @parser.strong('two words')
969    assert_equal '<b>_emphasis_</b>', @parser.strong('_emphasis_')
970  end
971
972  def parse text
973    @parser.parse text
974  end
975
976end
977
978