Back to index

moin  1.9.0~rc2
test_text_creole.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - MoinMoin.parser.text_creole Tests
00004 
00005     TODO: these are actually parser+formatter tests. We should have
00006     parser only tests here.
00007 
00008     @copyright: 2003-2004 by Juergen Hermann <jh@web.de>
00009     @license: GNU GPL, see COPYING for details.
00010 """
00011 
00012 import re
00013 from StringIO import StringIO
00014 
00015 import py
00016 
00017 from MoinMoin.Page import Page
00018 from MoinMoin.parser.text_creole import Parser as CreoleParser
00019 from MoinMoin.formatter.text_html import Formatter as HtmlFormatter
00020 
00021 PAGENAME = u'ThisPageDoesNotExistsAndWillNeverBeReally'
00022 
00023 class ParserTestCase(object):
00024     """ Helper class that provide a parsing method """
00025 
00026     def parse(self, body):
00027         """Parse body and return html
00028 
00029         Create a page with body, then parse it and format using html formatter
00030         """
00031         request = self.request
00032         assert body is not None
00033         request.reset()
00034         page = Page(request, PAGENAME)
00035         page.hilite_re = None
00036         page.set_raw_body(body)
00037         formatter = HtmlFormatter(request)
00038         formatter.setPage(page)
00039         page.formatter = formatter
00040         request.formatter = formatter
00041         request.page = page
00042         parser = CreoleParser(body, request, line_anchors=False)
00043         formatter.startContent('') # needed for _include_stack init
00044         output = request.redirectedOutput(parser.format, formatter)
00045         formatter.endContent('')
00046         return output
00047 
00048 
00049 class TestParagraphs(ParserTestCase):
00050     """ Test paragraphs creating
00051 
00052     All tests ignoring white space in output.
00053     We do not test for </p> as it is not there currently.
00054     """
00055 
00056     def testFirstParagraph(self):
00057         """ parser.wiki: first paragraph should be in <p> """
00058         result = self.parse('First')
00059         assert re.search(r'<p.*?>\s*First\s*', result)
00060 
00061     def testEmptyLineBetweenParagraphs(self):
00062         """ parser.wiki: empty line separates paragraphs """
00063         result = self.parse('First\n\nSecond')
00064         assert re.search(r'<p.*?>\s*Second\s*', result)
00065 
00066     def testParagraphAfterBlockMarkup(self):
00067         """ parser.wiki: create paragraph after block markup """
00068 
00069         markup = (
00070             '----\n',
00071             '| table |\n',
00072             '= heading 1 =\n',
00073             '== heading 2 ==\n',
00074             '=== heading 3 ===\n',
00075             '==== heading 4 ====\n',
00076             '===== heading 5 =====\n',
00077             )
00078         for item in markup:
00079             text = item + 'Paragraph'
00080             result = self.parse(text)
00081             assert re.search(r'<p.*?>\s*Paragraph\s*', result)
00082 
00083 
00084 class TestHeadings(ParserTestCase):
00085     """ Test various heading problems """
00086 
00087     def testIgnoreWhiteSpaceAroundHeadingText(self):
00088         """ parser.wiki: ignore white space around heading text
00089 
00090         See bug: TableOfContentsBreakOnExtraSpaces.
00091 
00092         Does not test mapping of '=' to h number, or valid html markup.
00093         """
00094         tests = (
00095             '=  head =\n', # leading
00096             '= head  =\n', # trailing
00097             '=  head  =\n' # both
00098                  )
00099         expected = self.parse('= head =')
00100         for test in tests:
00101             result = self.parse(test)
00102             assert result == expected
00103 
00104 
00105 class TestTOC(ParserTestCase):
00106 
00107     def testHeadingWithWhiteSpace(self):
00108         """ parser.wiki: TOC links to headings with white space
00109 
00110         See bug: TableOfContentsBreakOnExtraSpaces.
00111 
00112         Does not test TOC or heading formating, just verify that spaces
00113         around heading text does not matter.
00114         """
00115         standard = """
00116 <<TableOfContents>>
00117 = heading =
00118 Text
00119 """
00120         withWhitespace = """
00121 <<TableOfContents>>
00122 =   heading   =
00123 Text
00124 """
00125         expected = self.parse(standard)
00126         result = self.parse(withWhitespace)
00127         assert  result == expected
00128 
00129 
00130 class TestTextFormatingTestCase(ParserTestCase):
00131     """ Test wiki markup """
00132 
00133     text = 'AAA %s AAA'
00134     needle = re.compile(text % r'(.+)')
00135     _tests = (
00136         # test,                     expected
00137         ('no format',               'no format'),
00138         ("//em//",                  '<em>em</em>'),
00139         ("**bold**",              '<strong>bold</strong>'),
00140         ("//**Mix** at start//",  '<em><strong>Mix</strong> at start</em>'),
00141         ("**//Mix// at start**",  '<strong><em>Mix</em> at start</strong>'),
00142         ("**Mix at //end//**",    '<strong>Mix at <em>end</em></strong>'),
00143         ("//Mix at **end**//",    '<em>Mix at <strong>end</strong></em>'),
00144         )
00145 
00146     def testTextFormating(self):
00147         """ parser.wiki: text formating """
00148         for test, expected in self._tests:
00149             html = self.parse(self.text % test)
00150             result = self.needle.search(html).group(1)
00151             assert result == expected
00152 
00153 
00154 class TestCloseInlineTestCase(ParserTestCase):
00155 
00156     def testCloseOneInline(self):
00157         """ parser.wiki: close open inline tag when block close """
00158         cases = (
00159             # test, expected
00160             ("text**text\n", r"<p>text<strong>text\s*</strong></p>"),
00161             ("text//text\n", r"<p>text<em>text\s*</em></p>"),
00162             ("text //em **em strong", r"text <em>em <strong>em strong"),
00163         )
00164         for test, expected in cases:
00165             result = self.parse(test)
00166             assert re.search(expected, result)
00167 
00168 
00169 class TestInlineCrossing(ParserTestCase):
00170     """
00171     This test case fail with current parser/formatter and should be fixed in 2.0
00172     """
00173 
00174     def disabled_testInlineCrossing(self):
00175         """ parser.wiki: prevent inline crossing <a><b></a></b> """
00176 
00177         expected = (r"<p><em>a<strong>ab</strong></em><strong>b</strong>\s*</p>")
00178         test = "//a**ab//b**\n"
00179         result = self.parse(test)
00180         assert re.search(expected, result)
00181 
00182 
00183 class TestEscapeHTML(ParserTestCase):
00184 
00185     def testEscapeInTT(self):
00186         """ parser.wiki: escape html markup in {{{tt}}} """
00187         test = 'text {{{<escape-me>}}} text\n'
00188         self._test(test)
00189 
00190     def testEscapeInPre(self):
00191         """ parser.wiki: escape html markup in pre """
00192         test = '''{{{
00193 <escape-me>
00194 }}}
00195 '''
00196         self._test(test)
00197 
00198     def testEscapeInPreHashbang(self):
00199         """ parser.wiki: escape html markup in pre with hashbang """
00200         test = '''{{{#!
00201 <escape-me>
00202 }}}
00203 '''
00204         self._test(test)
00205 
00206     def testEscapeInPythonCodeArea(self):
00207         """ parser.wiki: escape html markup in python code area """
00208         test = '''{{{#!python
00209 #<escape-me>
00210 }}}
00211 '''
00212         self._test(test)
00213 
00214     def testEscapeInGetTextMacro(self):
00215         """ parser.wiki: escape html markup in GetText macro """
00216         test = u"text <<GetText(<escape-me>)>> text"
00217         self._test(test)
00218 
00219 # Getting double escaping
00220 #
00221 #    def testEscapeInGetTextFormatted(self):
00222 #        """ parser.wiki: escape html markup in getText formatted call """
00223 #        test = self.request.getText('<escape-me>', wiki=True)
00224 #        self._test(test)
00225 #
00226 #    def testEscapeInGetTextFormatedLink(self):
00227 #        """ parser.wiki: escape html markup in getText formatted call with link """
00228 #        test = self.request.getText('[[<escape-me>]]', wiki=True)
00229 #        self._test(test)
00230 
00231     def testEscapeInGetTextUnFormatted(self):
00232         """ parser.wiki: escape html markup in getText non formatted call """
00233         test = self.request.getText('<escape-me>', wiki=False)
00234         self._test(test)
00235 
00236     def _test(self, test):
00237         expected = r'&lt;escape-me&gt;'
00238         result = self.parse(test)
00239         assert re.search(expected, result)
00240 
00241 
00242 
00243 class TestRule(ParserTestCase):
00244     """ Test rules markup """
00245 
00246     def testNotRule(self):
00247         """ parser.wiki: --- is no rule """
00248         result = self.parse('---')
00249         expected = '---' # inside <p>
00250         assert expected in result
00251 
00252     def testStandardRule(self):
00253         """ parser.wiki: ---- is standard rule """
00254         result = self.parse('----')
00255         assert re.search(r'<hr.*?>', result)
00256 
00257     def testLongRule(self):
00258         """ parser.wiki: ----- is no rule """
00259         test = '-----'
00260         result = self.parse(test)
00261         assert re.search(r'-----', result)
00262 
00263 
00264 class TestBlock(ParserTestCase):
00265     cases = (
00266         # test, block start
00267         ('----\n', '<hr'),
00268         ('= Heading =\n', '<h1'),
00269         ('{{{\nPre\n}}}\n', '<pre'),
00270         ('{{{\n#!python\nPre\n}}}\n', '<div'),
00271         ('| Table |\n', '<div'),
00272         (' * unordered list\n', '<ul'),
00273         (' # ordered list\n', '<ol'),
00274         )
00275 
00276     def testParagraphBeforeBlock(self):
00277         """ parser.wiki: paragraph closed before block element """
00278         text = """AAA
00279 %s
00280 """
00281         for test, blockstart in self.cases:
00282             # We dont test here formatter white space generation
00283             expected = r'<p.*?>AAA\s*</p>\s*%s' % blockstart
00284             needle = re.compile(expected, re.MULTILINE)
00285             result = self.parse(text % test)
00286             assert needle.search(result)
00287 
00288     def testUrlAfterBlock(self):
00289         """ parser.wiki: tests url after block element """
00290         case = 'some text {{{some block text\n}}} and a URL http://moinmo.in/'
00291 
00292         result = self.parse(case)
00293         assert result.find('and a URL <a ') > -1
00294 
00295     def testColorizedPythonParserAndNestingPreBrackets(self):
00296         """ tests nested {{{ }}} for the python colorized parser
00297         """
00298 
00299         raw = """{{{
00300 #!python
00301 import re
00302 pattern = re.compile(r'{{{This is some nested text}}}')
00303 }}}"""
00304         output = self.parse(raw)
00305         output = ''.join(output)
00306         assert "{{{This is some nested text}}}" in output
00307 
00308     def testNestingPreBracketsWithLinebreak(self):
00309         """ tests nested {{{ }}} for the wiki parser
00310         """
00311 
00312         raw = """{{{
00313 Example
00314 You can use {{{brackets}}}
00315 }}}"""
00316         output = self.parse(raw)
00317         output = ''.join(output)
00318         print output
00319         assert 'You can use {{{brackets}}}' in output
00320 
00321     def testTextBeforeNestingPreBrackets(self):
00322         """ tests text before nested {{{ }}} for the wiki parser
00323         """
00324         raw = """Example
00325 {{{
00326 You can use {{{brackets}}}
00327 }}}"""
00328         output = self.parse(raw)
00329         output = ''.join(output)
00330         assert 'Example</p><pre>You can use {{{brackets}}}</pre>' in output
00331 
00332     def testManyNestingPreBrackets(self):
00333         """ tests two nestings  ({{{ }}} and {{{ }}}) in one line for the wiki parser
00334         """
00335 
00336         raw = """{{{
00337 Test {{{brackets}}} and test {{{brackets}}}
00338 }}}"""
00339         output = self.parse(raw)
00340         output = ''.join(output)
00341         expected = '<pre>Test {{{brackets}}} and test {{{brackets}}}'
00342         assert expected in output
00343 
00344     def testMultipleShortPreSections(self):
00345         """
00346         tests two single {{{ }}} in one line
00347         """
00348         raw = 'def {{{ghi}}} jkl {{{mno}}}'
00349         output = ''.join(self.parse(raw))
00350         expected = 'def <tt>ghi</tt> jkl <tt>mno</tt>'
00351         assert expected in output
00352 
00353 class TestLinkingMarkup(ParserTestCase):
00354     """ Test wiki link markup """
00355 
00356     text = 'AAA %s AAA'
00357     needle = re.compile(text % r'(.+)')
00358     _tests = [
00359         # test,           expected
00360         ('[[SomeNonExistentPage]]', '<a class="nonexistent" href="/SomeNonExistentPage">SomeNonExistentPage</a>'),
00361         ('[[SomeNonExistentPage#anchor]]', '<a class="nonexistent" href="/SomeNonExistentPage#anchor">SomeNonExistentPage#anchor</a>'),
00362         ('[[something]]', '<a class="nonexistent" href="/something">something</a>'),
00363         ('[[some thing]]', '<a class="nonexistent" href="/some%20thing">some thing</a>'),
00364         ('[[something|some text]]', '<a class="nonexistent" href="/something">some text</a>'),
00365         ('[[../something]]', '<a class="nonexistent" href="/something">../something</a>'),
00366         ('[[/something]]', '<a class="nonexistent" href="/%s/something">/something</a>' % PAGENAME),
00367         ('[[something#anchor]]', '<a class="nonexistent" href="/something#anchor">something#anchor</a>'),
00368         ('[[MoinMoin:something]]', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">something</a>'),
00369         ('[[MoinMoin:something|some text]]', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">some text</a>'),
00370         ('[[MoinMoin:with space]]', '<a class="interwiki" href="http://moinmo.in/with%20space" title="MoinMoin">with space</a>'),
00371         ('[[MoinMoin:with space|some text]]', '<a class="interwiki" href="http://moinmo.in/with%20space" title="MoinMoin">some text</a>'),
00372         ('[[http://google.com/|google]]', '<a class="http" href="http://google.com/">google</a>'),
00373         ]
00374 
00375     def testLinkFormating(self):
00376         """ parser.wiki: link formating """
00377         for test, expected in self._tests:
00378             html = self.parse(self.text % test)
00379             result = self.needle.search(html).group(1)
00380             assert result == expected
00381 
00382     def testLinkAttachment(self):
00383         html = self.parse("[[attachment:some file.txt]]")
00384         assert '<a ' in html
00385         assert 'href="' in html
00386         assert 'class="attachment nonexistent"' in html
00387         assert 'action=AttachFile' in html
00388         assert 'some+file.txt' in html
00389 
00390     def testLinkAttachmentImage(self):
00391         html = self.parse("[[attachment:some file.png]]")
00392         assert '<a ' in html # must create a link
00393         assert 'href="' in html
00394         assert 'class="attachment nonexistent"' in html
00395         assert 'action=AttachFile' in html
00396         assert 'some+file.png' in html
00397 
00398     def testAnchor(self):
00399         html = self.parse("{{#anchor}}")
00400         assert 'id="anchor"' in html
00401 
00402 coverage_modules = ['MoinMoin.parser.text_creole']
00403