# -*- coding: utf-8 -*-
# Copyright (C) 2013 Stefan Merten
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
"""
Test XsltParser.
"""
import unittest
import docutils.utils, docutils.frontend
import StringIO
from lxml import etree
from __init__ import DocutilsTestSupport
from docutils_xml.parsers.xslt import XsltParser, XPathExtension
from docutils_xml.writers.xslt import XsltWriter
###############################################################################
class XsltParserTestCase(DocutilsTestSupport.ParserTestCase):
"""
Output checker for XsltParser.
"""
xslt = None
"""
:type: basestring
XSLT sheet to use for processing.
Override this in subclasses.
"""
extension = None
"""
:type: None | XPathExtension
XPath extension class to use.
Override this in subclasses if you need XPath extension functions.
"""
def __init__(self, *args, **kwargs):
"""
:Parameters: See super class for arguments.
input : unicode | ( dict, unicode )
Either the input string to use or a tuple with a dictionary
containing settings for this test case and the input string.
expected : unicode | type
Either the expected output string or an exception class. If an
exception class is given the test case is expected to raise this
exception.
"""
self.parser = XsltParser(StringIO.StringIO(self.xslt), self.extension)
"""Input parser for this test case."""
self.option_parser = docutils.frontend.OptionParser(components=(
self.parser, ))
DocutilsTestSupport.ParserTestCase.__init__(self, *args, **kwargs)
def test_parser(self):
if isinstance(self.input, ( list, tuple )):
( case_settings, input ) = self.input
else:
( case_settings, input ) = ( { }, self.input )
settings = self.settings.copy()
settings.__dict__.update(self.suite_settings)
settings.__dict__.update(case_settings)
document = docutils.utils.new_document('test data', settings)
if (isinstance(self.expected, type)
and issubclass(self.expected, Exception)):
with self.assertRaises(self.expected):
self.parser.parse(input, document)
else:
self.parser.parse(input, document)
writer = XsltWriter()
output = writer.write(document, docutils.io.StringOutput())
self.compare_output(input, output, self.expected)
###############################################################################
###############################################################################
class XsltParserIdentityTestCase(XsltParserTestCase):
"""
Output checker for XsltParser with identity transformation.
"""
xslt = u"""\
"""
###############################################################################
class XsltParserIdentityTestSuite(DocutilsTestSupport.ParserTestSuite):
test_case_class = XsltParserIdentityTestCase
###############################################################################
identity = { }
identity['simple'] = (
( u"""
""",
"""
""" ),
( u"""
""",
etree.LxmlSyntaxError, ),
( u"""
""",
etree.LxmlSyntaxError, ),
)
identity['encoding'] = (
( """
""",
"""
""" ),
( """
""",
"""
""" ),
( u"""
""",
"""
""" ),
( """
""",
"""
""" ),
( u"""
""",
"""
""" ),
( """
""",
"""
""" ),
( u"""
""",
"""
""" ),
( u"""
""",
LookupError ),
( u"""
""",
UnicodeError ),
)
###############################################################################
###############################################################################
class XPathExtensionTest(XPathExtension):
"""
XPath extension functions for test purposes.
"""
namespace = "http://www.merten-home.de/docutils_xml"
def parVoid(self, context):
"""
Accept no parameters and do nothing.
"""
pass
def parString(self, context, s):
"""
Accept a string parameter and return its string representation.
:Parameters:
s : Smart string
The smart string.
"""
return repr(self._stringParameter(s))
def parBoolean(self, context, b):
"""
Accept a boolean parameter and return its string representation.
:Parameters:
b : boolean
The boolean.
"""
return str(self._boolParameter(b))
def parFloat(self, context, f):
"""
Accept a float parameter and return its string representation.
:Parameters:
f : float
The float.
"""
return str(self._floatParameter(f))
def parInt(self, context, i):
"""
Accept an int parameter and return its string representation.
:Parameters:
i : int
The int.
"""
return str(self._intParameter(i))
###############################################################################
class XsltParserXPathExtensionTestCase(XsltParserTestCase):
"""
Output checker for XsltParser using XPath extension functions.
"""
xslt = u"""\
"""
extension = XPathExtensionTest()
###############################################################################
class XsltParserXPathExtensionTestSuite(DocutilsTestSupport.ParserTestSuite):
test_case_class = XsltParserXPathExtensionTestCase
###############################################################################
xPathExtension = { }
xPathExtension['simple'] = (
( u"""
""",
"" ),
)
xPathExtension['void'] = (
( u"""
""",
"""
""" ),
)
xPathExtension['string'] = (
( u"""
""",
"""u'Constant'
""" ),
( u"""
""",
"""u'Attribute content'
""" ),
( u"""
""",
TypeError ),
( u"""
Element content
""",
TypeError ),
( u"""
""",
"""u'\\xfcmlaut'
""" ),
)
xPathExtension['boolean'] = (
( u"""
""",
"""True
""" ),
( u"""
""",
"""True
""" ),
( u"""
""",
"""False
""" ),
( u"""
""",
TypeError ),
( u"""
non-empty
""",
TypeError ),
)
xPathExtension['float'] = (
( u"""
""",
"""3.14
""" ),
( u"""
""",
"""0.0
""" ),
( u"""
""",
"""-3.7
""" ),
( u"""
""",
"""0.001
""" ),
( u"""
""",
TypeError ),
( u"""
10.7
""",
TypeError ),
)
xPathExtension['int'] = (
( u"""
""",
"""42
""" ),
( u"""
""",
"""0
""" ),
( u"""
""",
"""-3
""" ),
( u"""
""",
"""1000
""" ),
( u"""
""",
TypeError ),
( u"""
17
""",
TypeError ),
( u"""
""",
ValueError ),
)
###############################################################################
###############################################################################
class XsltParserParameterTestCase(XsltParserTestCase):
"""
Output checker for XsltParser using parameters.
"""
xslt = u"""\
"""
###############################################################################
class XsltParserParameterTestSuite(DocutilsTestSupport.ParserTestSuite):
test_case_class = XsltParserParameterTestCase
###############################################################################
parameter = { }
parameter['simple'] = (
( u"""
""",
u"""false
0
0
""" ),
( ( { 'bool': True,
'int': 42,
'float': 3.14,
'string': 'bla',
'mandatory': 'given',
},
u"""
""", ),
"""true
42
3.14
bla
given
""" ),
( ( { 'bool': False,
'int': 2147483647,
'float': 1e50,
'string': '',
'mandatory': ( 1, 2 ),
},
u"""
""", ),
"""false
2147483647
1e+50
""" ),
( ( { 'string': '"\'',
},
u"""
""", ),
ValueError ),
( ( { 'bool': True,
'int': 42,
'float': 3.14,
'string': u'ümlaut',
'mandatory': 'given',
},
u"""
""", ),
"""true
42
3.14
ümlaut
given
""" ),
)
###############################################################################
###############################################################################
def suite():
s = unittest.TestSuite()
identitySuite = XsltParserIdentityTestSuite()
identitySuite.generateTests(identity, dictname='identity')
s.addTest(identitySuite)
xPathExtensionSuite = XsltParserXPathExtensionTestSuite()
xPathExtensionSuite.generateTests(xPathExtension, dictname='xPathExtension')
s.addTest(xPathExtensionSuite)
parameterSuite = XsltParserParameterTestSuite()
parameterSuite.generateTests(parameter, dictname='parameter')
s.addTest(parameterSuite)
return s
###############################################################################
if __name__ == '__main__':
import unittest
unittest.main(defaultTest='suite')