lib/markdown: merge processor and emitter
[nit.git] / lib / markdown / test_markdown.nit
index a8d3b9f..b08f5b4 100644 (file)
 # limitations under the License.
 
 # Test suites for module `markdown`
-module test_markdown is test_suite
+module test_markdown is test
 
-import test_suite
 intrude import markdown
 
 class TestMarkdownProcessor
-       super TestSuite
+       test
 
-       fun test_process_empty do
+       fun test_process_empty is test do
                var test = ""
                var exp = ""
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_tabs do
+       fun test_process_tabs is test do
                var test = """
        some code
 """
@@ -40,14 +39,14 @@ class TestMarkdownProcessor
        end
 
 
-       fun test_process_par1 do
+       fun test_process_par1 is test do
                var test = "test"
                var exp = "<p>test</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_par2 do
+       fun test_process_par2 is test do
                var test = """
 line1
 line2
@@ -65,7 +64,7 @@ line2</p>
                assert res == exp
        end
 
-       fun test_process_par3 do
+       fun test_process_par3 is test do
                var test = """
 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
 Aliquam hendrerit mi posuere lectus.
@@ -85,7 +84,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_headings_1 do
+       fun test_process_headings_1 is test do
                var test = """
 This is a H1
 =============
@@ -101,7 +100,7 @@ This is a H2
                assert res == exp
        end
 
-       fun test_process_headings_2 do
+       fun test_process_headings_2 is test do
                var test = """
 # This is a H1
 
@@ -117,7 +116,7 @@ This is a H2
                assert res == exp
        end
 
-       fun test_process_headings_3 do
+       fun test_process_headings_3 is test do
                var test = """
 # This is a H1 #
 
@@ -134,7 +133,7 @@ This is a H2
                assert res == exp
        end
 
-       fun test_process_hr do
+       fun test_process_hr is test do
                var test = """
 * * *
 
@@ -151,7 +150,7 @@ This is a H2
                assert res == exp
        end
 
-       fun test_process_bquote1 do
+       fun test_process_bquote1 is test do
                var test = """
 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
 > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
@@ -172,7 +171,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_bquote2 do
+       fun test_process_bquote2 is test do
                var test = """
 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
@@ -193,7 +192,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_bquote3 do
+       fun test_process_bquote3 is test do
                var test = """
 > This is the first level of quoting.
 >
@@ -213,7 +212,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list1 do
+       fun test_process_list1 is test do
                var test = """
 *   Red
 *   Green
@@ -229,7 +228,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list2 do
+       fun test_process_list2 is test do
                var test = """
 +   Red
 +   Green
@@ -245,7 +244,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list3 do
+       fun test_process_list3 is test do
                var test = """
 -   Red
 -   Green
@@ -261,7 +260,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list4 do
+       fun test_process_list4 is test do
                var test = """
 1.  Bird
 2.  McHale
@@ -277,7 +276,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list5 do
+       fun test_process_list5 is test do
                var test = """
 3. Bird
 1. McHale
@@ -293,7 +292,7 @@ id sem consectetuer libero luctus adipiscing.</p>
                assert res == exp
        end
 
-       fun test_process_list6 do
+       fun test_process_list6 is test do
                var test = """
 *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
     Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
@@ -314,7 +313,7 @@ Suspendisse id sem consectetuer libero luctus adipiscing.</li>
                assert res == exp
        end
 
-       fun test_process_list7 do
+       fun test_process_list7 is test do
                var test = """
 *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
@@ -335,7 +334,7 @@ Suspendisse id sem consectetuer libero luctus adipiscing.</li>
                assert res == exp
        end
 
-       fun test_process_list8 do
+       fun test_process_list8 is test do
                var test = """
 *   Bird
 
@@ -353,7 +352,7 @@ Suspendisse id sem consectetuer libero luctus adipiscing.</li>
                assert res == exp
        end
 
-       fun test_process_list9 do
+       fun test_process_list9 is test do
                var test = """
 1.  This is a list item with two paragraphs. Lorem ipsum dolor
     sit amet, consectetuer adipiscing elit. Aliquam hendrerit
@@ -382,7 +381,7 @@ sit amet velit.</p>
                assert res == exp
        end
 
