Source

moin-2.0 / MoinMoin / converter / _tests / test_docbook_out.py

Full commit
# Copyright: 2010 MoinMoin:ValentinJaniaut
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

"""
MoinMoin - Tests for MoinMoin.converter.docbook_out
"""


import re
import StringIO

import pytest

try:
    from lxml import etree
except:
    pytest.skip("lxml module required to run test for docbook_out converter.")

from emeraldtree.tree import *

from MoinMoin import log
logging = log.getLogger(__name__)

from MoinMoin.converter.docbook_out import *

class Base(object):
    input_namespaces = ns_all = 'xmlns="{0}" xmlns:page="{1}" xmlns:html="{2}" xmlns:xlink="{3}" xmlns:xml="{4}"'.format(moin_page.namespace, moin_page.namespace, html.namespace, xlink.namespace, xml.namespace)
    output_namespaces = {
        docbook.namespace: '',
        moin_page.namespace: 'page',
        xlink.namespace: 'xlink',
        xml.namespace: 'xml',
    }

    namespaces_xpath = {'xlink': xlink.namespace,
                        'xml': xml.namespace,
    }

    input_re = re.compile(r'^(<[a-z:]+)')
    output_re = re.compile(r'\s+xmlns="[^"]+"')

    def handle_input(self, input):
        i = self.input_re.sub(r'\1 ' + self.input_namespaces, input)
        return ET.XML(i)

    def handle_output(self, elem, **options):
        file = StringIO.StringIO()
        tree = ET.ElementTree(elem)
        tree.write(file, namespaces=self.output_namespaces, **options)
        return self.output_re.sub(u'', file.getvalue())

    def do(self, input, xpath, args={}):
        out = self.conv(self.handle_input(input), **args)
        string_to_parse = self.handle_output(out)
        logging.debug("After the docbook_OUT conversion : {0}".format(string_to_parse))
        tree = etree.parse(StringIO.StringIO(string_to_parse))
        assert (tree.xpath(xpath, namespaces=self.namespaces_xpath))

