# This file is part of NIT ( http://www.nitlanguage.org ). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Test suites for module `markdown` module test_markdown is test_suite import test_suite intrude import markdown class TestMarkdownProcessor super TestSuite fun test_process_empty do var test = "" var exp = "" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_tabs do var test = """ some code """ var exp = """
some code
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_par1 do var test = "test" var exp = "

test

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_par2 do var test = """ line1 line2 line3 line4 line5""" var exp = """

line1 line2

line3 line4

line5

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_par3 do var test = """ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. """ var exp = """

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_headings_1 do var test = """ This is a H1 ============= This is a H2 ------------- """ var exp = """

This is a H1

This is a H2

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_headings_2 do var test = """ # This is a H1 ## This is a H2 ###### This is a H6 """ var exp = """

This is a H1

This is a H2

This is a H6
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_headings_3 do var test = """ # This is a H1 # ## This is a H2 ## ### This is a H3 ###### """ var exp = """

This is a H1

This is a H2

This is a H3

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_hr do var test = """ * * * *** ***** - - - --------------------------------------- """ var exp = "
\n
\n
\n
\n
\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_bquote1 do var test = """ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing. """ var exp = """

This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_bquote2 do var test = """ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. """ var exp = """

This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_bquote3 do var test = """ > This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level. """ var exp = """

This is the first level of quoting.

This is nested blockquote.

Back to the first level.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list1 do var test = """ * Red * Green * Blue """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list2 do var test = """ + Red + Green + Blue """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list3 do var test = """ - Red - Green - Blue """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list4 do var test = """ 1. Bird 2. McHale 3. Parish """ var exp = """
  1. Bird
  2. McHale
  3. Parish
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list5 do var test = """ 3. Bird 1. McHale 8. Parish """ var exp = """
  1. Bird
  2. McHale
  3. Parish
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list6 do var test = """ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list7 do var test = """ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list8 do var test = """ * Bird * Magic """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list9 do var test = """ 1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing. """ var exp = """
  1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.

    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit.

  2. Suspendisse id sem consectetuer libero luctus adipiscing.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list10 do var test = """ * This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list. """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_list11 do var test = """ This is a paragraph * and this is not a list """ var exp = """

This is a paragraph * and this is not a list

""" var proc = new MarkdownProcessor proc.ext_mode = false var res = proc.process(test).write_to_string assert res == exp end fun test_process_list_ext do var test = """ This is a paragraph * and this is not a list """ var exp = """

This is a paragraph

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code1 do var test = """ This is a normal paragraph: This is a code block. """ var exp = """

This is a normal paragraph:

This is a code block.
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code2 do var test = """ Here is an example of AppleScript: tell application "Foo" beep end tell """ var exp = """

Here is an example of AppleScript:

tell application "Foo"
    beep
end tell

<div class="footer">
    &copy; 2004 Foo Corporation
</div>
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext1 do var test = """ Here is an example of AppleScript: ~~~ tell application "Foo" beep end tell ~~~ """ var exp = """

Here is an example of AppleScript:

tell application "Foo"
    beep
end tell

<div class="footer">
    &copy; 2004 Foo Corporation
</div>
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext2 do var test = """ Here is an example of AppleScript: ``` tell application "Foo" beep end tell ``` """ var exp = """

Here is an example of AppleScript:

tell application "Foo"
    beep
end tell

<div class="footer">
    &copy; 2004 Foo Corporation
</div>
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext3 do var proc = new MarkdownProcessor proc.ext_mode = false var test = """ Here is an example of AppleScript: beep """ var exp = """

Here is an example of AppleScript: beep

""" var res = proc.process(test).write_to_string assert res == exp end fun test_process_code_ext4 do var test = """ Here is an example of AppleScript: beep """ var exp = """

Here is an example of AppleScript:

beep
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext5 do var test = """ ```nit print "Hello World!" ``` """ var exp = """
print "Hello World!"
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext6 do var test = """ ~~~ print "Hello" ~~~ ~~~ print "World" ~~~ """ var exp = """
print "Hello"
print "World"
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_code_ext7 do var test = """ ~~~ print "Hello" ~~~ ~~~ print "World" ~~~ """ var exp = """
print "Hello"
print "World"
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_nesting1 do var test = """ > ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script"); """ var exp = """

This is a header.

  1. This is the first list item.
  2. This is the second list item.

Here's some example code:

return shell_exec("echo $input | $markdown_script");
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_nesting2 do var test = """ * A list item with a blockquote: > This is a blockquote > inside a list item. """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_nesting3 do var test = """ * A list item with a code block: """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end fun test_process_nesting4 do var test = """ * Tab * Tab * Tab """ var exp = """ """ var res = test.md_to_html.write_to_string assert res == exp end # TODO # fun test_process_nesting5 do # var test = """ # * this # # * sub # # that # """ # var exp = """ # # """ # var res = test.md_to_html.write_to_string # assert res == exp # end fun test_process_emph1 do var test = """ *single asterisks* _single underscores_ **double asterisks** __double underscores__ """ var exp = """