-       fun test_process_list10 do
+       fun test_process_list10 is test do
                var test = """
 *   This is a list item with two paragraphs.
 
@@ -407,7 +406,7 @@ sit amet, consectetuer adipiscing elit.</p>
                assert res == exp
        end
 
-       fun test_process_list11 do
+       fun test_process_list11 is test do
                var test = """
 This is a paragraph
 * and this is not a list
@@ -422,7 +421,7 @@ This is a paragraph
                assert res == exp
        end
 
-       fun test_process_list_ext do
+       fun test_process_list_ext is test do
                var test = """
 This is a paragraph
 * and this is not a list
@@ -437,7 +436,7 @@ This is a paragraph
                assert res == exp
        end
 
-       fun test_process_code1 do
+       fun test_process_code1 is test do
                var test = """
 This is a normal paragraph:
 
@@ -451,7 +450,7 @@ This is a normal paragraph:
                assert res == exp
        end
 
-       fun test_process_code2 do
+       fun test_process_code2 is test do
                var test = """
 Here is an example of AppleScript:
 
@@ -478,7 +477,7 @@ end tell
                assert res == exp
        end
 
-       fun test_process_code_ext1 do
+       fun test_process_code_ext1 is test do
                var test = """
 Here is an example of AppleScript:
 ~~~
@@ -506,7 +505,7 @@ end tell
                assert res == exp
        end
 
-       fun test_process_code_ext2 do
+       fun test_process_code_ext2 is test do
                var test = """
 Here is an example of AppleScript:
 ```
@@ -534,7 +533,7 @@ end tell
                assert res == exp
        end
 
-       fun test_process_code_ext3 do
+       fun test_process_code_ext3 is test do
                var proc = new MarkdownProcessor
                proc.ext_mode = false
 
@@ -550,7 +549,7 @@ beep</p>
                assert res == exp
        end
 
-       fun test_process_code_ext4 do
+       fun test_process_code_ext4 is test do
                var test = """
 Here is an example of AppleScript:
     beep
@@ -564,7 +563,7 @@ Here is an example of AppleScript:
                assert res == exp
        end
 
-       fun test_process_code_ext5 do
+       fun test_process_code_ext5 is test do
                var test = """
 ```nit
 print "Hello World!"
@@ -578,7 +577,45 @@ print "Hello World!"
                assert res == exp
        end
 
-       fun test_process_nesting1 do
+       fun test_process_code_ext6 is test do
+               var test = """
+~~~
+print "Hello"
+~~~
+~~~
+print "World"
+~~~
+"""
+               var exp = """
+<pre><code>print "Hello"
+</code></pre>
+<pre><code>print "World"
+</code></pre>
+"""
+               var res = test.md_to_html.write_to_string
+               assert res == exp
+       end
+
+       fun test_process_code_ext7 is test do
+               var test = """
+~~~
+print "Hello"
+~~~
+~~~
+print "World"
+~~~
+"""
+               var exp = """
+<pre><code>print "Hello"
+</code></pre>
+<pre><code>print "World"
+</code></pre>
+"""
+               var res = test.md_to_html.write_to_string
+               assert res == exp
+       end
+
+       fun test_process_nesting1 is test do
                var test = """
 > ## This is a header.
 >
@@ -605,7 +642,7 @@ print "Hello World!"
                assert res == exp
        end
 
-       fun test_process_nesting2 do
+       fun test_process_nesting2 is test do
                var test = """
 *   A list item with a blockquote:
 
@@ -626,7 +663,7 @@ inside a list item.</p>
                assert res == exp
        end
 
-       fun test_process_nesting3 do
+       fun test_process_nesting3 is test do
                var test = """
 *   A list item with a code block:
 
@@ -644,7 +681,7 @@ inside a list item.</p>
                assert res == exp
        end
 
-       fun test_process_nesting4 do
+       fun test_process_nesting4 is test do
                var test = """
 *      Tab
        *       Tab
@@ -666,7 +703,7 @@ inside a list item.</p>
        end
 
        # TODO
-       #       fun test_process_nesting5 do
+       #       fun test_process_nesting5 is test do
        #               var test = """
        # *     this
        #
