summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2011-08-17 12:10:36 +0200
committerClaude Paroz <claude@2xlibre.net>2011-08-17 12:10:36 +0200
commit1abdf1b0d83b37a9f298563e139c118c9a62629b (patch)
tree1ef390970054afd615f395e030ce405e72588181
parent187fcbe585560f128c7436e66f6b8e3a789a73b0 (diff)
downloaditstool-1abdf1b0d83b37a9f298563e139c118c9a62629b.tar.gz
Catch XML parsing errors so itstool does properly exit with error code
-rwxr-xr-xitstool.in10
-rw-r--r--tests/Malformed.xml6
-rw-r--r--tests/run_tests.py18
3 files changed, 28 insertions, 6 deletions
diff --git a/itstool.in b/itstool.in
index 2401918..ff0ac46 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
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/run_tests.py b/tests/run_tests.py
index e8b009e..d935b52 100644
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -14,34 +14,35 @@ 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(), 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):
start_file_base = os.path.splitext(start_file)[0]
@@ -120,6 +121,11 @@ class ItstoolTests(unittest.TestCase):
def test_context(self):
self._test_translation_process('Context.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'])
+
class ITSTestRunner(unittest.TextTestRunner):
def run(self, test):