single asterisks

single underscores

double asterisks

double underscores

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_emph2 do var test = "un*frigging*believable" var exp = "

unfriggingbelievable

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_emph3 do var proc = new MarkdownProcessor proc.ext_mode = false var test = "Con_cat_this" var exp = "

Concatthis

\n" var res = proc.process(test).write_to_string assert res == exp end fun test_process_emph_ext do var test = "Con_cat_this" var exp = "

Con_cat_this

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_xml1 do var test = """ This is a regular paragraph.
Foo
This is another regular paragraph. """ var exp = """

This is a regular paragraph.

Foo

This is another regular paragraph.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_xml2 do var test = """ This is an image baz in a regular paragraph. """ var exp = """

This is an image baz in a regular paragraph.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_xml3 do var test = """
""" var exp = """
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_xml4 do var test = """

This is an example of a block element that should be escaped.

Idem for the second paragraph.

""" var exp = test var res = test.md_to_html.write_to_string assert res == exp end fun test_process_xml5 do var test = """ # Some more XML tests

This is an example of a block element that should be escaped.

Idem for the second paragraph.

With a *md paragraph*! """ var exp = """

Some more XML tests

This is an example of a block element that should be escaped.

Idem for the second paragraph.

With a md paragraph!

""" var res = test.md_to_html.write_to_string print res assert res == exp end fun test_process_span_code1 do var test = "Use the `printf()` function." var exp = "

Use the printf() function.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_span_code2 do var test = "``There is a literal backtick (`) here.``" var exp = "

There is a literal backtick (`) here.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_span_code3 do var test = """ A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` `` """ var exp = """

A single backtick in a code span: `

A backtick-delimited string in a code span: `foo`

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_span_code4 do var test = "Please don't use any `` tags." var exp = "

Please don't use any <blink> tags.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_span_code5 do var test = "`—` is the decimal-encoded equivalent of `—`." var exp = "

&#8212; is the decimal-encoded equivalent of &mdash;.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_escape1 do var test = "\\*this text is surrounded by literal asterisks\\*" var exp = "

*this text is surrounded by literal asterisks*

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_escape2 do var test = "1986\\. What a great season." var exp = "

1986. What a great season.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_escape3 do var test = "Ben & Lux" var exp = "

Ben & Lux

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link1 do var test = """ This is [an example](http://example.com/ "Title") inline link. [This link](http://example.net/) has no title attribute. """ var exp = """

This is an example inline link.

This link has no title attribute.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link2 do var test = "See my [About](/about/) page for details." var exp = "

See my About page for details.

\n" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link3 do var test = """ This is [an example][id] reference-style link. This is [an example] [id] reference-style link. Some lorem ipsum [id]: http://example.com/ "Optional Title Here" Some other lipsum """ var exp = """

This is an example reference-style link.

This is an example reference-style link.

Some lorem ipsum

Some other lipsum

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link4 do var test = """ This is multiple examples: [foo][1], [bar][2], [baz][3]. [1]: http://example.com/ "Optional Title Here" [2]: http://example.com/ 'Optional Title Here' [3]: http://example.com/ (Optional Title Here) """ var exp = """

This is multiple examples: foo, bar, baz.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link5 do var test = """ This is multiple examples: [foo][a], [bar][A], [a]. [a]: http://example.com/ "Optional Title Here" """ var exp = """

This is multiple examples: foo, bar, a.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link6 do var test = """ I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [Google]: http://google.com/ "Google" [Yahoo]: http://search.yahoo.com/ "Yahoo Search" [MSN]: http://search.msn.com/ "MSN Search" """ var exp = """

I get 10 times more traffic from Google than from Yahoo or MSN.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link7 do var test = """ Visit [Daring Fireball][] for more information. [Daring Fireball]: http://daringfireball.net/ """ var exp = """