@@ -688,7 +725,7 @@ inside a list item.</p>
        #               assert res == exp
        #       end
 
-       fun test_process_emph1 do
+       fun test_process_emph1 is test do
                var test = """
 *single asterisks*
 
@@ -707,14 +744,14 @@ __double underscores__
                assert res == exp
        end
 
-       fun test_process_emph2 do
+       fun test_process_emph2 is test do
                var test = "un*frigging*believable"
                var exp = "<p>un<em>frigging</em>believable</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_emph3 do
+       fun test_process_emph3 is test do
                var proc = new MarkdownProcessor
                proc.ext_mode = false
                var test = "Con_cat_this"
@@ -723,14 +760,14 @@ __double underscores__
                assert res == exp
        end
 
-       fun test_process_emph_ext do
+       fun test_process_emph_ext is test do
                var test = "Con_cat_this"
                var exp = "<p>Con_cat_this</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_xml1 do
+       fun test_process_xml1 is test do
                var test = """
 This is a regular paragraph.
 
@@ -755,7 +792,7 @@ This is another regular paragraph.
                assert res == exp
        end
 
-       fun test_process_xml2 do
+       fun test_process_xml2 is test do
                var test = """
 This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
 """
@@ -765,7 +802,7 @@ This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
                assert res == exp
        end
 
-       fun test_process_xml3 do
+       fun test_process_xml3 is test do
                var test = """
 <div style=">"/>
 """
@@ -776,21 +813,51 @@ This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
                assert res == exp
        end
 
-       fun test_process_span_code1 do
+       fun test_process_xml4 is test do
+               var test = """
+<p>This is an example of a block element that should be escaped.</p>
+<p>Idem for the second paragraph.</p>
+"""
+               var exp = test
+               var res = test.md_to_html.write_to_string
+               assert res == exp
+       end
+
+       fun test_process_xml5 is test do
+               var test = """
+# Some more XML tests
+
+<p>This is an example of a block element that should be escaped.</p>
+<p>Idem for the second paragraph.</p>
+
+With a *md paragraph*!
+"""
+               var exp = """
+<h1 id="Some_more_XML_tests">Some more XML tests</h1>
+<p>This is an example of a block element that should be escaped.</p>
+<p>Idem for the second paragraph.</p>
+<p>With a <em>md paragraph</em>!</p>
+"""
+               var res = test.md_to_html.write_to_string
+               print res
+               assert res == exp
+       end
+
+       fun test_process_span_code1 is test do
                var test = "Use the `printf()` function."
                var exp = "<p>Use the <code>printf()</code> function.</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_span_code2 do
+       fun test_process_span_code2 is test do
                var test = "``There is a literal backtick (`) here.``"
                var exp = "<p><code>There is a literal backtick (`) here.</code></p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_span_code3 do
