diff --git a/hed/errors/error_messages.py b/hed/errors/error_messages.py index a8c5dd170..3591bae83 100644 --- a/hed/errors/error_messages.py +++ b/hed/errors/error_messages.py @@ -245,7 +245,7 @@ def schema_error_hed_duplicate_node(tag, duplicate_tag_list, section): f"{tag_join_delimiter}{tag_join_delimiter.join(duplicate_tag_list)}" -@hed_error(SchemaErrors.HED_SCHEMA_ATTRIBUTE_INVALID) +@hed_error(SchemaErrors.SCHEMA_ATTRIBUTE_INVALID) def schema_error_unknown_attribute(attribute_name, source_tag): return f"Attribute '{attribute_name}' used by '{source_tag}' was not defined in the schema, " \ f"or was used outside of it's defined class." diff --git a/hed/errors/error_types.py b/hed/errors/error_types.py index fc3aa3788..18418a4f2 100644 --- a/hed/errors/error_types.py +++ b/hed/errors/error_types.py @@ -107,7 +107,7 @@ class SidecarErrors: class SchemaErrors: HED_SCHEMA_DUPLICATE_NODE = 'HED_SCHEMA_DUPLICATE_NODE' - HED_SCHEMA_ATTRIBUTE_INVALID = 'HED_SCHEMA_ATTRIBUTE_INVALID' + SCHEMA_ATTRIBUTE_INVALID = 'SCHEMA_ATTRIBUTE_INVALID' HED_SCHEMA_DUPLICATE_FROM_LIBRARY = "SCHEMA_LIBRARY_INVALID" diff --git a/hed/models/hed_group.py b/hed/models/hed_group.py index 9a4af46b1..10ea9a360 100644 --- a/hed/models/hed_group.py +++ b/hed/models/hed_group.py @@ -36,10 +36,6 @@ def append(self, tag_or_group): Parameters: tag_or_group (HedTag or HedGroup): The new object to add to this group. - - :raises ValueError: - If a HedGroupFrozen. - """ tag_or_group._parent = self self._children.append(tag_or_group) @@ -469,11 +465,6 @@ def find_exact_tags(self, tags_or_groups, recursive=False, include_groups=1): - This can only find identified tags. - By default, definition, def, def-expand, onset, and offset are identified, even without a schema. - If this is a HedGroup, order matters. (b, a) != (a, b) - - If this is a HedGroupFrozen: - if "(a, b)" in tags_or_groups, then it will match 1 and 2, but not 3. - 1. (a, b) - 2. (b, a) - 3. (a, b, c) """ found_tags = [] diff --git a/hed/schema/hed_cache.py b/hed/schema/hed_cache.py index 51c0f9ef4..793cd6d85 100644 --- a/hed/schema/hed_cache.py +++ b/hed/schema/hed_cache.py @@ -270,7 +270,7 @@ def cache_xml_versions(hed_base_urls=DEFAULT_URL_LIST, skip_folders=DEFAULT_SKIP _cache_hed_version(version, library_name, version_info, cache_folder=cache_folder) _write_last_cached_time(current_timestamp, cache_folder) - except portalocker.exceptions.LockException: + except portalocker.exceptions.LockException or ValueError: return -1 return 0 @@ -303,6 +303,8 @@ def _write_last_cached_time(new_time, cache_folder): new_time (float): The time this was updated. cache_folder (str): The folder used for caching the hed schema. + :raises ValueError: + - something went wrong writing to the file """ timestamp_filename = os.path.join(cache_folder, TIMESTAMP_FILENAME) try: diff --git a/hed/schema/hed_schema_group.py b/hed/schema/hed_schema_group.py index ab2112b7a..00bc2f78b 100644 --- a/hed/schema/hed_schema_group.py +++ b/hed/schema/hed_schema_group.py @@ -27,8 +27,8 @@ def __init__(self, schema_list): HedSchemaGroup: the container created. :raises HedFileError: - - If multiple schemas have the same library prefixes. - + - Multiple schemas have the same library prefixes. + - Empty list passed """ if len(schema_list) == 0: raise HedFileError(HedExceptions.BAD_PARAMETERS, "Empty list passed to HedSchemaGroup constructor.", diff --git a/hed/schema/hed_schema_io.py b/hed/schema/hed_schema_io.py index 07e59dcf5..f26ee7c6e 100644 --- a/hed/schema/hed_schema_io.py +++ b/hed/schema/hed_schema_io.py @@ -24,6 +24,7 @@ def from_string(schema_string, file_type=".xml", schema_namespace=None): :raises HedFileError: - If empty string or invalid extension is passed. + - Other fatal formatting issues with file Notes: - The loading is determined by file type. @@ -79,7 +80,9 @@ def load_schema(hed_path=None, schema_namespace=None): HedSchema: The loaded schema. :raises HedFileError: - - If there are any fatal issues when loading the schema. + - Empty path passed + - Unknown extension + - Any fatal issues when loading the schema. """ if not hed_path: @@ -114,6 +117,8 @@ def get_hed_xml_version(xml_file_path): Returns: str: The version number of the HED XML file. + :raises HedFileError: + - There is an issue loading the schema """ root_node = HedSchemaXMLParser._parse_hed_xml(xml_file_path) return root_node.attrib[hed_schema_constants.VERSION_ATTRIBUTE] @@ -130,10 +135,9 @@ def _load_schema_version(xml_version=None, xml_folder=None): HedSchema or HedSchemaGroup: The requested HedSchema object. :raises HedFileError: - - If the xml_version is not valid. - - Notes: - - The library schema files have names of the form HED_(LIBRARY_NAME)_(version).xml. + - The xml_version is not valid. + - The specified version cannot be found or loaded + - Other fatal errors loading the schema (These are unlikely if you are not editing them locally) """ schema_namespace = "" library_name = None @@ -179,10 +183,8 @@ def load_schema_version(xml_version=None, xml_folder=None): HedSchema or HedSchemaGroup: The schema or schema group extracted. :raises HedFileError: - - If the xml_version is not valid. - - Notes: - - Loads the latest schema value if an empty version is given (string or list). + - The xml_version is not valid. + - A fatal error was encountered in parsing """ if xml_version and isinstance(xml_version, list): schemas = [_load_schema_version(xml_version=version, xml_folder=xml_folder) for version in xml_version] diff --git a/hed/schema/schema_compliance.py b/hed/schema/schema_compliance.py index ddb222663..9f372cdb5 100644 --- a/hed/schema/schema_compliance.py +++ b/hed/schema/schema_compliance.py @@ -21,9 +21,8 @@ def check_compliance(hed_schema, check_for_warnings=True, name=None, error_handl Returns: list: A list of all warnings and errors found in the file. Each issue is a dictionary. - Notes: - - Useful for temp filenames in support of web services. - + :raises ValueError: + - Trying to validate a HedSchemaGroup directly """ if not isinstance(hed_schema, HedSchema): raise ValueError("To check compliance of a HedGroupSchema, call self.check_compliance on the schema itself.") @@ -40,7 +39,7 @@ def check_compliance(hed_schema, check_for_warnings=True, name=None, error_handl if unknown_attributes: for attribute_name, source_tags in unknown_attributes.items(): for tag in source_tags: - issues_list += error_handler.format_error_with_context(SchemaErrors.HED_SCHEMA_ATTRIBUTE_INVALID, + issues_list += error_handler.format_error_with_context(SchemaErrors.SCHEMA_ATTRIBUTE_INVALID, attribute_name, source_tag=tag) @@ -62,7 +61,10 @@ def check_compliance(hed_schema, check_for_warnings=True, name=None, error_handl validator = schema_attribute_validators.get(attribute_name) if validator: error_handler.push_error_context(ErrorContext.SCHEMA_ATTRIBUTE, attribute_name) - new_issues = validator(hed_schema, tag_entry, tag_entry.attributes[attribute_name]) + new_issues = validator(hed_schema, tag_entry, attribute_name) + # if force_issues_as_warnings: + for issue in new_issues: + issue['severity'] = ErrorSeverity.WARNING error_handler.add_context_and_filter(new_issues) issues_list += new_issues error_handler.pop_error_context() @@ -75,8 +77,7 @@ def check_compliance(hed_schema, check_for_warnings=True, name=None, error_handl if len(values) == 2: error_code = SchemaErrors.HED_SCHEMA_DUPLICATE_FROM_LIBRARY issues_list += error_handler.format_error_with_context(error_code, name, - duplicate_tag_list=[entry.name for entry in - duplicate_entries], + duplicate_tag_list=[entry.name for entry in duplicate_entries], section=section_key) error_handler.pop_error_context() @@ -92,15 +93,19 @@ def check_compliance(hed_schema, check_for_warnings=True, name=None, error_handl error_handler.pop_error_context() return issues_list +# attribute_checker_template(hed_schema, tag_entry, attribute_name, possible_values): +# hed_schema (HedSchema): The schema to use for validation +# tag_entry (HedSchemaEntry): The schema entry for this tag. +# attribute_name (str): The name of this attribute + -def tag_is_placeholder_check(hed_schema, tag_entry, possible_tags, force_issues_as_warnings=True): +def tag_is_placeholder_check(hed_schema, tag_entry, attribute_name): """ Check if comma separated list has valid HedTags. Parameters: - hed_schema (HedSchema): The schema to check if the tag exists. + hed_schema (HedSchema): The schema to use for validation tag_entry (HedSchemaEntry): The schema entry for this tag. - possible_tags (str): Comma separated list of tags. Short long or mixed form valid. - force_issues_as_warnings (bool): If True sets all the severity levels to warning. + attribute_name (str): The name of this attribute Returns: list: A list of issues. Each issue is a dictionary. @@ -109,91 +114,55 @@ def tag_is_placeholder_check(hed_schema, tag_entry, possible_tags, force_issues_ issues = [] if not tag_entry.name.endswith("/#"): issues += ErrorHandler.format_error(SchemaWarnings.NON_PLACEHOLDER_HAS_CLASS, tag_entry.name, - possible_tags) - - if force_issues_as_warnings: - for issue in issues: - issue['severity'] = ErrorSeverity.WARNING - - return issues - - -def attribute_does_not_exist_check(hed_schema, tag_entry, attribute_name, force_issues_as_warnings=True): - """ Throws an error saying this is a bad attribute if found. - - Parameters: - hed_schema (HedSchema): The schema to check if the tag exists. - tag_entry (HedSchemaEntry): The schema entry for this tag. - attribute_name (str): the attribute name we're looking for - force_issues_as_warnings (bool): If True sets all the severity levels to warning. - - Returns: - list: A list of issues. Each issue is a dictionary. - - """ - issues = [] - issues += ErrorHandler.format_error(SchemaWarnings.INVALID_ATTRIBUTE, tag_entry.name, - attribute_name) - - if force_issues_as_warnings: - for issue in issues: - issue['severity'] = ErrorSeverity.WARNING + attribute_name) return issues -def tag_exists_check(hed_schema, tag_entry, possible_tags, force_issues_as_warnings=True): - """ Check if comma separated list are valid HedTags. +def tag_exists_check(hed_schema, tag_entry, attribute_name): + """ Check if the list of possible tags exists in the schema. Parameters: - hed_schema (HedSchema): The schema to check if the tag exists. + hed_schema (HedSchema): The schema to use for validation tag_entry (HedSchemaEntry): The schema entry for this tag. - possible_tags (str): Comma separated list of tags. Short long or mixed form valid. - force_issues_as_warnings (bool): If True, set all the severity levels to warning. + attribute_name (str): The name of this attribute Returns: list: A list of issues. Each issue is a dictionary. """ issues = [] + possible_tags = tag_entry.attributes.get(attribute_name, "") split_tags = possible_tags.split(",") for org_tag in split_tags: - if org_tag not in hed_schema.all_tags: + if org_tag and org_tag not in hed_schema.all_tags: issues += ErrorHandler.format_error(ValidationErrors.NO_VALID_TAG_FOUND, org_tag, index_in_tag=0, index_in_tag_end=len(org_tag)) - if force_issues_as_warnings: - for issue in issues: - issue['severity'] = ErrorSeverity.WARNING return issues -def tag_exists_base_schema_check(hed_schema, tag_entry, tag_name, force_issues_as_warnings=True): +def tag_exists_base_schema_check(hed_schema, tag_entry, attribute_name): """ Check if the single tag is a partnered schema tag Parameters: - hed_schema (HedSchema): The schema to check if the tag exists. + hed_schema (HedSchema): The schema to use for validation tag_entry (HedSchemaEntry): The schema entry for this tag. - tag_name (str): The tag to verify, can be any form. - force_issues_as_warnings (bool): If True, set all the severity levels to warning. + attribute_name (str): The name of this attribute Returns: list: A list of issues. Each issue is a dictionary. - """ issues = [] - rooted_tag = tag_name.lower() - if rooted_tag not in hed_schema.all_tags: + rooted_tag = tag_entry.attributes.get(attribute_name, "") + if rooted_tag and rooted_tag not in hed_schema.all_tags: issues += ErrorHandler.format_error(ValidationErrors.NO_VALID_TAG_FOUND, rooted_tag, index_in_tag=0, index_in_tag_end=len(rooted_tag)) - if force_issues_as_warnings: - for issue in issues: - issue['severity'] = ErrorSeverity.WARNING return issues diff --git a/hed/schema/schema_validation_util.py b/hed/schema/schema_validation_util.py index 97376d380..17052a4d1 100644 --- a/hed/schema/schema_validation_util.py +++ b/hed/schema/schema_validation_util.py @@ -64,6 +64,18 @@ def is_hed3_version_number(version_string): def validate_present_attributes(attrib_dict, filename): + """ Validate combinations of attributes + + Parameters: + attrib_dict (dict): Dictionary of attributes to be evaluated. + filename (str): File name to use in reporting errors. + + Returns: + list: List of issues. Each issue is a dictionary. + + :raises HedFileError: + - withStandard is found in th header, but a library attribute is not specified + """ if constants.WITH_STANDARD_ATTRIBUTE in attrib_dict and constants.LIBRARY_ATTRIBUTE not in attrib_dict: raise HedFileError(HedExceptions.BAD_WITH_STANDARD, "withStandard header attribute found, but no library attribute is present", @@ -81,8 +93,9 @@ def validate_attributes(attrib_dict, filename): list: List of issues. Each issue is a dictionary. :raises HedFileError: - - If invalid or version not found in the dictionary. - + - Invalid library name + - Version not present + - Invalid combinations of attributes in header """ validate_present_attributes(attrib_dict, filename) @@ -111,9 +124,12 @@ def find_rooted_entry(tag_entry, schema, loading_merged): rooted_tag(HedTagEntry or None): The base tag entry from the standard schema Returns None if this tag isn't rooted - :raises HedValueError: - - If the tag doesn't exist or similar - + :raises HedFileError: + - A rooted attribute is found in a non-paired schema + - A rooted attribute is not a string + - A rooted attribute was found on a non-root node in an unmerged schema. + - A rooted attribute is found on a root node in a merged schema. + - A rooted attribute indicates a tag that doesn't exist in the base schema. """ rooted_tag = tag_entry.has_attribute(constants.HedKey.Rooted, return_value=True) if rooted_tag is not None: diff --git a/hed/tools/remodeling/operations/summarize_definitions_op.py b/hed/tools/remodeling/operations/summarize_definitions_op.py index bc988c5d3..43a104e09 100644 --- a/hed/tools/remodeling/operations/summarize_definitions_op.py +++ b/hed/tools/remodeling/operations/summarize_definitions_op.py @@ -7,7 +7,7 @@ class SummarizeDefinitionsOp(BaseOp): - """ Summarize the values in the columns of a tabular file. + """ Summarize the definitions in the columns of a tabular file. Required remodeling parameters: - **summary_name** (*str*): The name of the summary. @@ -42,16 +42,14 @@ def __init__(self, parameters): :raises TypeError: - If a parameter has the wrong type. - """ - super().__init__(self.PARAMS, parameters) self.summary_name = parameters['summary_name'] self.summary_filename = parameters['summary_filename'] self.append_timecode = parameters.get('append_timecode', False) def do_op(self, dispatcher, df, name, sidecar=None): - """ Create factor columns corresponding to values in a specified column. + """ Create summaries of definitions Parameters: dispatcher (Dispatcher): Manages the operation I/O. @@ -60,7 +58,7 @@ def do_op(self, dispatcher, df, name, sidecar=None): sidecar (Sidecar or file-like): Only needed for HED operations. Returns: - DataFrame: A new DataFrame with the factor columns appended. + DataFrame: the same datafarme Side-effect: Updates the relevant summary. @@ -92,40 +90,41 @@ def update_summary(self, new_info): series, def_dict = data_input.series_a, data_input.get_def_dict(new_info['schema']) self.def_gatherer.process_def_expands(series, def_dict) + @staticmethod + def _build_summary_dict(items_dict, title, process_func, display_description=False): + summary_dict = {} + items = {} + for key, value in items_dict.items(): + if process_func: + value = process_func(value) + if "#" in str(value): + key = key + "/#" + if display_description: + description, value = DefinitionSummary._remove_description(value) + items[key] = {"description": description, "contents": str(value)} + else: + if isinstance(value, list): + items[key] = [str(x) for x in value] + else: + items[key] = str(value) + summary_dict[title] = items + return summary_dict + def get_details_dict(self, def_gatherer): """ Return the summary-specific information in a dictionary. Parameters: - summary (?): Contains the resolved dictionaries. + def_gatherer (DefExpandGatherer): Contains the resolved dictionaries. Returns: dict: dictionary with the summary results. """ - def build_summary_dict(items_dict, title, process_func, display_description=False): - summary_dict = {} - items = {} - for key, value in items_dict.items(): - if process_func: - value = process_func(value) - if "#" in str(value): - key = key + "/#" - if display_description: - description, value = DefinitionSummary.remove_description(value) - items[key] = {"description": description, "contents": str(value)} - else: - if isinstance(value, list): - items[key] = [str(x) for x in value] - else: - items[key] = str(value) - summary_dict[title] = items - return summary_dict - - known_defs_summary = build_summary_dict(def_gatherer.def_dict, "Known Definitions", None, - display_description=True) - ambiguous_defs_summary = build_summary_dict(def_gatherer.ambiguous_defs, "Ambiguous Definitions", - def_gatherer.get_ambiguous_group) - errors_summary = build_summary_dict(def_gatherer.errors, "Errors", None) + known_defs_summary = self._build_summary_dict(def_gatherer.def_dict, "Known Definitions", None, + display_description=True) + ambiguous_defs_summary = self._build_summary_dict(def_gatherer.ambiguous_defs, "Ambiguous Definitions", + def_gatherer.get_ambiguous_group) + errors_summary = self._build_summary_dict(def_gatherer.errors, "Errors", None) known_defs_summary.update(ambiguous_defs_summary) known_defs_summary.update(errors_summary) @@ -161,25 +160,26 @@ def _get_result_string(self, name, result, indent=BaseSummary.DISPLAY_INDENT): return self._get_individual_string(result, indent=indent) @staticmethod - def _get_dataset_string(summary_dict, indent=BaseSummary.DISPLAY_INDENT): - def nested_dict_to_string(data, level=1): - result = [] - for key, value in data.items(): - if isinstance(value, dict): - result.append(f"{indent * level}{key}: {len(value)} items") - result.append(nested_dict_to_string(value, level + 1)) - elif isinstance(value, list): - result.append(f"{indent * level}{key}:") - for item in value: - result.append(f"{indent * (level + 1)}{item}") - else: - result.append(f"{indent * level}{key}: {value}") - return "\n".join(result) + def _nested_dict_to_string(data, indent, level=1): + result = [] + for key, value in data.items(): + if isinstance(value, dict): + result.append(f"{indent * level}{key}: {len(value)} items") + result.append(DefinitionSummary._nested_dict_to_string(value, indent, level + 1)) + elif isinstance(value, list): + result.append(f"{indent * level}{key}:") + for item in value: + result.append(f"{indent * (level + 1)}{item}") + else: + result.append(f"{indent * level}{key}: {value}") + return "\n".join(result) - return nested_dict_to_string(summary_dict) + @staticmethod + def _get_dataset_string(summary_dict, indent=BaseSummary.DISPLAY_INDENT): + return DefinitionSummary._nested_dict_to_string(summary_dict, indent) @staticmethod - def remove_description(def_entry): + def _remove_description(def_entry): def_group = def_entry.contents.copy() description = "" desc_tag = def_group.find_tags({"description"}, include_groups=False) diff --git a/spec_tests/test_errors.py b/spec_tests/test_errors.py index 3c2793d94..e48333c5d 100644 --- a/spec_tests/test_errors.py +++ b/spec_tests/test_errors.py @@ -47,6 +47,8 @@ "SIDECAR_BRACES_INVALID", "SCHEMA_LIBRARY_INVALID", + + "SCHEMA_ATTRIBUTE_INVALID" ] skip_tests = { diff --git a/tests/schema/test_hed_cache.py b/tests/schema/test_hed_cache.py index bf8091b15..55a343a26 100644 --- a/tests/schema/test_hed_cache.py +++ b/tests/schema/test_hed_cache.py @@ -26,10 +26,9 @@ def setUpClass(cls): cls.semantic_version_two = '1.2.4' cls.semantic_version_three = '1.2.5' cls.semantic_version_list = ['1.2.3', '1.2.4', '1.2.5'] - cls.specific_base_url = "https://api.github.com/repos/hed-standard/hed-specification/contents/hedxml" + cls.specific_base_url = "https://api.github.com/repos/hed-standard/hed-schemas/contents/standard_schema/hedxml" + cls.specific_hed_url = "https://raw.githubusercontent.com/hed-standard/hed-schemas/master/standard_schema/hedxml/HED8.0.0.xml" try: - cls.specific_hed_url = \ - """https://raw.githubusercontent.com/hed-standard/hed-specification/master/hedxml/HED8.0.0.xml""" hed_cache.cache_xml_versions(cache_folder=cls.hed_cache_dir) except urllib.error.HTTPError as e: schema.set_cache_directory(cls.saved_cache_folder) diff --git a/tests/schema/test_schema_compliance.py b/tests/schema/test_schema_compliance.py index a9eb18b9c..1578e57d9 100644 --- a/tests/schema/test_schema_compliance.py +++ b/tests/schema/test_schema_compliance.py @@ -1,18 +1,15 @@ import unittest import os +import copy from hed.schema import schema_compliance from hed import schema from hed.errors import ErrorHandler, SchemaWarnings class Test(unittest.TestCase): - # a known schema with some issues - schema_file = '../data/schema_tests/HED8.0.0.mediawiki' - @classmethod def setUpClass(cls): - cls.error_handler = ErrorHandler() - cls.schema_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.schema_file) + cls.hed_schema = schema.load_schema_version("8.1.0") def validate_term_base(self, input_text, expected_issues): for text, issues in zip(input_text, expected_issues): @@ -25,7 +22,9 @@ def validate_desc_base(self, input_descriptions, expected_issues): self.assertCountEqual(issues, test_issues) def test_validate_schema(self): - hed_schema = schema.load_schema(self.schema_path) + schema_path_with_issues = '../data/schema_tests/HED8.0.0.mediawiki' + schema_path_with_issues = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_path_with_issues) + hed_schema = schema.load_schema(schema_path_with_issues) issues = hed_schema.check_compliance() self.assertTrue(isinstance(issues, list)) self.assertTrue(len(issues) > 1) @@ -72,3 +71,34 @@ def test_validate_schema_description(self): ] self.validate_desc_base(test_descs, expected_issues) + + def test_util_placeholder(self): + tag_entry = self.hed_schema.all_tags["Event"] + attribute_name = "unitClass" + self.assertTrue(schema_compliance.tag_is_placeholder_check(self.hed_schema, tag_entry, attribute_name)) + attribute_name = "unitClass" + tag_entry = self.hed_schema.all_tags["Age/#"] + self.assertFalse(schema_compliance.tag_is_placeholder_check(self.hed_schema, tag_entry, attribute_name)) + + def test_util_suggested(self): + tag_entry = self.hed_schema.all_tags["Event/Sensory-event"] + attribute_name = "suggestedTag" + self.assertFalse(schema_compliance.tag_exists_check(self.hed_schema, tag_entry, attribute_name)) + tag_entry = self.hed_schema.all_tags["Property"] + self.assertFalse(schema_compliance.tag_exists_check(self.hed_schema, tag_entry, attribute_name)) + tag_entry = copy.deepcopy(tag_entry) + tag_entry.attributes["suggestedTag"] = "InvalidSuggestedTag" + self.assertTrue(schema_compliance.tag_exists_check(self.hed_schema, tag_entry, attribute_name)) + + def test_util_rooted(self): + tag_entry = self.hed_schema.all_tags["Event"] + attribute_name = "rooted" + self.assertFalse(schema_compliance.tag_exists_base_schema_check(self.hed_schema, tag_entry, attribute_name)) + tag_entry = self.hed_schema.all_tags["Property"] + self.assertFalse(schema_compliance.tag_exists_base_schema_check(self.hed_schema, tag_entry, attribute_name)) + tag_entry = copy.deepcopy(tag_entry) + tag_entry.attributes["rooted"] = "Event" + self.assertFalse(schema_compliance.tag_exists_base_schema_check(self.hed_schema, tag_entry, attribute_name)) + tag_entry = copy.deepcopy(tag_entry) + tag_entry.attributes["rooted"] = "NotRealTag" + self.assertTrue(schema_compliance.tag_exists_base_schema_check(self.hed_schema, tag_entry, attribute_name)) \ No newline at end of file diff --git a/tests/schema/test_schema_util.py b/tests/schema/test_schema_util.py index ab6099276..0fb72539d 100644 --- a/tests/schema/test_schema_util.py +++ b/tests/schema/test_schema_util.py @@ -8,7 +8,7 @@ class Test(unittest.TestCase): @classmethod def setUpClass(cls): cls.default_test_url = \ - """https://raw.githubusercontent.com/hed-standard/hed-specification/master/hedxml/HED8.0.0.xml""" + """https://raw.githubusercontent.com/hed-standard/hed-schemas/master/standard_schema/hedxml/HED8.0.0.xml""" cls.hed_xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../schema_tests/HED8.0.0t.xml') diff --git a/tests/schema/test_schema_wiki_fatal_errors.py b/tests/schema/test_schema_wiki_fatal_errors.py index 50f3cf6ca..583579b17 100644 --- a/tests/schema/test_schema_wiki_fatal_errors.py +++ b/tests/schema/test_schema_wiki_fatal_errors.py @@ -96,7 +96,7 @@ def test_merging_errors_schema(self): error_handler.push_error_context(ErrorContext.ROW, 1) error_handler.push_error_context(ErrorContext.COLUMN, 2) - issues = error_handler.format_error_with_context(SchemaErrors.HED_SCHEMA_ATTRIBUTE_INVALID, + issues = error_handler.format_error_with_context(SchemaErrors.SCHEMA_ATTRIBUTE_INVALID, "error_attribute", source_tag="error_tag") error_handler.pop_error_context() error_handler.pop_error_context()