class TestConverter(Base):
    def setup_class(self):
        self.conv = Converter()

    def test_base(self):
        data = [
           # NB: All the output contain the <info> section, but for a better
           #     readability, I did not wrote it in the snippet except this one
           ('<page><body><p>Test</p></body></page>',
            # <article><info><title>Untitled</title></info><simpara>Test</simpara></article>
              '/article[./info[title="Untitled"]][simpara="Test"]'),
           # ADMONITION type --> type
           ('<page><body><admonition page:type="warning"><p>Text</p></admonition></body></page>',
            # <article><warning><simpara>Text</simpara></warning></article>
            '/article/warning[simpara="Text"]'),
           # Unknown admonition
           ('<page><body><admonition page:type="none"><p>Text</p></admonition></body></page>',
            '/article[simpara="Text"]'),
           # XML attributes: we support all the xml standard attributes
           ('<page><body><p xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>',
            # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
            '/article/simpara[@xml:base="http://base.tld"][@xml:id="id"][@xml:lang="en"][text()="Text"]'),
           # Para with title
           ('<page><body><p html:title="Title">Text</p></body></page>',
            # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
            '/article/para[text()="Text"][title="Title"]'),
        ]
        for i in data:
            yield (self.do, ) + i

    def test_title(self):
        data = [
            ('<page><body><h page:outline-level="1">Heading 1</h><p>First</p><h page:outline-level="2">Heading 2</h><p>Second</p></body></page>',
             '/article/sect1[title="Heading 1"][simpara="First"]/sect2[title="Heading 2"][simpara="Second"]'),
        ]
        for i in data:
            yield (self.do, ) + i

    def test_list(self):
        data = [
            # Simple unordered list
            ('<page><body><list page:item-label-generate="unordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><itemizedlist><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></itemizedlist></article>
             '/article/itemizedlist[listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple ordered list (use default arabic numeration)
            ('<page><body><list page:item-label-generate="ordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><orderedlist numeration="arabic"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
             '/article/orderedlist[@numeration="arabic"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple ordered list with upper-alpha numeration
            ('<page><body><list page:item-label-generate="ordered" page:list-style-type="upper-alpha"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><orderedlist numeration="upperalpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
             '/article/orderedlist[@numeration="upperalpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple ordered list with lower-alpha numeration
            ('<page><body><list page:item-label-generate="ordered" page:list-style-type="lower-alpha"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><orderedlist numeration="loweralpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
             '/article/orderedlist[@numeration="loweralpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple ordered list with upper-roman numeration
            ('<page><body><list page:item-label-generate="ordered" page:list-style-type="upper-roman"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><orderedlist numeration="upperroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
             '/article/orderedlist[@numeration="upperroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple ordered list with lower-roman numeration
            ('<page><body><list page:item-label-generate="ordered" page:list-style-type="lower-roman"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
             # <article><orderedlist numeration="lowerroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
             '/article/orderedlist[@numeration="lowerroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
            # Simple definition list
            ('<page><body><list><list-item><list-item-label>First Term</list-item-label><list-item-body>First Definition</list-item-body></list-item><list-item><list-item-label>Second Term</list-item-label><list-item-body>Second Definition</list-item-body></list-item></list></body></page>',
             # <article><variablelist><varlistentry><term>First Term</term><listitem><simpara>First Definition</simpara></listitem></varlistentry><varlistentry><term>Second term</term><listitem><simpara>Second Definition</simpara></listitem></varlistentry></variablelist></article>
             '/article/variablelist[varlistentry[1][./term[text()="First Term"]][./listitem/simpara[text()="First Definition"]]][varlistentry[2][./term[text()="Second Term"]][./listitem/simpara[text()="Second Definition"]]]')
        ]

        for i in data:
            yield (self.do, ) + i

    def test_table(self):
        data = [
            # All the table output caption, just wrote a test and snippet
            # for the two first tests.
            ('<page><body><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></body></page>',
            # <article><table><caption>Table 0</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
                '/article/table[caption="Table 0"][thead/tr[td="Header"]][tfoot/tr[td="Footer"]][tbody/tr[td="Cell"]]'),
            ('<page><body><table html:title="Title"><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></body></page>',
            # <article><table><caption>Title</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
                '/article/table[caption="Title"][thead/tr[td="Header"]][tfoot/tr[td="Footer"]][tbody/tr[td="Cell"]]'),
            ('<page><body><table><table-body><table-row><table-cell page:number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>',
             # <article><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></article>
                '/article/table/tbody/tr/td[@colspan="2"][text()="Cell"]'),
            ('<page><body><table><table-body><table-row><table-cell page:number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>',
            # <article><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></article>
                '/article/table/tbody/tr/td[@rowspan="2"][text()="Cell"]'),
        ]
        for i in data:
            yield (self.do, ) + i

    def test_simparagraph_elements(self):
        data = [
            # Footnote conversion
            ('<page><body><p>Text simpara<note page:note-class="footnote"><note-body>Text Footnote</note-body></note></p></body></page>',
             # <article><simpara>Text simpara<footnote>Text Footnote</footnote></simpara></article>
             '/article/simpara[text()="Text simpara"]/footnote[simpara="Text Footnote"]'),
            # Link conversion
            ('<page><body><p><a xlink:href="uri:test" xlink:title="title">link</a></p></body></page>',
              # <article><simpara><link xlink:href="uri:test" xlink:title="title">link</link></simpara></article>
              '/article/simpara/link[@xlink:href="uri:test"][@xlink:title="title"][text()="link"]'),
            # Blockcode conversion into <screen> with CDATA
            ('<page><body><blockcode>Text</blockcode></body></page>',
              # <article><screen><![CDATA[Text]]></screen></article>
             '/article[screen="<![CDATA[Text]]>"]'),
            # Code conversion into <literal>
            ('<page><body><p><code>Text</code></p></body></page>',
              # <article><simpara><literal>Text</literal></simpara></article>
             '/article/simpara[literal="Text"]'),
            # SPAN --> PHRASE
            ('<page><body><p><span>Text</span></p></body></page>',
              # <article><simpara><phrase>Text</phrase></simpara></article>
             '/article/simpara[phrase="Text"]'),
            # SPAN baseline-shift=sub --> subscript
            ('<page><body><p>sub<span page:baseline-shift="sub">sub</span>script</p></body></page>',
             # <article><simpara>script<subscript>sub</subscript></simpara></article>
             '/article/simpara[text()="script"][subscript="sub"]'),
            # SPAN baseline-shift=super --> superscript
            ('<page><body><p>sub<span page:baseline-shift="super">super</span>script</p></body></page>',
             # <article><simpara>script</simpara><superscript>super</superscript></article>
             '/article/simpara[text()="script"][superscript="super"]'),
            # STRONG --> EMPHASIS role='strong'
            ('<page><body><p>text<strong>strong</strong></p></body></page>',
             # <article><simpara>text<emphasis role="strong">strong</emphasis></simpara>
             '/article/simpara[text()="text"]/emphasis[@role="strong"][text()="strong"]'),
            # EMPHASIS --> EMPHASIS
            ('<page><body><p>text<emphasis>emphasis</emphasis></p></body></page>',
             # <article><simpara>text<emphasis>emphasis</emphasis></simpara>
             '/article/simpara[text()="text"][emphasis="emphasis"]'),
            # LINE-BREAK --> SBR
            ('<page><body><p>Line 1<line-break />Line 2</p></body></page>',
             #<article><simpara>Line 1<sbr />Line 2</simpara></article>
             '/article/simpara[text()="Line 1"]/sbr'),
            # QUOTE --> QUOTE
            ('<page><body><p>Text<quote>quotation</quote></p></body></page>',
             # <article><simpara>Text<quote>quotation</quote></simpara></body></page>
             '/article/simpara[text()="Text"][quote="quotation"]'),
            # BLOCKQUOTE --> BLOCKQUOTE
            ('<page><body><blockquote page:source="Socrates">One thing only I know, and that is that I know nothing.</blockquote></body></page>',
             # <article><blockquote><attribution>Socrates</attribution><simpara>One thing ... nothing</simpara></blockquote></article>
             '/article/blockquote[attribution="Socrates"][simpara="One thing only I know, and that is that I know nothing."]'),

        ]
        for i in data:
            yield (self.do, ) + i

    def test_object(self):
        data = [
            ('<page><body><p><object xlink:href="pics.png" page:type="image/" /></p></body></page>',
             # <article><simpara><inlinemediaobject><imageobject><imagedata fileref="pics.png"></imageobject></inlinemediaobject></simpara></article>
             '/article/simpara/inlinemediaobject/imageobject/imagedata[@fileref="pics.png"]'),
            ('<page><body><p><object xlink:href="sound.wav" page:type="audio/" /></p></body></page>',
             # <article><simpara><inlinemediaobject><audioobject><audiodata fileref="sound.wav"></audioobject></inlinemediaobject></simpara></article>
             '/article/simpara/inlinemediaobject/audioobject/audiodata[@fileref="sound.wav"]'),
            ('<page><body><p><object xlink:href="video.ogg" page:type="video/" /></p></body></page>',
             # <article><simpara><inlinemediaobject><videoobject><videodata fileref="video.ogg"></videoobject></inlinemediaobject></simpara></article>
             '/article/simpara/inlinemediaobject/videoobject/videodata[@fileref="video.ogg"]'),
        ]
        for i in data:
            yield (self.do, ) + i