Visit Daring Fireball for more information.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_link8 do var test = """ This one has a [line break]. This one has a [line break] with a line-ending space. [line break]: /foo """ var exp = """

This one has a line break.

This one has a line break with a line-ending space.

""" var res = test.md_to_html.write_to_string assert res == exp end # FIXME unignore test once escape strings fixed # fun test_process_link9 do # var test = """ # Foo [bar][]. # # Foo [bar](/url/ "Title with \"quotes\" inside"). # # # [bar]: /url/ "Title with \"quotes\" inside" # """ # var exp = """ #

Foo bar.

#

Foo bar.

# """ # var res = test.md_to_html.write_to_string # assert res == exp # end fun test_process_img1 do var test = """ ![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title") """ var exp = """

Alt text

Alt text

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_img2 do var test = """ ![Alt text][id] [id]: url/to/image "Optional title attribute" """ var exp = """

Alt text

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_process_strike do var proc = new MarkdownProcessor proc.ext_mode = false var test = "This is how you ~~strike text~~" var exp = "

This is how you ~~strike text~~

\n" var res = proc.process(test).write_to_string assert exp == res end fun test_process_strike_ext do var test = "This is how you ~~strike text~~" var exp = "

This is how you strike text

\n" var res = test.md_to_html.write_to_string assert exp == res end fun test_escape_bad_html do var test = "-1 if < , +1 if > and 0 otherwise" var exp = "

-1 if < , +1 if > and 0 otherwise

\n" var res = test.md_to_html.write_to_string assert exp == res end fun test_daring_encoding do var test = """ AT&T has an ampersand in their name. AT&T is another way to write it. This & that. 4 < 5. 6 > 5. Here's a [link] [1] with an ampersand in the URL. Here's a link with an amersand in the link text: [AT&T] [2]. Here's an inline [link](/script?foo=1&bar=2). Here's an inline [link](). [1]: http://example.com/?foo=1&bar=2 [2]: http://att.com/ "AT&T" """ var exp = """

AT&T has an ampersand in their name.

AT&T is another way to write it.

This & that.

4 < 5.

6 > 5.

Here's a link with an ampersand in the URL.

Here's a link with an amersand in the link text: AT&T.

Here's an inline link.

Here's an inline link.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_autolinks do var test = """ Link: . With an ampersand: * In a list? * * It should. > Blockquoted: Auto-links should not occur here: `` or here: """ var exp = """

Link: http://example.com/.

With an ampersand: http://example.com/?foo=1&bar=2

Blockquoted: http://example.com/

Auto-links should not occur here: <http://example.com/>

or here: <http://example.com/>
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_escape do var test = """ These should all get escaped: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- These should not, because they occur within a code block: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- Nor should these, which occur in code spans: Backslash: `\\` Backtick: `` \` `` Asterisk: `\*` Underscore: `\_` Left brace: `\{` Right brace: `\}` Left bracket: `\[` Right bracket: `\]` Left paren: `\(` Right paren: `\)` Greater-than: `\>` Hash: `\#` Period: `\.` Bang: `\!` Plus: `\+` Minus: `\-` These should get escaped, even though they're matching pairs for other Markdown constructs: \\\*asterisks\\\* \\\_underscores\\\_ \\\`backticks\\\` This is a code span with a literal backslash-backtick sequence: `` \` `` This is a tag with unescaped backticks bar. This is a tag with backslashes bar. """ var exp = """

These should all get escaped:

Backslash: \\

Backtick: \`

Asterisk: \*

Underscore: \_

Left brace: \{

Right brace: \}

Left bracket: \[

Right bracket: \]

Left paren: \(

Right paren: \)

Greater-than: \>

Hash: \#

Period: \.

Bang: \!

Plus: \+

Minus: \-

These should not, because they occur within a code block:

Backslash: \\

Backtick: \`

Asterisk: \*

Underscore: \_

Left brace: \{

Right brace: \}

Left bracket: \[

Right bracket: \]

Left paren: \(

Right paren: \)

Greater-than: \>

Hash: \#

Period: \.

Bang: \!

Plus: \+

Minus: \-

Nor should these, which occur in code spans:

Backslash: \\

Backtick: \`

Asterisk: \*

Underscore: \_

Left brace: \{

Right brace: \}

Left bracket: \[

Right bracket: \]

Left paren: \(

Right paren: \)

Greater-than: \>

Hash: \#

Period: \.

Bang: \!

Plus: \+

Minus: \-

These should get escaped, even though they're matching pairs for other Markdown constructs:

*asterisks*

_underscores_

`backticks`

This is a code span with a literal backslash-backtick sequence: \`

This is a tag with unescaped backticks bar.

This is a tag with backslashes bar.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_blockquotes do var test = """ > Example: > > sub status { > print "working"; > } > > Or: > > sub status { > return "working"; > } """ var exp = """

