summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2011-09-03 13:21:09 -0400
committerShaun McCance <shaunm@gnome.org>2011-09-03 13:21:09 -0400
commit0520144626db679e81725aebfaba273a52fd0bf4 (patch)
treebda0095be8d25969373b8f6afa0f7c7527e0f911
parent092a26470a5032c85ba8a40570ee6fd6c9fe9b30 (diff)
parent7e0739641507d92e1d2ec7e9b7f5e5c7c09a940a (diff)
downloaditstool-0520144626db679e81725aebfaba273a52fd0bf4.tar.gz
Merge: Proper XML error catching [claude]
-rwxr-xr-xitstool.in11
-rw-r--r--tests/Malformed.xml6
-rw-r--r--tests/Translate3.ll.wrong.po19
-rw-r--r--tests/run_tests.py41
4 files changed, 66 insertions, 11 deletions
diff --git a/itstool.in b/itstool.in
index 1db369c..d0510a9 100755
--- a/itstool.in
+++ b/itstool.in
@@ -287,9 +287,14 @@ def xml_is_ns_name (node, ns, name):
return False
return node.name == name and node.ns() is not None and node.ns().content == ns
+def xml_error_catcher(doc, error):
+ doc._xml_err += " %s" % error
+
class Document (object):
def __init__ (self, filename, messages):
+ self._xml_err = ''
+ libxml2.registerErrorHandler(xml_error_catcher, self)
ctxt = libxml2.createFileParserCtxt(filename)
ctxt.lineNumbers(1)
ctxt.replaceEntities(1)
@@ -313,6 +318,7 @@ class Document (object):
self._localrules.append(child)
pre_process(child)
pre_process(self._doc)
+ self._check_errors()
self._msgs = messages
self._its_translate_nodes = {}
self._its_within_text_nodes = {}
@@ -325,6 +331,10 @@ class Document (object):
self._itst_credits = None
self._itst_externals = []
+ def _check_errors(self):
+ if self._xml_err:
+ raise libxml2.parserError(self._xml_err)
+
def apply_its_rule(self, rule, xpath):
if rule.type != 'element':
return
@@ -644,6 +654,7 @@ class Document (object):
if child.type == 'element':
fix_node_ns(child, childnsdefs)
fix_node_ns(node, {})
+ self._check_errors()
def translate_attrs(self, oldnode, newnode):
trans_attrs = [attr for attr in xml_attr_iter(oldnode) if self._its_translate_nodes.get(attr, 'no') == 'yes']
diff --git a/tests/Malformed.xml b/tests/Malformed.xml
new file mode 100644
index 0000000..1df11e5
--- /dev/null
+++ b/tests/Malformed.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<myDoc>
+ <body>
+ <par>This is the first paragraph. It has some <code>malformed XML<code>.</par>
+ </body>
+</myDoc>
diff --git a/tests/Translate3.ll.wrong.po b/tests/Translate3.ll.wrong.po
new file mode 100644
index 0000000..a143f9c
--- /dev/null
+++ b/tests/Translate3.ll.wrong.po
@@ -0,0 +1,19 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2011-05-31 21:23+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: tests/Translate3.xml:6(head/title)
+msgid "The Life of a Simple Man"
+msgstr "La vie d'un simple homme"
+
+#: tests/Translate3.xml:9(body/p)
+msgid "Everything started when Zebulon discovered that he had a <_:span-1/> who was a serious baseball <_:span-2/>."
+msgstr "Tout commença alors que Zebulon découvrit qu'il avait un <_:span-1> qui était un <_:span-2/> sérieux de baseball."
+
diff --git a/tests/run_tests.py b/tests/run_tests.py
index 9f0ca9a..906d638 100644
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -14,48 +14,56 @@ class ItstoolTests(unittest.TestCase):
if os.path.exists(path):
os.remove(path)
- def run_command(self, cmd):
+ def run_command(self, cmd, expected_status=0):
""" Helper method to run a shell command """
# Set stdout = sys.stdout to debug a subprocess if you set a breakpoint in it
pipe = Popen(cmd, shell=True, env=os.environ, stdin=None, stdout=PIPE, stderr=PIPE)
(output, errout) = map(lambda x:x.decode('utf-8'), pipe.communicate())
status = pipe.returncode
- self.assertEqual(status, 0, errout or output)
- return (status, output, errout)
+ self.assertEqual(status, expected_status, errout or output)
+ return {'status': status, 'output': output, 'errors': errout}
def assertFilesEqual(self, f1, f2):
options = ""
if f1.endswith(".po") or f1.endswith(".pot"):
options = "--ignore-matching-lines=^\\\"POT-Creation-Date"
result = self.run_command("diff -u %s %s %s" % (options, f1, f2))
- return self.assertEqual(result[1], "", result[1])
+ self.assertEqual(result['output'], "", result['output'])
- def _test_pot_generation(self, start_file, reference_pot=None):
+ def _test_pot_generation(self, start_file, reference_pot=None, expected_status=0):
start_file_base = os.path.splitext(start_file)[0]
result = self.run_command("cd %(dir)s && python itstool_test -o %(out)s %(in)s" % {
'dir' : ITSTOOL_DIR,
'out' : os.path.join('tests', "test.pot"),
'in' : os.path.join('tests', start_file),
- })
+ }, expected_status)
# If a reference pot file is present, test the output with this file
if reference_pot is None:
reference_pot = start_file_base + ".pot"
if os.path.exists(os.path.join(TEST_DIR, reference_pot)):
self.assertFilesEqual(os.path.join(TEST_DIR, "test.pot"), os.path.join(TEST_DIR, reference_pot))
+ return result
- def _test_translation_process(self, start_file):
+ def _test_translation_process(self, start_file, expected_status=0, po_file=None):
start_file_base = os.path.splitext(start_file)[0]
self._test_pot_generation(start_file)
# Compile mo and merge
- self.run_command("cd %(dir)s && msgfmt -o test.mo %(base)s.ll.po" % {'dir': TEST_DIR, 'base': start_file_base})
- res = self.run_command("cd %(dir)s && python itstool_test -m %(mo)s -o %(res)s %(src)s" % {
+ if po_file is None:
+ po_file = "%s.ll.po" % start_file_base
+ self.run_command("cd %(dir)s && msgfmt -o test.mo %(po_file)s" % {'dir': TEST_DIR, 'po_file': po_file})
+ result = self.run_command("cd %(dir)s && python itstool_test -m %(mo)s -o %(res)s %(src)s" % {
'dir': ITSTOOL_DIR,
'mo' : os.path.join(TEST_DIR, "test.mo"),
'res': os.path.join(TEST_DIR, "test.xml"),
'src': os.path.join(TEST_DIR, start_file),
- })
- self.assertFilesEqual(os.path.join(TEST_DIR, "test.xml"), os.path.join(TEST_DIR, "%s.ll.xml" % start_file_base))
+ }, expected_status)
+ if (expected_status == 0):
+ self.assertFilesEqual(
+ os.path.join(TEST_DIR, "test.xml"),
+ os.path.join(TEST_DIR, "%s.ll.xml" % start_file_base)
+ )
+ return result
def test_locnotes(self):
@@ -123,6 +131,17 @@ class ItstoolTests(unittest.TestCase):
def test_deep_placeholder(self):
self._test_translation_process('Placeholder.xml')
+ def test_bad_file(self):
+ """ Test that a malformed XML generates a proper exception """
+ res = self._test_pot_generation('Malformed.xml', expected_status=1)
+ self.assertTrue("libxml2.parserError" in res['errors'])
+
+ def test_bad_translation(self):
+ """ Test that bad XML syntax in translation generates a proper exception """
+ res = self._test_translation_process('Translate3.xml', expected_status=1, po_file='Translate3.ll.wrong.po')
+ self.assertTrue("libxml2.parserError" in res['errors'])
+
+
class ITSTestRunner(unittest.TextTestRunner):
def run(self, test):
# Global setup