From c861ccb463957e3319105cdbad8ff79b81cd337f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Cl=C3=A9rice?= Date: Sat, 23 Sep 2017 12:21:28 +0200 Subject: [PATCH] Fixed #111 : Covering xml:lang on /text --- CHANGES.txt | 5 ++ HookTest/capitains_units/cts.py | 38 +++++++------ tests/test_cts/__init__.py | 0 tests/test_cts/mocks/__init__.py | 0 tests/test_cts/mocks/xmllang_data.py | 80 ++++++++++++++++++++++++++++ tests/test_cts/test_unit.py | 41 ++++++++++++++ 6 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 tests/test_cts/__init__.py create mode 100644 tests/test_cts/mocks/__init__.py create mode 100644 tests/test_cts/mocks/xmllang_data.py create mode 100644 tests/test_cts/test_unit.py diff --git a/CHANGES.txt b/CHANGES.txt index e0b42fe..594687f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,8 @@ +## 1.1.5 - 2017-09-23 + +- ( Added a fix for #111 ) Refactored language test unit to cover all cases of guidelines +- Started refactoring a little some unit tests, with example generations. + ## 1.1.4 - 2017-09-19 - Updated RNG checks for compatibility with _JAVA_OPTIONS environment variable on Travis diff --git a/HookTest/capitains_units/cts.py b/HookTest/capitains_units/cts.py index 71e6c91..f9e3f34 100644 --- a/HookTest/capitains_units/cts.py +++ b/HookTest/capitains_units/cts.py @@ -585,27 +585,25 @@ def language(self): """ Tests to make sure an xml:lang element is on the correct node """ if self.scheme == "epidoc": - try: - self.lang = self.xml.xpath('/tei:TEI/tei:text/tei:body/tei:div[@type="edition" or @type="translation" or @type="commentary"]', - namespaces=TESTUnit.NS)[0].get('{http://www.w3.org/XML/1998/namespace}lang') - except: - self.lang = '' - if self.lang == '' or self.lang is None: - self.lang = 'UNK' - yield False - else: - yield True + urns_holding_node = self.xml.xpath( + "//tei:text/tei:body/tei:div" + "[@type='edition' or @type='translation' or @type='commentary']" + "[starts-with(@n, 'urn:cts:')]", + namespaces=TESTUnit.NS + ) elif self.scheme == "tei": - try: - self.lang = self.xml.xpath('/tei:TEI/tei:text/tei:body', - namespaces=TESTUnit.NS)[0].get('{http://www.w3.org/XML/1998/namespace}lang') - except: - self.lang = '' - if self.lang == '' or self.lang is None: - self.lang = 'UNK' - yield False - else: - yield True + urns_holding_node = self.xml.xpath("//tei:text/tei:body[starts-with(@n, 'urn:cts:')]", namespaces=TESTUnit.NS) + \ + self.xml.xpath("//tei:text[starts-with(@xml:base, 'urn:cts:')]", namespaces=TESTUnit.NS) + + try: + self.lang = urns_holding_node[0].get('{http://www.w3.org/XML/1998/namespace}lang') + except: + self.lang = '' + if self.lang == '' or self.lang is None: + self.lang = 'UNK' + yield False + else: + yield True def test(self, scheme, inventory=None): """ Test a file with various checks diff --git a/tests/test_cts/__init__.py b/tests/test_cts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_cts/mocks/__init__.py b/tests/test_cts/mocks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_cts/mocks/xmllang_data.py b/tests/test_cts/mocks/xmllang_data.py new file mode 100644 index 0000000..407e2d0 --- /dev/null +++ b/tests/test_cts/mocks/xmllang_data.py @@ -0,0 +1,80 @@ +from MyCapytain.common.utils import xmlparser +from lxml.etree import tostring + +TEMPLATES = """ + + + + + + + + +
+
""" +URN = "urn:cts:latinLit:phi1294.phi002.perseus-lat2" +LANG = "lat" + +# The following variable is a list of element with error that they should throw and status (XML_OBJECT, STATUS, ERROR) +XMLLANG_DOCUMENTS = [ + ("tei", "", "", True, "TEI works with urn and xml lang on @base/text"), + ("tei", "", "", False, "TEI fails with urn and xml lang on @n/text"), + ("tei", "", "", False, "TEI fails with urn without xml lang on @base/text"), + ("tei", "", "", False, "TEI fails with urn without xml lang on @n/text"), + + ("epidoc", "", "", False, "Epidoc fails with urn and xml lang on @base/text"), + ("epidoc", "", "", False, "Epidoc fails with urn and xml lang on @n/text"), + ("epidoc", "", "", False, "Epidoc fails with urn without xml lang on @base/text"), + ("epidoc", "", "", False, "Epidoc fails with urn without xml lang on @n/text"), + + ("tei", "", "", False, "TEI fails with urn and xml lang on @base/body"), + ("tei", "", "", True, "TEI works with urn and xml lang on @n/body"), + ("tei", "", "", False, "TEI fails with urn without xml lang on @base/body"), + ("tei", "", "", False, "TEI fails with urn without xml lang on @n/body"), + + ("epidoc", "", "", False, "Epidoc fails with urn and xml lang on @base/body"), + ("epidoc", "", "", False, "Epidoc fails with urn and xml lang on @n/body"), + ("epidoc", "", "", False, "Epidoc fails with urn without xml lang on @base/body"), + ("epidoc", "", "", False, "Epidoc fails with urn without xml lang on @n/body"), + +] +# Epidocs Tests +XMLLANG_DOCUMENTS += [ + (scheme, source, replacement.replace("{epidoc}", type_epidoc), boolean, message.replace("{epidoc}", type_epidoc)) + for scheme, source, replacement, boolean, message in + [ + ("tei", "
", "
", False, + "TEI fails with urn and xml lang on @n/div-{epidoc}"), + + ("tei", "
", "
", False, + "TEI fails with urn and xml lang on @xml:base/div-{epidoc}"), + + ("tei", "
", "
", False, + "TEI fails with urn and without xml lang on @n/div-{epidoc}"), + + ("tei", "
", "
", False, + "TEI fails with urn and without xml lang on @xml:base/div-{epidoc}"), + + ("epidoc", "
", "
", True, + "Epidoc works with urn and xml lang on @n/div-{epidoc}"), + + ("epidoc", "
", "
", False, + "Epidoc fails with urn and xml lang on @xml:base/div-{epidoc}"), + + ("epidoc", "
", "
", False, + "Epidoc fails with urn and without xml lang on @n/div-{epidoc}"), + + ("epidoc", "
", "
", False, + "Epidoc fails with urn and without xml lang on @xml:base/div-{epidoc}") + ] + for type_epidoc in ["edition", "translation", "commentary"] +] +XMLLANG_DOCUMENTS = [ + ( + scheme, + tostring(xmlparser(TEMPLATES.replace(source, replacement).format(urn=URN, lang=LANG)), encoding=str), + boolean, + msg + " ("+replacement.format(urn=URN, lang=LANG)+")" + ) + for scheme, source, replacement, boolean, msg in XMLLANG_DOCUMENTS +] \ No newline at end of file diff --git a/tests/test_cts/test_unit.py b/tests/test_cts/test_unit.py new file mode 100644 index 0000000..e0d89f3 --- /dev/null +++ b/tests/test_cts/test_unit.py @@ -0,0 +1,41 @@ +import unittest +import HookTest.capitains_units.cts +import HookTest.units +import tests.test_cts.mocks.xmllang_data as CAPITAINS_MOCKS +from lxml import etree + +class TestCTS(unittest.TestCase): + """ Test the UnitTest for __cts__ + """ + pass + + +class TestText(unittest.TestCase): + """ Test the UnitTests for Text + """ + + def setUp(self): + self.backup = [x for x in HookTest.capitains_units.cts.CTSText_TestUnit.tests] + + def tearDown(self): + HookTest.capitains_units.cts.CTSText_TestUnit.tests = self.backup + + def unit_from_string(self, xml_string, scheme): + """ Generates a test unit based on xml_string and scheme + + :param xml_string: String representation of the XML Document + :param scheme: Scheme to apply + :return: HookTest.capitains_units.cts.CTSText_TestUnit + """ + node = HookTest.capitains_units.cts.CTSText_TestUnit("/false/path") + node.scheme = scheme + node.xml = etree.fromstring(xml_string, HookTest.units.TESTUnit.PARSER) + return node + + def test_xml_lang(self): + """ Ensure the XML:LANG test checks against the guideline + """ + for scheme, xml, status, message in CAPITAINS_MOCKS.XMLLANG_DOCUMENTS: + unit = self.unit_from_string(xml, scheme) + results = [result for result in unit.language()] + self.assertEqual(results[0], status, message)