Example:

sub status {
    print "working";
}

Or:

sub status {
    return "working";
}
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_code_blocks do var test = """ code block on the first line Regular text. code block indented by spaces Regular text. the lines in this block all contain trailing spaces Regular Text. code block on the last line """ var exp = """
code block on the first line

Regular text.

code block indented by spaces

Regular text.

the lines in this block
all contain trailing spaces

Regular Text.

code block on the last line
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_code_spans do var test = """ `` Fix for backticks within HTML tag: like this Here's how you put `` `backticks` `` in a code span. """ var exp = """

<test a=" content of attribute ">

Fix for backticks within HTML tag: like this

Here's how you put `backticks` in a code span.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_pars do var proc = new MarkdownProcessor proc.ext_mode = false var test = """ In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item. Here's one with a bullet. * criminey. """ var exp = """

In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.

Here's one with a bullet. * criminey.

""" var res = proc.process(test).write_to_string assert res == exp end fun test_daring_rules do var test = """ Dashes: --- --- --- --- --- - - - - - - - - - - - - - - - Asterisks: *** *** *** *** *** * * * * * * * * * * * * * * * Underscores: ___ ___ ___ ___ ___ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ """ var exp = """

Dashes:





---




- - -

Asterisks:





***




* * *

Underscores:





___




_ _ _
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_images do var test = """ ![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title") Inline within a paragraph: [alt text](/url/). ![alt text](/url/ "title preceded by two spaces") ![alt text](/url/ "title has spaces afterward" ) ![alt text]() ![alt text]( "with a title"). ![Empty]() ![this is a stupid URL](http://example.com/(parens).jpg) ![alt text][foo] [foo]: /url/ ![alt text][bar] [bar]: /url/ "Title here" """ var exp = """

Alt text

Alt text

Inline within a paragraph: alt text.

alt text

alt text

alt text

alt text.

Empty

this is a stupid URL

alt text

alt text

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_inline_html1 do var test = """ Here's a simple block:
foo
This should be a code block, though:
foo
As should this:
foo
Now, nested:
foo
This should just be an HTML comment: Multiline: Code block: Just plain comment, with trailing spaces on the line: Code:
Hr's:








""" var exp = """

Here's a simple block:

foo

This should be a code block, though:

<div>
    foo
</div>

As should this:

<div>foo</div>

Now, nested:

foo

This should just be an HTML comment:

Multiline:

Code block:

<!-- Comment -->

Just plain comment, with trailing spaces on the line:

Code:

<hr />

Hr's:










""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_inline_html2 do var test = """ Simple block on one line:
foo
And nested without indentation:
foo
bar
And with attributes:
This was broken in 1.0.2b7:
foo
""" var exp = """

Simple block on one line:

foo

And nested without indentation:

foo
bar

And with attributes:

This was broken in 1.0.2b7:

foo
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_inline_html3 do var test = """ Paragraph one. Paragraph two. The end. """ var exp = """

Paragraph one.

Paragraph two.

The end.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_links1 do var test = """ Just a [URL](/url/). [URL and title](/url/ "title"). [URL and title](/url/ "title preceded by two spaces"). [URL and title](/url/ "title preceded by a tab"). [URL and title](/url/ "title has spaces afterward" ). [URL wrapped in angle brackets](). [URL w/ angle brackets + title]( "Here's the title"). [Empty](). [With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing)) (With outer parens and [parens in url](/foo(bar))) [With parens in the URL](/foo(bar) "and a title") (With outer parens and [parens in url](/foo(bar) "and a title")) """ var exp = """

Just a URL.

URL and title.

URL and title.

URL and title.

URL and title.

URL wrapped in angle brackets.

URL w/ angle brackets + title.

Empty.

With parens in the URL

(With outer parens and parens in url)

With parens in the URL

(With outer parens and parens in url)

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_links2 do var test = """ Foo [bar] [1]. Foo [bar][1]. Foo [bar] [1]. [1]: /url/ "Title" With [embedded [brackets]] [b]. Indented [once][]. Indented [twice][]. Indented [thrice][]. Indented [four][] times. [once]: /url [twice]: /url [thrice]: /url [four]: /url [b]: /url/ * * * [this] [this] should work So should [this][this]. And [this] []. And [this][]. And [this]. But not [that] []. Nor [that][]. Nor [that]. [Something in brackets like [this][] should work] [Same with [this].] In this case, [this](/somethingelse/) points to something else. Backslashing should suppress \\\[this] and [this\\\]. [this]: foo * * * Here's one where the [link breaks] across lines. Here's another where the [link breaks] across lines, but with a line-ending space. [link breaks]: /url/ """ var exp = """

