diff --git a/hed/schema/hed_schema.py b/hed/schema/hed_schema.py index d32413aa..935de4b8 100644 --- a/hed/schema/hed_schema.py +++ b/hed/schema/hed_schema.py @@ -113,6 +113,15 @@ def unit_classes(self): """ return self._sections[HedSectionKey.UnitClasses] + @property + def units(self): + """ Return the unit schema section. + + Returns: + HedSchemaSection: The unit section. + """ + return self._sections[HedSectionKey.Units] + @property def unit_modifiers(self): """ Return the modifiers classes schema section @@ -364,9 +373,9 @@ def __eq__(self, other): return False if self.has_duplicates() != other.has_duplicates(): return False - if self.prologue != other.prologue: + if self.prologue.strip() != other.prologue.strip(): return False - if self.epilogue != other.epilogue: + if self.epilogue.strip() != other.epilogue.strip(): return False if self._sections != other._sections: # This block is useful for debugging when modifying the schema class itself. diff --git a/hed/schema/hed_schema_io.py b/hed/schema/hed_schema_io.py index 63a751d8..e7b43830 100644 --- a/hed/schema/hed_schema_io.py +++ b/hed/schema/hed_schema_io.py @@ -45,6 +45,9 @@ def from_string(schema_string, schema_format=".xml", schema_namespace=None, sche raise HedFileError(HedExceptions.BAD_PARAMETERS, "Empty string passed to HedSchema.from_string", filename=schema_string) + # Replace carriage returns with new lines since this might not be done by the caller + schema_string = schema_string.replace("\r\n", "\n") + if schema_format.endswith(".xml"): hed_schema = SchemaLoaderXML.load(schema_as_string=schema_string, schema=schema) elif schema_format.endswith(".mediawiki"): diff --git a/hed/schema/schema_compliance.py b/hed/schema/schema_compliance.py index 1a68baf8..439f5d1d 100644 --- a/hed/schema/schema_compliance.py +++ b/hed/schema/schema_compliance.py @@ -124,4 +124,12 @@ def check_invalid_chars(self): for tag_name, desc in self.hed_schema.get_desc_iter(): issues_list += validate_schema_description(tag_name, desc) + + # todo Activate this session once we have clearer rules on spaces in unit names + # for unit in self.hed_schema.units: + # for i, char in enumerate(unit): + # if char == " ": + # issues_list += ErrorHandler.format_error(SchemaWarnings.SCHEMA_INVALID_CHARACTERS_IN_TAG, + # unit, char_index=i, problem_char=char) + return issues_list diff --git a/tests/schema/test_schema_converters.py b/tests/schema/test_schema_converters.py index 90d69d65..9073e50e 100644 --- a/tests/schema/test_schema_converters.py +++ b/tests/schema/test_schema_converters.py @@ -29,170 +29,181 @@ def wrapper(*args, **kwargs): return decorator -# class TestConverterBase(unittest.TestCase): -# xml_file = '../data/schema_tests/HED8.2.0.xml' -# wiki_file = '../data/schema_tests/HED8.2.0.mediawiki' -# can_compare = True -# -# @classmethod -# def setUpClass(cls): -# cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) -# cls.hed_schema_xml = schema.load_schema(cls.xml_file) -# cls.wiki_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.wiki_file) -# cls.hed_schema_wiki = schema.load_schema(cls.wiki_file) -# -# @with_temp_file(".xml") -# def test_schema2xml(self, filename): -# self.hed_schema_xml.save_as_xml(filename) -# loaded_schema = schema.load_schema(filename) -# -# self.assertEqual(loaded_schema, self.hed_schema_xml) -# -# @with_temp_file(".mediawiki") -# def test_schema2wiki(self, filename): -# self.hed_schema_xml.save_as_mediawiki(filename) -# loaded_schema = schema.load_schema(filename) -# -# self.assertEqual(loaded_schema, self.hed_schema_xml) -# -# def test_schema_as_string_xml(self): -# with open(self.xml_file) as file: -# hed_schema_as_string = "".join([line for line in file]) -# -# string_schema = schema.from_string(hed_schema_as_string) -# -# self.assertEqual(string_schema, self.hed_schema_xml) -# -# def test_schema_as_string_wiki(self): -# with open(self.wiki_file) as file: -# hed_schema_as_string = "".join([line for line in file]) -# -# string_schema = schema.from_string(hed_schema_as_string, schema_format=".mediawiki") -# self.assertEqual(string_schema, self.hed_schema_wiki) -# -# @with_temp_file(".xml") -# def test_wikischema2xml(self, filename): -# self.hed_schema_wiki.save_as_xml(filename) -# loaded_schema = schema.load_schema(filename) -# -# wiki_schema_copy = copy.deepcopy(self.hed_schema_wiki) -# -# self.assertEqual(loaded_schema, wiki_schema_copy) -# -# @with_temp_file(".mediawiki") -# def test_wikischema2wiki(self, filename): -# self.hed_schema_wiki.save_as_mediawiki(filename) -# loaded_schema = schema.load_schema(filename) -# -# self.assertEqual(loaded_schema, self.hed_schema_wiki) -# -# def test_compare_readers(self): -# if self.can_compare: -# self.assertEqual(self.hed_schema_wiki, self.hed_schema_xml) -# -# -# class TestComplianceBase(unittest.TestCase): -# xml_file_old = '../data/schema_tests/HED8.0.0t.xml' -# xml_file = '../data/schema_tests/HED8.2.0.xml' -# wiki_file = '../data/schema_tests/HED8.2.0.mediawiki' -# can_compare = True -# expected_issues = 0 -# -# @classmethod -# def setUpClass(cls): -# cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) -# cls.hed_schema_xml = schema.load_schema(cls.xml_file) -# cls.wiki_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.wiki_file) -# cls.hed_schema_wiki = schema.load_schema(cls.wiki_file) -# cls.xml_file_old = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file_old) -# cls.hed_schema_xml_old = schema.load_schema(cls.xml_file_old) -# def test_compliance(self): -# issues = self.hed_schema_wiki.check_compliance() -# self.assertEqual(len(issues), self.expected_issues) -# issues_old = self.hed_schema_xml_old.check_compliance() -# self.assertGreater(len(issues_old), 0) -# -# def test_compare_readers(self): -# self.assertNotEqual(self.hed_schema_xml, self.hed_schema_xml_old) -# if self.can_compare: -# self.assertEqual(self.hed_schema_wiki, self.hed_schema_xml) -# -# -# class TestPropertyAdded(TestConverterBase): -# xml_file = '../data/schema_tests/added_prop.xml' -# wiki_file = '../data/schema_tests/added_prop.mediawiki' -# can_compare = True -# -# -# class TestPropertyAddedUsage(TestConverterBase): -# xml_file = '../data/schema_tests/added_prop_with_usage.xml' -# wiki_file = '../data/schema_tests/added_prop_with_usage.mediawiki' -# can_compare = True -# -# -# class TestHedUnknownAttr(TestConverterBase): -# xml_file = '../data/schema_tests/unknown_attribute.xml' -# wiki_file = '../data/schema_tests/unknown_attribute.mediawiki' -# can_compare = True -# -# -# class TestHedMultiValueClass(TestConverterBase): -# xml_file = '../data/schema_tests/HED8.0.0_2_value_classes.xml' -# wiki_file = '../data/schema_tests/HED8.0.0_2_value_classes.mediawiki' -# can_compare = True -# -# -# class TestPrologueIssues1(TestConverterBase): -# xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_end.xml' -# wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_end.mediawiki' -# can_compare = True -# -# -# class TestPrologueIssues2(TestConverterBase): -# xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_middle.xml' -# wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_middle.mediawiki' -# can_compare = True -# -# -# class TestPrologueIssues3(TestConverterBase): -# xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_start.xml' -# wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_start.mediawiki' -# can_compare = True -# -# -# class TestPrologueIssues4(TestConverterBase): -# xml_file = '../data/schema_tests/prologue_tests/test_no_blank_line.xml' -# wiki_file = '../data/schema_tests/prologue_tests/test_no_blank_line.mediawiki' -# can_compare = True -# -# -# class TestDuplicateUnitCompliance(TestComplianceBase): -# xml_file = '../data/schema_tests/duplicate_unit.xml' -# wiki_file = '../data/schema_tests/duplicate_unit.mediawiki' -# can_compare = True -# expected_issues = 1 -# -# -# class TestDuplicateUnitClass(TestComplianceBase): -# xml_file = '../data/schema_tests/duplicate_unit_class.xml' -# wiki_file = '../data/schema_tests/duplicate_unit_class.mediawiki' -# can_compare = True -# expected_issues = 1 -# -# -# -# class TestConverterSavingPrefix(unittest.TestCase): -# xml_file = '../data/schema_tests/HED8.0.0t.xml' -# -# @classmethod -# def setUpClass(cls): -# cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) -# cls.hed_schema_xml = schema.load_schema(cls.xml_file) -# cls.hed_schema_xml_prefix = schema.load_schema(cls.xml_file, schema_namespace="tl:") -# -# @with_temp_file(".xml") -# def test_saving_prefix(self, filename): -# self.hed_schema_xml_prefix.save_as_xml(filename) -# loaded_schema = schema.load_schema(filename) -# -# self.assertEqual(loaded_schema, self.hed_schema_xml) +class TestConverterBase(unittest.TestCase): + xml_file = '../data/schema_tests/HED8.2.0.xml' + wiki_file = '../data/schema_tests/HED8.2.0.mediawiki' + can_compare = True + + @classmethod + def setUpClass(cls): + cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) + cls.hed_schema_xml = schema.load_schema(cls.xml_file) + cls.wiki_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.wiki_file) + cls.hed_schema_wiki = schema.load_schema(cls.wiki_file) + + # !BFK! - Delete default units as they aren't in the XML file. + if "HED8.2.0" in cls.wiki_file: + del cls.hed_schema_wiki.unit_classes["temperatureUnits"].attributes["defaultUnits"] + + @with_temp_file(".xml") + def test_schema2xml(self, filename): + self.hed_schema_xml.save_as_xml(filename) + loaded_schema = schema.load_schema(filename) + + self.assertEqual(loaded_schema, self.hed_schema_xml) + + @with_temp_file(".mediawiki") + def test_schema2wiki(self, filename): + self.hed_schema_xml.save_as_mediawiki(filename) + loaded_schema = schema.load_schema(filename) + + self.assertEqual(loaded_schema, self.hed_schema_xml) + + def test_schema_as_string_xml(self): + with open(self.xml_file) as file: + hed_schema_as_string = "".join([line for line in file]) + + string_schema = schema.from_string(hed_schema_as_string) + + self.assertEqual(string_schema, self.hed_schema_xml) + + def test_schema_as_string_wiki(self): + with open(self.wiki_file) as file: + hed_schema_as_string = "".join([line for line in file]) + + string_schema = schema.from_string(hed_schema_as_string, schema_format=".mediawiki") + #!BFK! - Same as before, 8.2.0 has a difference + if "HED8.2.0" in self.wiki_file: + del string_schema.unit_classes["temperatureUnits"].attributes["defaultUnits"] + + self.assertEqual(string_schema, self.hed_schema_wiki) + + @with_temp_file(".xml") + def test_wikischema2xml(self, filename): + self.hed_schema_wiki.save_as_xml(filename) + loaded_schema = schema.load_schema(filename) + + wiki_schema_copy = copy.deepcopy(self.hed_schema_wiki) + + self.assertEqual(loaded_schema, wiki_schema_copy) + + @with_temp_file(".mediawiki") + def test_wikischema2wiki(self, filename): + self.hed_schema_wiki.save_as_mediawiki(filename) + loaded_schema = schema.load_schema(filename) + + self.assertEqual(loaded_schema, self.hed_schema_wiki) + + def test_compare_readers(self): + if self.can_compare: + self.assertEqual(self.hed_schema_wiki, self.hed_schema_xml) + + +class TestComplianceBase(unittest.TestCase): + xml_file_old = '../data/schema_tests/HED8.0.0t.xml' + xml_file = '../data/schema_tests/HED8.2.0.xml' + wiki_file = '../data/schema_tests/HED8.2.0.mediawiki' + can_compare = True + expected_issues = 0 + + @classmethod + def setUpClass(cls): + cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) + cls.hed_schema_xml = schema.load_schema(cls.xml_file) + cls.wiki_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.wiki_file) + cls.hed_schema_wiki = schema.load_schema(cls.wiki_file) + if "HED8.2.0" in cls.wiki_file: + del cls.hed_schema_wiki.unit_classes["temperatureUnits"].attributes["defaultUnits"] + cls.xml_file_old = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file_old) + cls.hed_schema_xml_old = schema.load_schema(cls.xml_file_old) + + def test_compliance(self): + issues = self.hed_schema_wiki.check_compliance() + self.assertEqual(len(issues), self.expected_issues) + issues_old = self.hed_schema_xml_old.check_compliance() + self.assertGreater(len(issues_old), 0) + + def test_compare_readers(self): + self.assertNotEqual(self.hed_schema_xml, self.hed_schema_xml_old) + if self.can_compare: + self.assertEqual(self.hed_schema_wiki, self.hed_schema_xml) + + +class TestPropertyAdded(TestConverterBase): + xml_file = '../data/schema_tests/added_prop.xml' + wiki_file = '../data/schema_tests/added_prop.mediawiki' + can_compare = True + + +class TestPropertyAddedUsage(TestConverterBase): + xml_file = '../data/schema_tests/added_prop_with_usage.xml' + wiki_file = '../data/schema_tests/added_prop_with_usage.mediawiki' + can_compare = True + + +class TestHedUnknownAttr(TestConverterBase): + xml_file = '../data/schema_tests/unknown_attribute.xml' + wiki_file = '../data/schema_tests/unknown_attribute.mediawiki' + can_compare = True + + +class TestHedMultiValueClass(TestConverterBase): + xml_file = '../data/schema_tests/HED8.0.0_2_value_classes.xml' + wiki_file = '../data/schema_tests/HED8.0.0_2_value_classes.mediawiki' + can_compare = True + + +class TestPrologueIssues1(TestConverterBase): + xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_end.xml' + wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_end.mediawiki' + can_compare = True + + +class TestPrologueIssues2(TestConverterBase): + xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_middle.xml' + wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_middle.mediawiki' + can_compare = True + + +class TestPrologueIssues3(TestConverterBase): + xml_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_start.xml' + wiki_file = '../data/schema_tests/prologue_tests/test_extra_blank_line_start.mediawiki' + can_compare = True + + +class TestPrologueIssues4(TestConverterBase): + xml_file = '../data/schema_tests/prologue_tests/test_no_blank_line.xml' + wiki_file = '../data/schema_tests/prologue_tests/test_no_blank_line.mediawiki' + can_compare = True + + +class TestDuplicateUnitCompliance(TestComplianceBase): + xml_file = '../data/schema_tests/duplicate_unit.xml' + wiki_file = '../data/schema_tests/duplicate_unit.mediawiki' + can_compare = True + expected_issues = 1 + + +class TestDuplicateUnitClass(TestComplianceBase): + xml_file = '../data/schema_tests/duplicate_unit_class.xml' + wiki_file = '../data/schema_tests/duplicate_unit_class.mediawiki' + can_compare = True + expected_issues = 1 + + + +class TestConverterSavingPrefix(unittest.TestCase): + xml_file = '../data/schema_tests/HED8.0.0t.xml' + + @classmethod + def setUpClass(cls): + cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) + cls.hed_schema_xml = schema.load_schema(cls.xml_file) + cls.hed_schema_xml_prefix = schema.load_schema(cls.xml_file, schema_namespace="tl:") + + @with_temp_file(".xml") + def test_saving_prefix(self, filename): + self.hed_schema_xml_prefix.save_as_xml(filename) + loaded_schema = schema.load_schema(filename) + + self.assertEqual(loaded_schema, self.hed_schema_xml)