[tryton-debian-vcs] relatorio branch upstream updated. upstream/0.7.1-1-g424366c
Mathias Behrle
tryton-debian-vcs at alioth.debian.org
Fri Jan 19 18:08:20 UTC 2018
The following commit has been merged in the upstream branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/relatorio.git;a=commitdiff;h=upstream/0.7.1-1-g424366c
commit 424366c100c9ae96f1914d88d5ac159d5d0f6499
Author: Mathias Behrle <mathiasb at m9s.biz>
Date: Fri Jan 19 18:25:59 2018 +0100
Adding upstream version 0.8.0.
Signed-off-by: Mathias Behrle <mathiasb at m9s.biz>
diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..494e28b
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,27 @@
+clone:
+ hg:
+ image: plugins/hg
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ commands:
+ - pip install tox
+ - apt-get update
+ - apt-get install -y python-cairo
+ - tox -e "${TOXENV}"
+ volumes:
+ - cache:/root/.cache
+
+matrix:
+ include:
+ - IMAGE: python:2.7
+ TOXENV: py27
+ - IMAGE: python:3.3
+ TOXENV: py33
+ - IMAGE: python:3.4
+ TOXENV: py34
+ - IMAGE: python:3.5
+ TOXENV: py35
+ - IMAGE: python:3.6
+ TOXENV: py36
diff --git a/CHANGES b/CHANGES
index 4b6c809..1cc4da5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+0.8.0 - 20171204
+* Do not guess_type on styled cell content
+* Remove type attributes when guessing type
+* Add support for Python 3.6
+* Remove soft-page-break
+
0.7.1 - 20171008
* Remove warning when import plugin fails
* Apply the guess type function on the correct node
diff --git a/PKG-INFO b/PKG-INFO
index 2c3578f..88e41da 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: relatorio
-Version: 0.7.1
+Version: 0.8.0
Summary: A templating library able to output odt and pdf files
Home-page: http://relatorio.tryton.org/
Author: Cedric Krier
@@ -21,14 +21,6 @@ Description: Relatorio
The documenation is provided at http://relatorio.readthedocs.org/
- Note on PyCha
- =============
-
- Since the 0.4.0 release, pycha upstream author included most of our patches. So
- it is not necessary anymore to use our friendly fork of the project.
-
- For SVG support, you need PyCha 0.4.2 or later.
-
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
diff --git a/README b/README
index 76e37f3..2be76db 100644
--- a/README
+++ b/README
@@ -12,11 +12,3 @@ Documenation
============
The documenation is provided at http://relatorio.readthedocs.org/
-
-Note on PyCha
-=============
-
-Since the 0.4.0 release, pycha upstream author included most of our patches. So
-it is not necessary anymore to use our friendly fork of the project.
-
-For SVG support, you need PyCha 0.4.2 or later.
diff --git a/doc/conf.py b/doc/conf.py
index 433badb..19ef52e 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -48,9 +48,9 @@ copyright = u'2015, Nicolas Évrard, CGaëtan de Menten, Cédric Krier'
# built documents.
#
# The short X.Y version.
-version = '0.7'
+version = '0.8'
# The full version, including alpha/beta/rc tags.
-release = '0.7.1'
+release = '0.8.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/examples/basic.odt b/examples/basic.odt
new file mode 100644
index 0000000..f82485e
Binary files /dev/null and b/examples/basic.odt differ
diff --git a/examples/basic.tex b/examples/basic.tex
new file mode 100644
index 0000000..5316a30
--- /dev/null
+++ b/examples/basic.tex
@@ -0,0 +1,21 @@
+\enableregime [utf-8]
+\mainlanguage [fr]
+
+\starttext
+
+Dear $o.customer.name,
+
+Here is the list of your purchases:
+
+\starttable[|l|l|l|l|l|]
+\HL
+\NC Name \VL Reference \VL Quantity \VL Unit Price \VL Amount \SR
+\HL
+{% for line in o.lines%} \
+\NC $line.item.name \VL $line.item.reference \VL $line.quantity
+\VL $line.item.price \VL $line.amount \SR
+\HL \
+{% end %}
+\stoptable
+
+\stoptext
diff --git a/examples/bouteille.png b/examples/bouteille.png
new file mode 100644
index 0000000..ce076c3
Binary files /dev/null and b/examples/bouteille.png differ
diff --git a/examples/columns.odt b/examples/columns.odt
new file mode 100644
index 0000000..4363581
Binary files /dev/null and b/examples/columns.odt differ
diff --git a/examples/common.py b/examples/common.py
new file mode 100644
index 0000000..1fd898f
--- /dev/null
+++ b/examples/common.py
@@ -0,0 +1,43 @@
+from os.path import join, dirname
+
+
+class Invoice(dict):
+
+ @property
+ def total(self):
+ return sum(l['amount'] for l in self['lines'])
+
+ @property
+ def vat(self):
+ return self.total * 0.21
+
+
+inv = Invoice(customer={'name': 'John Bonham',
+ 'address': {'street': 'Smirnov street',
+ 'zip': 1000,
+ 'city': 'Montreux'}},
+ lines=[{'item': {'name': 'Vodka 70cl',
+ 'reference': 'VDKA-001',
+ 'price': 10.34},
+ 'quantity': 7,
+ 'amount': 7 * 10.34},
+ {'item': {'name': 'Cognac 70cl',
+ 'reference': 'CGNC-067',
+ 'price': 13.46},
+ 'quantity': 12,
+ 'amount': 12 * 13.46},
+ {'item': {'name': 'Sparkling water 25cl',
+ 'reference': 'WATR-007',
+ 'price': 4},
+ 'quantity': 1,
+ 'amount': 4},
+ {'item': {'name': 'Good customer',
+ 'reference': 'BONM-001',
+ 'price': -20},
+ 'quantity': 1,
+ 'amount': -20},
+ ],
+ id='MZY-20080703',
+ status='late',
+ bottle=(open(join(dirname(__file__), 'bouteille.png'), 'rb'),
+ 'image/png'))
diff --git a/examples/complicated.odt b/examples/complicated.odt
new file mode 100644
index 0000000..c36ce6a
Binary files /dev/null and b/examples/complicated.odt differ
diff --git a/examples/demo_chart.py b/examples/demo_chart.py
new file mode 100644
index 0000000..f7fb567
--- /dev/null
+++ b/examples/demo_chart.py
@@ -0,0 +1,23 @@
+from os.path import abspath, join, dirname
+from relatorio import Report
+
+# test data
+from common import inv
+
+if __name__ == '__main__':
+ pie_report = Report(abspath(join(dirname(__file__), 'pie_chart')),
+ 'image/png')
+ open(join(dirname(__file__), 'pie.png'), 'wb').write(
+ pie_report(o=inv).render().getvalue())
+ hbar_report = Report(abspath(join(dirname(__file__), 'hbar_chart')),
+ 'image/svg')
+ open(join(dirname(__file__), 'hbar.svg'), 'wb').write(
+ hbar_report(o=inv).render().getvalue())
+ vbar_report = Report(abspath(join(dirname(__file__), 'vbar_chart')),
+ 'image/svg')
+ open(join(dirname(__file__), 'vbar.svg'), 'wb').write(
+ vbar_report(o=inv).render().getvalue())
+ line_report = Report(abspath(join(dirname(__file__), 'line_chart')),
+ 'image/png')
+ open(join(dirname(__file__), 'line.png'), 'wb').write(
+ line_report(o=inv).render().getvalue())
diff --git a/examples/demo_context.py b/examples/demo_context.py
new file mode 100644
index 0000000..5551532
--- /dev/null
+++ b/examples/demo_context.py
@@ -0,0 +1,14 @@
+from os.path import abspath, join, dirname
+from relatorio import Report
+
+# test data
+from common import inv
+
+# PDF
+if __name__ == '__main__':
+ print "generating output_basic.pdf... ",
+ report = Report(abspath(join(dirname(__file__), 'basic.tex')),
+ 'application/pdf')
+ content = report(o=inv).render().getvalue()
+ open(join(dirname(__file__), 'output_basic.pdf'), 'wb').write(content)
+ print "done"
diff --git a/examples/demo_odf.py b/examples/demo_odf.py
new file mode 100644
index 0000000..66c4286
--- /dev/null
+++ b/examples/demo_odf.py
@@ -0,0 +1,68 @@
+from os.path import abspath, join, dirname
+from relatorio import Report
+from relatorio.templates import opendocument
+
+# test data
+from common import inv
+
+ODT_MIME = 'application/vnd.oasis.opendocument.text'
+ODS_MIME = 'application/vnd.oasis.opendocument.spreadsheet'
+ODP_MIME = 'application/vnd.oasis.opendocument.presentation'
+
+if __name__ == '__main__':
+ pwd = dirname(__file__)
+ # ODT
+ print "generating output_basic.odt... ",
+ report = Report(abspath(join(dirname(__file__), 'basic.odt')), ODT_MIME)
+ content = report(o=inv).render().getvalue()
+ open(join(pwd, 'output_basic.odt'), 'wb').write(content)
+ print "done"
+
+ # we could also use an opendocument template directly
+ print "generating output_template_basic.odt... ",
+ template = opendocument.Template(source='',
+ filepath=abspath(join(pwd, 'basic.odt')))
+ content = template.generate(o=inv).render().getvalue()
+ open(join(pwd, 'output_template_basic.odt'), 'wb').write(content)
+ print "done"
+
+ print "generating output_complicated.odt... ",
+ # Add a chart to the invoice
+ inv['chart'] = (
+ Report(abspath(join(pwd, 'pie_chart')), 'image/png'), 'image/png')
+ report = Report(abspath(join(pwd, 'complicated.odt')), ODT_MIME)
+ try:
+ content = report(o=inv).render().getvalue()
+ except NotImplementedError:
+ print "skipped"
+ else:
+ open(join(pwd, 'output_complicated.odt'), 'wb').write(content)
+ print "done"
+
+ print "generating output_columns.odt... ",
+ report = Report(abspath(join(pwd, 'columns.odt')), ODT_MIME)
+ lst = [[], ['i'], ['a', 'b'], [1, 2, 3], ['I', 'II', 'III', 'IV']]
+ titles = ['first', 'second', 'third', 'fourth']
+ content = report(titles=titles, lst=lst).render().getvalue()
+ open(join(pwd, 'output_columns.odt'), 'wb').write(content)
+ print "done"
+
+ # ODS
+ print "generating output_pivot.ods... ",
+ report = Report(abspath(join(pwd, 'pivot.ods')), ODS_MIME)
+ content = report(o=inv).render().getvalue()
+ open(join(pwd, 'output_pivot.ods'), 'wb').write(content)
+ print "done"
+
+ print "generating output_sheets.ods... ",
+ report = Report(abspath(join(pwd, 'demo_sheets.ods')), ODS_MIME)
+ content = report(lst=lst).render().getvalue()
+ open(join(pwd, 'output_sheets.ods'), 'wb').write(content)
+ print "done"
+
+ # ODP
+ print "generating output_presentation.odp... ",
+ report = Report(abspath(join(pwd, 'presentation.odp')), ODP_MIME)
+ content = report(o=inv).render().getvalue()
+ open(join(pwd, 'output_presentation.odp'), 'wb').write(content)
+ print "done"
diff --git a/examples/demo_repository.py b/examples/demo_repository.py
new file mode 100644
index 0000000..cb1e35a
--- /dev/null
+++ b/examples/demo_repository.py
@@ -0,0 +1,32 @@
+import relatorio
+from common import Invoice, inv
+from os.path import join, dirname
+
+ODT_MIME = 'application/vnd.oasis.opendocument.text'
+ODS_MIME = 'application/vnd.oasis.opendocument.spreadsheet'
+ODP_MIME = 'application/vnd.oasis.opendocument.presentation'
+
+repository = relatorio.ReportRepository()
+repository.add_report(Invoice, ODT_MIME, 'basic.odt', report_name='basic')
+repository.add_report(Invoice, ODT_MIME,
+ 'complicated.odt', report_name='complicated')
+repository.add_report(Invoice, ODS_MIME, 'pivot.ods', report_name='pivot')
+repository.add_report(Invoice, ODP_MIME,
+ 'presentation.odp', report_name='presentation')
+repository.add_report(Invoice, 'image/png', 'pie_chart', report_name='pie')
+
+if __name__ == '__main__':
+ # Add a chart to the invoice
+ inv['chart'] = repository.by_id(Invoice, 'pie')[:2]
+
+ # Generate all reports on the invoice class
+ for report_name, ext in (('basic', '.odt'),
+ ('complicated', '.odt'),
+ ('pivot', '.ods'),
+ ('presentation', '.odp')):
+ filename = 'output_%s%s' % (report_name, ext)
+ print "generating '%s'..." % filename,
+ report, mimetype, desc = repository.by_id(Invoice, report_name)
+ data = report(o=inv).render().getvalue()
+ open(join(dirname(__file__), filename), 'wb').write(data)
+ print "done"
diff --git a/examples/demo_sheets.ods b/examples/demo_sheets.ods
new file mode 100644
index 0000000..5797de4
Binary files /dev/null and b/examples/demo_sheets.ods differ
diff --git a/examples/hbar_chart b/examples/hbar_chart
new file mode 100644
index 0000000..0f6607b
--- /dev/null
+++ b/examples/hbar_chart
@@ -0,0 +1,32 @@
+options:
+ width: 600
+ height: 500
+ legend:
+ hide: false
+ position:
+ right: 40
+ padding: {bottom: 70, left: 70, right: 10, top: 10}
+ axis:
+ y:
+ interval: 15
+ padding: 5
+ x:
+ ticks:
+ {% for idx, line in enumerate(o.lines) %}
+ - v: $idx
+ label: $line.item.name
+ {% end %}
+chart:
+ type: hbar
+ output_type: svg
+ dataset:
+ - - Sales
+ -
+ {% for idx, line in enumerate(o.lines) %}
+ - [$idx, $line.amount]
+ {% end %}
+ - - Absolute sales
+ -
+ {% for idx, line in enumerate(o.lines) %}
+ - [$idx, ${abs(line.amount)}]
+ {% end %}
diff --git a/examples/line_chart b/examples/line_chart
new file mode 100644
index 0000000..1457845
--- /dev/null
+++ b/examples/line_chart
@@ -0,0 +1,27 @@
+options:
+ width: 600
+ height: 500
+ legend:
+ hide: false
+ position:
+ right: 40
+ padding: {bottom: 70, left: 70, right: 10, top: 10}
+ axis:
+ y:
+ interval: 10
+ padding: 10
+ x:
+ ticks:
+ {% for idx, line in enumerate(o.lines) %}
+ - v: $idx
+ label: $line.item.name
+ {% end %}
+chart:
+ type: line
+ output_type: png
+ dataset:
+ - - Sales
+ -
+ {% for idx, line in enumerate(o.lines) %}
+ - [$idx, $line.amount]
+ {% end %}
diff --git a/examples/pie_chart b/examples/pie_chart
new file mode 100644
index 0000000..4b24054
--- /dev/null
+++ b/examples/pie_chart
@@ -0,0 +1,15 @@
+options:
+ width: 600
+ height: 400
+ background: {hide: true}
+ legend: {hide: true}
+ axis: {labelFontSize: 14}
+ padding: {bottom: 10, left: 10, right: 10, top: 10}
+chart:
+ type: pie
+ output_type: png
+ dataset:
+ {% for line in o.lines %}
+ - - ${line.item.name}
+ - - [0, $line.amount]
+ {% end %}
diff --git a/examples/pivot.ods b/examples/pivot.ods
new file mode 100644
index 0000000..0d0b40f
Binary files /dev/null and b/examples/pivot.ods differ
diff --git a/examples/presentation.odp b/examples/presentation.odp
new file mode 100644
index 0000000..7d08b92
Binary files /dev/null and b/examples/presentation.odp differ
diff --git a/examples/vbar_chart b/examples/vbar_chart
new file mode 100644
index 0000000..56c6790
--- /dev/null
+++ b/examples/vbar_chart
@@ -0,0 +1,32 @@
+options:
+ width: 600
+ height: 500
+ legend:
+ hide: false
+ position:
+ right: 40
+ padding: {bottom: 70, left: 70, right: 10, top: 10}
+ axis:
+ y:
+ interval: 20
+ padding: 5
+ x:
+ ticks:
+ {% for idx, line in enumerate(o.lines) %}
+ - v: $idx
+ label: $line.item.name
+ {% end %}
+chart:
+ type: vbar
+ output_type: svg
+ dataset:
+ - - Sales
+ -
+ {% for idx, line in enumerate(o.lines) %}
+ - [$idx, $line.amount]
+ {% end %}
+ - - Absolute sales
+ -
+ {% for idx, line in enumerate(o.lines) %}
+ - [$idx, ${abs(line.amount)}]
+ {% end %}
diff --git a/relatorio.egg-info/PKG-INFO b/relatorio.egg-info/PKG-INFO
index 2c3578f..88e41da 100644
--- a/relatorio.egg-info/PKG-INFO
+++ b/relatorio.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: relatorio
-Version: 0.7.1
+Version: 0.8.0
Summary: A templating library able to output odt and pdf files
Home-page: http://relatorio.tryton.org/
Author: Cedric Krier
@@ -21,14 +21,6 @@ Description: Relatorio
The documenation is provided at http://relatorio.readthedocs.org/
- Note on PyCha
- =============
-
- Since the 0.4.0 release, pycha upstream author included most of our patches. So
- it is not necessary anymore to use our friendly fork of the project.
-
- For SVG support, you need PyCha 0.4.2 or later.
-
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
diff --git a/relatorio.egg-info/SOURCES.txt b/relatorio.egg-info/SOURCES.txt
index 5d118bc..07d1fee 100644
--- a/relatorio.egg-info/SOURCES.txt
+++ b/relatorio.egg-info/SOURCES.txt
@@ -1,3 +1,6 @@
+.drone.yml
+.hgignore
+.hgtags
AUTHORS
CHANGES
LICENSE
@@ -5,6 +8,7 @@ MANIFEST.in
README
setup.cfg
setup.py
+tox.ini
doc/Makefile
doc/basic.png
doc/basic_generated.png
@@ -22,6 +26,23 @@ doc/pivot.png
doc/pivot_rendered.png
doc/quickexample.rst
doc/relatorio_basic.png
+examples/basic.odt
+examples/basic.tex
+examples/bouteille.png
+examples/columns.odt
+examples/common.py
+examples/complicated.odt
+examples/demo_chart.py
+examples/demo_context.py
+examples/demo_odf.py
+examples/demo_repository.py
+examples/demo_sheets.ods
+examples/hbar_chart
+examples/line_chart
+examples/pie_chart
+examples/pivot.ods
+examples/presentation.odp
+examples/vbar_chart
relatorio/__init__.py
relatorio/reporting.py
relatorio.egg-info/PKG-INFO
diff --git a/relatorio/__init__.py b/relatorio/__init__.py
index f2bb8da..4a9e345 100644
--- a/relatorio/__init__.py
+++ b/relatorio/__init__.py
@@ -12,5 +12,5 @@ and report together, find reports by mimetypes/name/python objects.
from .reporting import MIMETemplateLoader, ReportRepository, Report
from . import templates
-__version__ = '0.7.1'
+__version__ = '0.8.0'
__all__ = ['MIMETemplateLoader', 'ReportRepository', 'Report', 'templates']
diff --git a/relatorio/templates/opendocument.py b/relatorio/templates/opendocument.py
index b72a075..c25284a 100644
--- a/relatorio/templates/opendocument.py
+++ b/relatorio/templates/opendocument.py
@@ -211,6 +211,26 @@ def wrap_nodes_between(first, last, new_parent):
old_parent.remove(last)
+def remove_node_keeping_tail(node):
+ """Remove the node from the tree but keeping tail by appending to the
+ previous or parent node.
+ """
+ parent = node.getparent()
+ if node.tail:
+ previous = node.getprevious()
+ if previous is not None:
+ if not previous.tail:
+ previous.tail = node.tail
+ else:
+ previous.tail += node.tail
+ else:
+ if not parent.text:
+ parent.text = node.tail
+ else:
+ parent.text += node.tail
+ parent.remove(node)
+
+
def update_py_attrs(node, value):
"""An helper function to update py_attrs of a node.
"""
@@ -311,6 +331,7 @@ class Template(MarkupTemplate):
self.namespaces['py'] = GENSHI_URI
self.namespaces['relatorio'] = RELATORIO_URI
+ self._remove_soft_page_break(tree)
self._invert_style(tree)
self._handle_relatorio_tags(tree)
self._handle_images(tree)
@@ -318,6 +339,17 @@ class Template(MarkupTemplate):
self._escape_values(tree)
return BytesIO(lxml.etree.tostring(tree))
+ def _remove_soft_page_break(self, tree):
+ "remove soft-page-break tag and use-soft-page-break attribute"
+ xpath_expr = "//text:soft-page-break"
+ for node in tree.xpath(xpath_expr, namespaces=self.namespaces):
+ remove_node_keeping_tail(node)
+
+ xpath_expr = "//office:text[@text:use-soft-page-breaks]"
+ text_namespace = self.namespaces['text']
+ for node in tree.xpath(xpath_expr, namespaces=self.namespaces):
+ node.attrib.pop('{%s}use-soft-page-breaks' % text_namespace)
+
def _invert_style(self, tree):
"inverts the text:a and text:span"
xpath_expr = "//text:a[starts-with(@xlink:href, 'relatorio://')]" \
@@ -396,6 +428,16 @@ class Template(MarkupTemplate):
table_namespace = self.namespaces['table']
table_row_tag = '{%s}table-row' % table_namespace
table_cell_tag = '{%s}table-cell' % table_namespace
+ text_namespace = self.namespaces['text']
+ text_style_attributes = [s % text_namespace for s in [
+ '{%s}class-names', '{%s}cond-style-name', '{%s}style-name']]
+
+ office_value = '{%s}value' % self.namespaces['office']
+ office_valuetype = '{%s}value-type' % self.namespaces['office']
+ if 'calcext' in self.namespaces:
+ calcext_valuetype = '{%s}value-type' % self.namespaces['calcext']
+ else:
+ calcext_valuetype = None
py_replace = '{%s}replace' % GENSHI_URI
@@ -473,13 +515,17 @@ class Template(MarkupTemplate):
# remove the directive node
r_node.getparent().remove(r_node)
else:
+ def has_style(node):
+ return any(attr in node.attrib
+ for attr in text_style_attributes)
# It's not a genshi statement it's a python expression
parent = r_node.getparent()
grand_parent = parent.getparent()
# Guess type only if it is the only value in the cell
+ # and its parent has no style
if (grand_parent is None
or grand_parent.tag != table_cell_tag
- ) or len(parent) != 1:
+ ) or len(grand_parent) != 1 or has_style(parent):
r_node.attrib[py_replace] = expr
continue
@@ -491,6 +537,11 @@ class Template(MarkupTemplate):
dico = ('__relatorio_guess_type('
'__relatorio_store_cache(%s, %s))')
update_py_attrs(grand_parent, dico % (cache_id, expr))
+ for attr in [office_value,
+ office_valuetype,
+ calcext_valuetype]:
+ if attr:
+ grand_parent.attrib.pop(attr, None)
def _handle_column_loops(self, statement, ancestor, opening,
outer_o_node, outer_c_node):
diff --git a/relatorio/tests/test_odt.py b/relatorio/tests/test_odt.py
index 2b22087..ca5f5b4 100644
--- a/relatorio/tests/test_odt.py
+++ b/relatorio/tests/test_odt.py
@@ -23,7 +23,7 @@
import os
import unittest
-from io import StringIO
+from io import StringIO, BytesIO
import lxml.etree
from genshi.filters import Translator
@@ -31,7 +31,7 @@ from genshi.core import PI
from genshi.template.eval import UndefinedError
from relatorio.templates.opendocument import Template, GENSHI_EXPR,\
- GENSHI_URI, RELATORIO_URI, fod2od
+ GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail
OO_TABLE_NS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
@@ -339,3 +339,76 @@ class TestOOTemplating(unittest.TestCase):
with open(filepath, mode='rb') as source:
oot = Template(source)
oot.generate(**self.data)
+
+
+class TestRemoveNodeKeepingTail(unittest.TestCase):
+
+ def test_without_tail(self):
+ "Testing remove_node_keeping_tail without tail"
+ xml = b'''<parent><target/></parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[0]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(lxml.etree.tostring(tree), b'''<parent/>''')
+
+ def test_with_tail(self):
+ "Testing remove_node_keeping_tail with tail"
+ xml = b'''<parent><target/>tail</parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[0]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(
+ lxml.etree.tostring(tree),
+ b'''<parent>tail</parent>''')
+
+ def test_with_tail_and_parent_text(self):
+ "Testing remove_node_keeping_tail with tail and parent text"
+ xml = b'''<parent>text<target/>tail</parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[0]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(
+ lxml.etree.tostring(tree),
+ b'''<parent>texttail</parent>''')
+
+ def test_without_tail_and_with_previous(self):
+ "Testing remove_node_keeping_tail without tail and with previous"
+ xml = b'''<parent><previous/><target/></parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[1]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(
+ lxml.etree.tostring(tree),
+ b'''<parent><previous/></parent>''')
+
+ def test_with_tail_and_previous(self):
+ "Testing remove_node_keeping_tail with tail and previous"
+ xml = b'''<parent><previous/><target/>tail</parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[1]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(
+ lxml.etree.tostring(tree),
+ b'''<parent><previous/>tail</parent>''')
+
+ def test_with_tail_and_previous_tail(self):
+ "Testing remove_node_keeping_tail with tail and previous tail"
+ xml = b'''<parent><previous/>tail<target/>tail</parent>'''
+ tree = lxml.etree.parse(BytesIO(xml))
+ target = tree.getroot()[1]
+
+ remove_node_keeping_tail(target)
+
+ self.assertEqual(
+ lxml.etree.tostring(tree),
+ b'''<parent><previous/>tailtail</parent>''')
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..792676f
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,13 @@
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py26, py27, py32, py33, py34, py35, py36, pypy
+
+[testenv]
+commands = {envpython} setup.py test
+deps =
+ pyyaml
+ pycha
--
relatorio
More information about the tryton-debian-vcs
mailing list