Foo bar.

Foo bar.

Foo bar.

With embedded [brackets].

Indented once.

Indented twice.

Indented thrice.

Indented [four][] times.

[four]: /url

this should work

So should this.

And this.

And this.

And this.

But not [that] [].

Nor [that][].

Nor [that].

[Something in brackets like this should work]

[Same with this.]

In this case, this points to something else.

Backslashing should suppress [this] and [this].


Here's one where the link breaks across lines.

Here's another where the link breaks across lines, but with a line-ending space.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_links3 do var test = """ This is the [simple case]. [simple case]: /simple This one has a [line break]. This one has a [line break] with a line-ending space. [line break]: /foo [this] [that] and the [other] [this]: /this [that]: /that [other]: /other """ var exp = """

This is the simple case.

This one has a line break.

This one has a line break with a line-ending space.

this and the other

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_nested do var test = """ > foo > > > bar > > foo """ var exp = """

foo

bar

foo

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_list do var test = """ ## Unordered Asterisks tight: * asterisk 1 * asterisk 2 * asterisk 3 Asterisks loose: * asterisk 1 * asterisk 2 * asterisk 3 * * * Pluses tight: + Plus 1 + Plus 2 + Plus 3 Pluses loose: + Plus 1 + Plus 2 + Plus 3 * * * Minuses tight: - Minus 1 - Minus 2 - Minus 3 Minuses loose: - Minus 1 - Minus 2 - Minus 3 ## Ordered Tight: 1. First 2. Second 3. Third and: 1. One 2. Two 3. Three Loose using tabs: 1. First 2. Second 3. Third and using spaces: 1. One 2. Two 3. Three Multiple paragraphs: 1. Item 1, graf one. Item 2. graf two. The quick brown fox jumped over the lazy dog's back. 2. Item 2. 3. Item 3. ## Nested * Tab * Tab * Tab Here's another: 1. First 2. Second: * Fee * Fie * Foe 3. Third Same thing but with paragraphs: 1. First 2. Second: * Fee * Fie * Foe 3. Third """ var exp = """

Unordered

Asterisks tight:

  • asterisk 1
  • asterisk 2
  • asterisk 3

Asterisks loose:

  • asterisk 1

  • asterisk 2

  • asterisk 3


Pluses tight:

  • Plus 1
  • Plus 2
  • Plus 3

Pluses loose:

  • Plus 1

  • Plus 2

  • Plus 3


Minuses tight:

  • Minus 1
  • Minus 2
  • Minus 3

Minuses loose:

  • Minus 1

  • Minus 2

  • Minus 3

Ordered

Tight:

  1. First
  2. Second
  3. Third

and:

  1. One
  2. Two
  3. Three

Loose using tabs:

  1. First

  2. Second

  3. Third

and using spaces:

  1. One

  2. Two

  3. Three

Multiple paragraphs:

  1. Item 1, graf one.

    Item 2. graf two. The quick brown fox jumped over the lazy dog's back.

  2. Item 2.

  3. Item 3.

Nested

  • Tab
    • Tab
      • Tab

Here's another:

  1. First
  2. Second:
    • Fee
    • Fie
    • Foe
  3. Third

Same thing but with paragraphs:

  1. First

  2. Second:

    • Fee
    • Fie
    • Foe
  3. Third

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_strong_em do var test = """ ***This is strong and em.*** So is ***this*** word. ___This is strong and em.___ So is ___this___ word. """ var exp = """

This is strong and em.

So is this word.

This is strong and em.

So is this word.

""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_tabs do var test = """ + this is a list item indented with tabs + this is a list item indented with spaces Code: this code block is indented by one tab And: this code block is indented by two tabs And: + this is an example list item indented with tabs + this is an example list item indented with spaces """ var exp = """
  • this is a list item indented with tabs

  • this is a list item indented with spaces

Code:

this code block is indented by one tab

And:

    this code block is indented by two tabs

And:

+   this is an example list item
    indented with tabs

+   this is an example list item
    indented with spaces
""" var res = test.md_to_html.write_to_string assert res == exp end fun test_daring_tidyness do var test = """ > A list within a blockquote: > > * asterisk 1 > * asterisk 2 > * asterisk 3 """ var exp = """

A list within a blockquote:

  • asterisk 1
  • asterisk 2
  • asterisk 3
""" var res = test.md_to_html.write_to_string assert res == exp end end class TestBlock super TestSuite # A dummy location for testing purposes. var loc = new MDLocation(0, 0, 0, 0) fun test_has_blocks do var subject = new MDBlock(loc) assert not subject.has_blocks subject.first_block = new MDBlock(loc) assert subject.has_blocks end fun test_count_blocks do var subject = new MDBlock(loc) assert subject.count_blocks == 0 subject.first_block = new MDBlock(loc) assert subject.count_blocks == 1 subject.first_block.next = new MDBlock(loc) assert subject.count_blocks == 2 end fun test_has_lines do var subject = new MDBlock(loc) assert not subject.has_lines subject.first_line = new MDLine(loc, "") assert subject.has_lines end fun test_count_lines do var subject = new MDBlock(loc) assert subject.count_lines == 0 subject.first_line = new MDLine(loc, "") assert subject.count_lines == 1 subject.first_line.next = new MDLine(loc, "") assert subject.count_lines == 2 end fun test_split do var line1 = new MDLine(loc, "line1") var line2 = new MDLine(loc, "line2") var line3 = new MDLine(loc, "line3") var subject = new MDBlock(loc) subject.add_line line1 subject.add_line line2 subject.add_line line3 var block = subject.split(line2) assert subject.count_blocks == 1 assert subject.count_lines == 1 assert subject.first_line == line3 assert block.count_blocks == 0 assert block.count_lines == 2 assert block.first_line == line1 assert block.last_line == line2 end fun test_add_line do var subject = new MDBlock(loc) assert subject.count_lines == 0 subject.add_line new MDLine(loc, "") assert subject.count_lines == 1 subject.add_line new MDLine(loc, "") assert subject.count_lines == 2 end fun test_remove_line do var line1 = new MDLine(loc, "line1") var line2 = new MDLine(loc, "line2") var line3 = new MDLine(loc, "line3") var subject = new MDBlock(loc) subject.add_line line1 subject.add_line line2 subject.add_line line3 subject.remove_line(line2) assert subject.count_lines == 2 subject.remove_line(line1) assert subject.count_lines == 1 assert subject.first_line == line3 assert subject.last_line == line3 end fun test_transform_headline1 do var subject = new MDBlock(loc) var kind = new BlockHeadline(subject) subject.add_line new MDLine(loc, " # Title 1 ") kind.transform_headline(subject) assert kind.depth == 1 assert subject.first_line.value == "Title 1" end fun test_transform_headline2 do var subject = new MDBlock(loc) var kind = new BlockHeadline(subject) subject.add_line new MDLine(loc, " #####Title 5 ") kind.transform_headline(subject) assert kind.depth == 5 assert subject.first_line.value == "Title 5" end fun test_remove_quote_prefix do var subject = new MDBlock(loc) var kind = new BlockQuote(subject) subject.add_line new MDLine(loc, " > line 1") subject.add_line new MDLine(loc, " > line 2") subject.add_line new MDLine(loc, " > line 3") kind.remove_block_quote_prefix(subject) assert subject.first_line.value == "line 1" assert subject.first_line.next.value == "line 2" assert subject.first_line.next.next.value == "line 3" end fun test_remove_leading_empty_lines_1 do var block = new MDBlock(loc) block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, " text") block.add_line new MDLine(loc, "") assert block.remove_leading_empty_lines assert block.first_line.value == " text" end fun test_remove_leading_empty_lines_2 do var block = new MDBlock(loc) block.add_line new MDLine(loc, " text") block.remove_leading_empty_lines assert block.first_line.value == " text" end fun test_remove_trailing_empty_lines_1 do var block = new MDBlock(loc) block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "text") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") assert block.remove_trailing_empty_lines assert block.last_line.value == "text" end fun test_remove_trailing_empty_lines_2 do var block = new MDBlock(loc) block.add_line new MDLine(loc, "text ") assert not block.remove_trailing_empty_lines assert block.last_line.value == "text " end fun test_remove_surrounding_empty_lines do var block = new MDBlock(loc) block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "text") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") block.add_line new MDLine(loc, "") assert block.remove_surrounding_empty_lines assert block.first_line.value == "text" assert block.last_line.value == "text" end end class TestLine super TestSuite # A dummy location for testing purposes. var loc = new MDLocation(0, 0, 0, 0) var subject: MDLine fun test_is_empty do subject = new MDLine(loc, "") assert subject.is_empty subject = new MDLine(loc, " ") assert subject.is_empty subject = new MDLine(loc, "test") assert not subject.is_empty subject = new MDLine(loc, " test") assert not subject.is_empty end fun test_leading do subject = new MDLine(loc, "") assert subject.leading == 0 subject = new MDLine(loc, " ") assert subject.leading == 4 subject = new MDLine(loc, "test") assert subject.leading == 0 subject = new MDLine(loc, " test") assert subject.leading == 4 end fun test_trailing do subject = new MDLine(loc, "") assert subject.trailing == 0 subject = new MDLine(loc, " ") assert subject.trailing == 0 subject = new MDLine(loc, "test ") assert subject.trailing == 3 subject = new MDLine(loc, " test ") assert subject.trailing == 1 end fun test_line_type do var v = new MarkdownProcessor subject = new MDLine(loc, "") assert v.line_kind(subject) isa LineEmpty subject = new MDLine(loc, " ") assert v.line_kind(subject) isa LineEmpty subject = new MDLine(loc, "text ") assert v.line_kind(subject) isa LineOther subject = new MDLine(loc, " # Title") assert v.line_kind(subject) isa LineHeadline subject = new MDLine(loc, " ### Title") assert v.line_kind(subject) isa LineHeadline subject = new MDLine(loc, " code") assert v.line_kind(subject) isa LineCode subject = new MDLine(loc, " Title ") subject.next = new MDLine(loc, "== ") assert v.line_kind(subject) isa LineHeadline1 subject = new MDLine(loc, " Title ") subject.next = new MDLine(loc, "-- ") assert v.line_kind(subject) isa LineHeadline2 subject = new MDLine(loc, " * * * ") assert v.line_kind(subject) isa LineHR subject = new MDLine(loc, " *** ") assert v.line_kind(subject) isa LineHR subject = new MDLine(loc, "- -- ") assert v.line_kind(subject) isa LineHR subject = new MDLine(loc, "--------- ") assert v.line_kind(subject) isa LineHR subject = new MDLine(loc, " >") assert v.line_kind(subject) isa LineBlockquote subject = new MDLine(loc, "

") assert v.line_kind(subject) isa LineXML subject = new MDLine(loc, "

") assert v.line_kind(subject) isa LineOther subject = new MDLine(loc, " * foo") assert v.line_kind(subject) isa LineUList subject = new MDLine(loc, "- foo") assert v.line_kind(subject) isa LineUList subject = new MDLine(loc, "+ foo") assert v.line_kind(subject) isa LineUList subject = new MDLine(loc, "1. foo") assert v.line_kind(subject) isa LineOList subject = new MDLine(loc, " 11111. foo") assert v.line_kind(subject) isa LineOList end fun test_line_type_ext do var v = new MarkdownProcessor subject = new MDLine(loc, " ~~~") assert v.line_kind(subject) isa LineFence subject = new MDLine(loc, " ```") assert v.line_kind(subject) isa LineFence subject = new MDLine(loc, "~~~raw") assert v.line_kind(subject) isa LineFence end fun test_count_chars do subject = new MDLine(loc, "") assert subject.count_chars('*') == 0 subject = new MDLine(loc, "* ") assert subject.count_chars('*') == 1 subject = new MDLine(loc, " * text") assert subject.count_chars('*') == 0 subject = new MDLine(loc, " * * *") assert subject.count_chars('*') == 3 subject = new MDLine(loc, "text ** ") assert subject.count_chars('*') == 0 end fun test_count_chars_start do subject = new MDLine(loc, "") assert subject.count_chars_start('*') == 0 subject = new MDLine(loc, "* ") assert subject.count_chars_start('*') == 1 subject = new MDLine(loc, " * text") assert subject.count_chars_start('*') == 1 subject = new MDLine(loc, " * * * text") assert subject.count_chars_start('*') == 3 subject = new MDLine(loc, "text ** ") assert subject.count_chars_start('*') == 0 end end class TestHTMLDecorator super TestSuite fun test_headlines do var test = """ # **a** ## a.a ### a.a.b ### a.a.b ## a.b # [b](test) ## b.a ### b.a.c ## b.b ## b.c # c """ var proc = new MarkdownProcessor var decorator = proc.emitter.decorator.as(HTMLDecorator) proc.process(test) var res = "" for id, headline in decorator.headlines do res += "{headline.title}:{id}\n" end var exp = """ **a**:a a.a:a.a a.a.b:a.a.b a.a.b:a.a.b_1 a.b:a.b [b](test):btest b.a:b.a b.a.c:b.a.c b.b:b.b b.c:b.c c:c """ assert res == exp end end class TestTokenLocation super TestSuite fun test_token_location1 do var string = "**Hello** `World`" var stack = [ "TokenStrongStar at 1,1--1,1", "TokenStrongStar at 1,8--1,8", "TokenCodeSingle at 1,11--1,11", "TokenCodeSingle at 1,17--1,17"] (new TestTokenProcessor(stack)).process(string) end fun test_token_location2 do var string = "**Hello**\n`World`\n*Bonjour*\n[le monde]()" var stack = [ "TokenStrongStar at 1,1--1,1", "TokenStrongStar at 1,8--1,8", "TokenCodeSingle at 2,1--2,1", "TokenCodeSingle at 2,7--2,7", "TokenEmStar at 3,1--3,1", "TokenEmStar at 3,9--3,9", "TokenLink at 4,1--4,1"] (new TestTokenProcessor(stack)).process(string) end fun test_token_location3 do var string = """**Hello** `World` *Bonjour* [le monde]()""" var stack = [ "TokenStrongStar at 1,1--1,1", "TokenStrongStar at 1,8--1,8", "TokenCodeSingle at 2,1--2,1", "TokenCodeSingle at 2,7--2,7", "TokenEmStar at 3,1--3,1", "TokenEmStar at 3,9--3,9", "TokenLink at 4,1--4,1"] (new TestTokenProcessor(stack)).process(string) end fun test_token_location4 do var string = "**Hello**\n\n`World`" var stack = [ "TokenStrongStar at 1,1--1,1", "TokenStrongStar at 1,8--1,8", "TokenCodeSingle at 3,1--3,1", "TokenCodeSingle at 3,7--3,7"] (new TestTokenProcessor(stack)).process(string) end fun test_token_location5 do var string = "# *Title1*\n\n# *Title2*" var stack = [ "TokenEmStar at 1,3--1,3", "TokenEmStar at 1,10--1,10", "TokenEmStar at 3,3--3,3", "TokenEmStar at 3,10--3,10"] (new TestTokenProcessor(stack)).process(string) end end class TestTokenProcessor super MarkdownProcessor var test_stack: Array[String] redef fun token_at(input, pos) do var token = super if token isa TokenNone then return token var res = "{token.class_name} at {token.location}" var exp = test_stack.shift print "" print "EXP {exp}" print "RES {res}" assert exp == res return token end end class TestBlockLocation super TestSuite var proc = new MarkdownProcessor fun test_block_location1 do var stack = [ "BlockHeadline: 1,1--1,8", "BlockListItem: 2,1--2,6", "BlockListItem: 3,1--3,5" ] var string = "# Title\n* li1\n* li2" proc.emitter.decorator = new TestBlockDecorator(stack) proc.process(string) end fun test_block_location2 do var stack = [ "BlockHeadline: 1,1--1,11", "BlockFence: 3,1--5,4", "BlockListItem: 7,1--7,7", "BlockListItem: 8,1--8,6"] var string ="""#### Title ~~~fence some code ~~~ 1. li1 1. li2""" proc.emitter.decorator = new TestBlockDecorator(stack) proc.process(string) end fun test_block_location3 do var stack = [ "BlockHeadline: 1,1--1,8", "BlockHeadline: 3,1--3,10"] var string ="""# Title\n\n## Title 2""" proc.emitter.decorator = new TestBlockDecorator(stack) proc.process(string) end end class TestBlockDecorator super HTMLDecorator var stack: Array[String] redef fun add_headline(v, block) do super check_res(block) end redef fun add_listitem(v, block) do super check_res(block) end redef fun add_blockquote(v, block) do super check_res(block) end redef fun add_code(v, block) do super check_res(block) end fun check_res(block: Block) do var res = "{block.class_name}: {block.block.location}" var exp = stack.shift assert res == exp end end