+       fun test_process_span_code3 is test do
                var test = """
 A single backtick in a code span: `` ` ``
 
@@ -804,42 +871,42 @@ A backtick-delimited string in a code span: `` `foo` ``
                assert res == exp
        end
 
-       fun test_process_span_code4 do
+       fun test_process_span_code4 is test do
                var test = "Please don't use any `<blink>` tags."
                var exp = "<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_span_code5 do
+       fun test_process_span_code5 is test do
                var test = "`&#8212;` is the decimal-encoded equivalent of `&mdash;`."
                var exp = "<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_escape1 do
+       fun test_process_escape1 is test do
                var test = "\\*this text is surrounded by literal asterisks\\*"
                var exp = "<p>*this text is surrounded by literal asterisks*</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_escape2 do
+       fun test_process_escape2 is test do
                var test = "1986\\. What a great season."
                var exp = "<p>1986. What a great season.</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_escape3 do
+       fun test_process_escape3 is test do
                var test = "Ben & Lux"
                var exp = "<p>Ben &amp; Lux</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_link1 do
+       fun test_process_link1 is test do
                var test = """
 This is [an example](http://example.com/ "Title") inline link.
 
@@ -852,14 +919,14 @@ This is [an example](http://example.com/ "Title") inline link.
                assert res == exp
        end
 
-       fun test_process_link2 do
+       fun test_process_link2 is test do
                var test = "See my [About](/about/) page for details."
                var exp = "<p>See my <a href=\"/about/\">About</a> page for details.</p>\n"
                var res = test.md_to_html.write_to_string
                assert res == exp
        end
 
-       fun test_process_link3 do
+       fun test_process_link3 is test do
                var test = """
 This is [an example][id] reference-style link.
 
@@ -881,7 +948,7 @@ Some other lipsum
                assert res == exp
        end
 
-       fun test_process_link4 do
+       fun test_process_link4 is test do
                var test = """
 This is multiple examples: [foo][1], [bar][2], [baz][3].
 
@@ -896,7 +963,7 @@ This is multiple examples: [foo][1], [bar][2], [baz][3].
                assert res == exp
        end
 
-       fun test_process_link5 do
+       fun test_process_link5 is test do
                var test = """
 This is multiple examples: [foo][a], [bar][A], [a].
 
@@ -908,7 +975,7 @@ This is multiple examples: [foo][a], [bar][A], [a].
                assert res == exp
        end
 
-       fun test_process_link6 do
+       fun test_process_link6 is test do
                var test = """
 I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
 
@@ -922,7 +989,7 @@ I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
                assert res == exp
        end
 
-       fun test_process_link7 do
+       fun test_process_link7 is test do
                var test = """
 Visit [Daring Fireball][] for more information.
 
@@ -934,7 +1001,7 @@ Visit [Daring Fireball][] for more information.
                assert res == exp
        end
 
-       fun test_process_link8 do
+       fun test_process_link8 is test do
                var test = """
 This one has a [line
 break].
@@ -955,7 +1022,7 @@ break</a> with a line-ending space.</p>
        end
 
        # FIXME unignore test once escape strings fixed
-       #       fun test_process_link9 do
+       #       fun test_process_link9 is test do
        #               var test = """
        # Foo [bar][].
        #
@@ -972,7 +1039,7 @@ break</a> with a line-ending space.</p>
        #               assert res == exp
        #       end
 
-       fun test_process_img1 do
+       fun test_process_img1 is test do
                var test = """
 ![Alt text](/path/to/img.jpg)
 
@@ -985,7 +1052,7 @@ break</a> with a line-ending space.</p>
                assert res == exp
        end
 
-       fun test_process_img2 do
+       fun test_process_img2 is test do
                var test = """
 ![Alt text][id]
 
@@ -997,7 +1064,7 @@ break</a> with a line-ending space.</p>
                assert res == exp
        end
 
-       fun test_process_strike do
+       fun test_process_strike is test do
                var proc = new MarkdownProcessor
                proc.ext_mode = false
                var test = "This is how you ~~strike text~~"
@@ -1006,15 +1073,21 @@ break</a> with a line-ending space.</p>
                assert exp == res
        end
 
-       fun test_process_strike_ext do
+       fun test_process_strike_ext is test do
                var test = "This is how you ~~strike text~~"
                var exp = "<p>This is how you <del>strike text</del></p>\n"
                var res = test.md_to_html.write_to_string
                assert exp == res
        end
 
+       fun test_escape_bad_html is test do
+                       var test = "-1 if < , +1 if > and 0 otherwise"
+                       var exp = "<p>-1 if &lt; , +1 if > and 0 otherwise</p>\n"
+               var res = test.md_to_html.write_to_string
+               assert exp == res
+       end
 
-       fun test_daring_encoding do
+       fun test_daring_encoding is test do
                var test = """
 AT&T has an ampersand in their name.
 
@@ -1055,7 +1128,7 @@ Here's an inline [link](</script?foo=1&bar=2>).
 
        end
 
-       fun test_daring_autolinks do
+       fun test_daring_autolinks is test do
                var test = """
 Link: <http://example.com/>.
 
@@ -1091,7 +1164,7 @@ Auto-links should not occur here: `<http://example.com/>`
                assert res == exp
        end
 
-       fun test_daring_escape do
+       fun test_daring_escape is test do
                var test = """
 These should all get escaped:
 
@@ -1293,7 +1366,7 @@ other Markdown constructs:</p>
                assert res == exp
        end
 
-       fun test_daring_blockquotes do
+       fun test_daring_blockquotes is test do
                var test = """
 > Example:
 >
@@ -1326,7 +1399,7 @@ other Markdown constructs:</p>
                assert res == exp
        end
 
-       fun test_daring_code_blocks do
+       fun test_daring_code_blocks is test do
                var test = """
        code block on the first line
 
@@ -1362,7 +1435,7 @@ all contain trailing spaces
                assert res == exp
        end
 
-       fun test_daring_code_spans do
+       fun test_daring_code_spans is test do
                var test = """
 `<test a="` content of attribute `">`
 
@@ -1380,7 +1453,7 @@ Here's how you put `` `backticks` `` in a code span.
                assert res == exp
        end
 
-       fun test_daring_pars do
+       fun test_daring_pars is test do
                var proc = new MarkdownProcessor
                proc.ext_mode = false
 
@@ -1408,7 +1481,7 @@ list item.</p>
                assert res == exp
        end
 
-       fun test_daring_rules do
+       fun test_daring_rules is test do
                var test = """
 Dashes:
 
@@ -1524,7 +1597,7 @@ _ _ _
                assert res == exp
        end
 
-       fun test_daring_images do
+       fun test_daring_images is test do
                var test = """
 ![Alt text](/path/to/img.jpg)
 
@@ -1571,7 +1644,7 @@ Inline within a paragraph: [alt text](/url/).
                assert res == exp
        end
 
-       fun test_daring_inline_html1 do
+       fun test_daring_inline_html1 is test do
                var test = """
 Here's a simple block:
 
@@ -1694,7 +1767,7 @@ Blah
                assert res == exp
        end
 
-       fun test_daring_inline_html2 do
+       fun test_daring_inline_html2 is test do
                var test = """
 Simple block on one line:
 
@@ -1757,7 +1830,7 @@ foo
                assert res == exp
        end
 
-       fun test_daring_inline_html3 do
+       fun test_daring_inline_html3 is test do
                var test = """
 Paragraph one.
 
@@ -1788,7 +1861,7 @@ The end.
                assert res == exp
        end
 
-       fun test_daring_links1 do
+       fun test_daring_links1 is test do
                var test = """
 Just a [URL](/url/).
 
@@ -1834,7 +1907,7 @@ Just a [URL](/url/).
                assert res == exp
        end
 
-       fun test_daring_links2 do
+       fun test_daring_links2 is test do
                var test = """
 Foo [bar] [1].
 
@@ -1943,7 +2016,7 @@ breaks</a> across lines, but with a line-ending space.</p>
                assert res == exp
        end
 
-       fun test_daring_links3 do
+       fun test_daring_links3 is test do
                var test = """
 This is the [simple case].
 
@@ -1979,7 +2052,7 @@ break</a> with a line-ending space.</p>
                assert res == exp
        end
 
-       fun test_daring_nested do
+       fun test_daring_nested is test do
                var test = """
 > foo
 >
@@ -2001,7 +2074,7 @@ break</a> with a line-ending space.</p>
                assert res == exp
        end
 
-       fun test_daring_list do
+       fun test_daring_list is test do
                var test = """
 ## Unordered
 
@@ -2258,7 +2331,7 @@ back.</p>
                assert res == exp
        end
 
-       fun test_daring_strong_em do
+       fun test_daring_strong_em is test do
                var test = """
 ***This is strong and em.***
 
@@ -2279,7 +2352,7 @@ So is ___this___ word.
                assert res == exp
        end
 
-       fun test_daring_tabs do
+       fun test_daring_tabs is test do
                var test = """
 +      this is a list item
        indented with tabs
@@ -2331,7 +2404,7 @@ indented with spaces</p>
                assert res == exp
        end
 
-       fun test_daring_tidyness do
+       fun test_daring_tidyness is test do
                var test = """
 > A list within a blockquote:
 >
@@ -2358,45 +2431,48 @@ indented with spaces</p>
 end
 
 class TestBlock
-       super TestSuite
+       test
+
+       # A dummy location for testing purposes.
+       var loc = new MDLocation(0, 0, 0, 0)
 
-       fun test_has_blocks do
-               var subject = new MDBlock
+       fun test_has_blocks is test do
+               var subject = new MDBlock(loc)
                assert not subject.has_blocks
-               subject.first_block = new MDBlock
+               subject.first_block = new MDBlock(loc)
                assert subject.has_blocks
        end
 
-       fun test_count_blocks do
-               var subject = new MDBlock
+       fun test_count_blocks is test do
+               var subject = new MDBlock(loc)
                assert subject.count_blocks == 0
-               subject.first_block = new MDBlock
+               subject.first_block = new MDBlock(loc)
                assert subject.count_blocks == 1
-               subject.first_block.next = new MDBlock
+               subject.first_block.next = new MDBlock(loc)
                assert subject.count_blocks == 2
        end
 
-       fun test_has_lines do
-               var subject = new MDBlock
+       fun test_has_lines is test do
+               var subject = new MDBlock(loc)
                assert not subject.has_lines
-               subject.first_line = new MDLine("")
+               subject.first_line = new MDLine(loc, "")
                assert subject.has_lines
        end
 
-       fun test_count_lines do
-               var subject = new MDBlock
+       fun test_count_lines is test do
+               var subject = new MDBlock(loc)
                assert subject.count_lines == 0
-               subject.first_line = new MDLine("")
+               subject.first_line = new MDLine(loc, "")
                assert subject.count_lines == 1
-               subject.first_line.next = new MDLine("")
+               subject.first_line.next = new MDLine(loc, "")
                assert subject.count_lines == 2
        end
 
-       fun test_split do
-               var line1 = new MDLine("line1")
-               var line2 = new MDLine("line2")
-               var line3 = new MDLine("line3")
-               var subject = new MDBlock
+       fun test_split is test 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
@@ -2410,20 +2486,20 @@ class TestBlock
                assert block.last_line == line2
        end
 
-       fun test_add_line do
-               var subject = new MDBlock
+       fun test_add_line is test do
+               var subject = new MDBlock(loc)
                assert subject.count_lines == 0
-               subject.add_line new MDLine("")
+               subject.add_line new MDLine(loc, "")
                assert subject.count_lines == 1
-               subject.add_line new MDLine("")
+               subject.add_line new MDLine(loc, "")
                assert subject.count_lines == 2
        end
 
-       fun test_remove_line do
-               var line1 = new MDLine("line1")
-               var line2 = new MDLine("line2")
-               var line3 = new MDLine("line3")
-               var subject = new MDBlock
+       fun test_remove_line is test 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
@@ -2435,82 +2511,82 @@ class TestBlock
                assert subject.last_line == line3
        end
 
-       fun test_transform_headline1 do
-               var subject = new MDBlock
+       fun test_transform_headline1 is test do
+               var subject = new MDBlock(loc)
                var kind = new BlockHeadline(subject)
-               subject.add_line new MDLine(" #   Title 1   ")
+               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
+       fun test_transform_headline2 is test do
+               var subject = new MDBlock(loc)
                var kind = new BlockHeadline(subject)
-               subject.add_line new MDLine(" #####Title 5   ")
+               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
+       fun test_remove_quote_prefix is test do
+               var subject = new MDBlock(loc)
                var kind = new BlockQuote(subject)
-               subject.add_line new MDLine(" > line 1")
-               subject.add_line new MDLine(" > line 2")
-               subject.add_line new MDLine(" > line 3")
+               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
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("   text")
-               block.add_line new MDLine("")
+       fun test_remove_leading_empty_lines_1 is test 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
-               block.add_line new MDLine("   text")
+       fun test_remove_leading_empty_lines_2 is test 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
-               block.add_line new MDLine("")
-               block.add_line new MDLine("text")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
+       fun test_remove_trailing_empty_lines_1 is test 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
-               block.add_line new MDLine("text  ")
+       fun test_remove_trailing_empty_lines_2 is test 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
-               block.add_line new MDLine("")
-               block.add_line new MDLine("text")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
-               block.add_line new MDLine("")
+       fun test_remove_surrounding_empty_lines is test 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"
@@ -2518,130 +2594,133 @@ class TestBlock
 end
 
 class TestLine
-       super TestSuite
+       test
 
-       var subject: MDLine
+       # A dummy location for testing purposes.
+       var loc = new MDLocation(0, 0, 0, 0)
 
-       init do end
+       var subject: MDLine
 
-       fun test_is_empty do
-               subject = new MDLine("")
+       fun test_is_empty is test do
+               subject = new MDLine(loc, "")
                assert subject.is_empty
-               subject = new MDLine("    ")
+               subject = new MDLine(loc, "    ")
                assert subject.is_empty
-               subject = new MDLine("test")
+               subject = new MDLine(loc, "test")
                assert not subject.is_empty
-               subject = new MDLine("    test")
+               subject = new MDLine(loc, "    test")
                assert not subject.is_empty
        end
 
-       fun test_leading do
-               subject = new MDLine("")
+       fun test_leading is test do
+               subject = new MDLine(loc, "")
                assert subject.leading == 0
-               subject = new MDLine("    ")
+               subject = new MDLine(loc, "    ")
                assert subject.leading == 4
-               subject = new MDLine("test")
+               subject = new MDLine(loc, "test")
                assert subject.leading == 0
-               subject = new MDLine("    test")
+               subject = new MDLine(loc, "    test")
                assert subject.leading == 4
        end
 
-       fun test_trailing do
-               subject = new MDLine("")
+       fun test_trailing is test do
+               subject = new MDLine(loc, "")
                assert subject.trailing == 0
-               subject = new MDLine("    ")
+               subject = new MDLine(loc, "    ")
                assert subject.trailing == 0
-               subject = new MDLine("test   ")
+               subject = new MDLine(loc, "test   ")
                assert subject.trailing == 3
-               subject = new MDLine("    test ")
+               subject = new MDLine(loc, "    test ")
                assert subject.trailing == 1
        end
 
-       fun test_line_type do
+       fun test_line_type is test do
                var v = new MarkdownProcessor
-               subject = new MDLine("")
+               subject = new MDLine(loc, "")
                assert v.line_kind(subject) isa LineEmpty
-               subject = new MDLine("    ")
+               subject = new MDLine(loc, "    ")
                assert v.line_kind(subject) isa LineEmpty
-               subject = new MDLine("text   ")
+               subject = new MDLine(loc, "text   ")
                assert v.line_kind(subject) isa LineOther
-               subject = new MDLine("  # Title")
+               subject = new MDLine(loc, "  # Title")
                assert v.line_kind(subject) isa LineHeadline
-               subject = new MDLine("  ### Title")
+               subject = new MDLine(loc, "  ### Title")
                assert v.line_kind(subject) isa LineHeadline
-               subject = new MDLine("    code")
+               subject = new MDLine(loc, "    code")
                assert v.line_kind(subject) isa LineCode
-               subject = new MDLine("   Title  ")
-               subject.next = new MDLine("== ")
+               subject = new MDLine(loc, "   Title  ")
+               subject.next = new MDLine(loc, "== ")
                assert v.line_kind(subject) isa LineHeadline1
-               subject = new MDLine("   Title  ")
-               subject.next = new MDLine("-- ")
+               subject = new MDLine(loc, "   Title  ")
+               subject.next = new MDLine(loc, "-- ")
                assert v.line_kind(subject) isa LineHeadline2
-               subject = new MDLine("  *    *   * ")
+               subject = new MDLine(loc, "  *    *   * ")
                assert v.line_kind(subject) isa LineHR
-               subject = new MDLine("  *** ")
+               subject = new MDLine(loc, "  *** ")
                assert v.line_kind(subject) isa LineHR
-               subject = new MDLine("- -- ")
+               subject = new MDLine(loc, "- -- ")
                assert v.line_kind(subject) isa LineHR
-               subject = new MDLine("--------- ")
+               subject = new MDLine(loc, "--------- ")
                assert v.line_kind(subject) isa LineHR
-               subject = new MDLine(" >")
+               subject = new MDLine(loc, " >")
                assert v.line_kind(subject) isa LineBlockquote
-               subject = new MDLine("<p></p>")
+               subject = new MDLine(loc, "<p></p>")
                assert v.line_kind(subject) isa LineXML
-               subject = new MDLine("<p>")
+               subject = new MDLine(loc, "<p>")
                assert v.line_kind(subject) isa LineOther
-               subject = new MDLine("  * foo")
+               subject = new MDLine(loc, "  * foo")
                assert v.line_kind(subject) isa LineUList
-               subject = new MDLine("- foo")
+               subject = new MDLine(loc, "- foo")
                assert v.line_kind(subject) isa LineUList
-               subject = new MDLine("+ foo")
+               subject = new MDLine(loc, "+ foo")
                assert v.line_kind(subject) isa LineUList
-               subject = new MDLine("1. foo")
+               subject = new MDLine(loc, "1. foo")
                assert v.line_kind(subject) isa LineOList
-               subject = new MDLine("   11111. foo")
+               subject = new MDLine(loc, "   11111. foo")
                assert v.line_kind(subject) isa LineOList
        end
 
-       fun test_line_type_ext do
+       fun test_line_type_ext is test do
                var v = new MarkdownProcessor
-               subject = new MDLine("  ~~~")
+               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("  ```")
+               subject = new MDLine(loc, "~~~raw")
                assert v.line_kind(subject) isa LineFence
        end
 
-       fun test_count_chars do
-               subject = new MDLine("")
+       fun test_count_chars is test do
+               subject = new MDLine(loc, "")
                assert subject.count_chars('*') == 0
-               subject = new MDLine("* ")
+               subject = new MDLine(loc, "* ")
                assert subject.count_chars('*') == 1
-               subject = new MDLine(" * text")
+               subject = new MDLine(loc, " * text")
                assert subject.count_chars('*') == 0
-               subject = new MDLine(" *    *    *")
+               subject = new MDLine(loc, " *    *    *")
                assert subject.count_chars('*') == 3
-               subject = new MDLine("text ** ")
+               subject = new MDLine(loc, "text ** ")
                assert subject.count_chars('*') == 0
        end
 
-       fun test_count_chars_start do
-               subject = new MDLine("")
+       fun test_count_chars_start is test do
+               subject = new MDLine(loc, "")
                assert subject.count_chars_start('*') == 0
-               subject = new MDLine("* ")
+               subject = new MDLine(loc, "* ")
                assert subject.count_chars_start('*') == 1
-               subject = new MDLine(" * text")
+               subject = new MDLine(loc, " * text")
                assert subject.count_chars_start('*') == 1
-               subject = new MDLine(" *    *    * text")
+               subject = new MDLine(loc, " *    *    * text")
                assert subject.count_chars_start('*') == 3
-               subject = new MDLine("text ** ")
+               subject = new MDLine(loc, "text ** ")
                assert subject.count_chars_start('*') == 0
        end
 end
 
 class TestHTMLDecorator
-       super TestSuite
+       test
 
-       fun test_headlines do
+       fun test_headlines is test do
                var test = """
 # **a**
 ## a.a
@@ -2656,7 +2735,7 @@ class TestHTMLDecorator
 # c
 """
                var proc = new MarkdownProcessor
-               var decorator = proc.emitter.decorator.as(HTMLDecorator)
+               var decorator = proc.decorator.as(HTMLDecorator)
                proc.process(test)
                var res = ""
                for id, headline in decorator.headlines do
@@ -2678,3 +2757,161 @@ c:c
                assert res == exp
        end
 end
+
+class TestTokenLocation
+       test
+
+       fun test_token_location1 is test 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 is test 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 is test 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 is test 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 is test 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 or else "?"}"
+               var exp = test_stack.shift
+               print ""
+               print "EXP {exp}"
+               print "RES {res}"
+               assert exp == res
+               return token
+       end
+end
+
+class TestBlockLocation
+       test
+
+       var proc = new MarkdownProcessor
+
+       fun test_block_location1 is test 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.decorator = new TestBlockDecorator(stack)
+               proc.process(string)
+       end
+
+       fun test_block_location2 is test 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.decorator = new TestBlockDecorator(stack)
+               proc.process(string)
+       end
+
+       fun test_block_location3 is test do
+               var stack = [
+                       "BlockHeadline: 1,1--1,8",
+                       "BlockHeadline: 3,1--3,10"]
+               var string ="""# Title\n\n## Title 2"""
+               proc.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