diff options
author | Shaun McCance <shaunm@gnome.org> | 2011-09-03 13:21:09 -0400 |
---|---|---|
committer | Shaun McCance <shaunm@gnome.org> | 2011-09-03 13:21:09 -0400 |
commit | 0520144626db679e81725aebfaba273a52fd0bf4 (patch) | |
tree | bda0095be8d25969373b8f6afa0f7c7527e0f911 | |
parent | 092a26470a5032c85ba8a40570ee6fd6c9fe9b30 (diff) | |
parent | 7e0739641507d92e1d2ec7e9b7f5e5c7c09a940a (diff) | |
download | itstool-0520144626db679e81725aebfaba273a52fd0bf4.tar.gz |
Merge: Proper XML error catching [claude]
-rwxr-xr-x | itstool.in | 11 | ||||
-rw-r--r-- | tests/Malformed.xml | 6 | ||||
-rw-r--r-- | tests/Translate3.ll.wrong.po | 19 | ||||
-rw-r--r-- | tests/run_tests.py | 41 |
4 files changed, 66 insertions, 11 deletions
@@ -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 |