def validate_via_metapype(node): errs = [] try: validate.tree(node, errs) except Exception as e: print(f'validate_via_metapype: node={node.name} exception={e}') return errs
def parse_xml_file(filename, filepath): log_info(f"parse_xml_file: {filename}") eml_version = '' with open(filepath, "r") as f: lines = f.readlines() for line in lines: if 'xmlns:eml' in line: eml_version = line[-7:-2] break xml = "".join(lines) eml_node = metapype_io.from_xml(xml, clean=True, literals=['literalLayout', 'markdown']) assert isinstance(eml_node, Node) # TODO: error-handling pruned_nodes = set() errs = [] unknown_nodes = None attr_errs = None child_errs = None other_errs = None try: validate.tree(eml_node, errs) validate.tree(eml_node) print(f'{filename} - {eml_version}: valid') log_info(f'{filename} - {eml_version}: valid') # return None except Exception as e: print(f'{filename} - {eml_version}: ', end='') try: pruned = validate.prune(eml_node, strict=False) for x, _ in pruned: pruned_nodes.add(x.name) pruned_nodes = sorted(pruned_nodes) unknown_nodes, attr_errs, child_errs, other_errs = extract_eml_errors( errs) if unknown_nodes: print(f"Unknown nodes: {unknown_nodes}") log_info(f"Unknown nodes: {unknown_nodes}") if attr_errs: print(f"Attribute errors: {attr_errs}") log_info(f"Attribute errors: {attr_errs}") if child_errs: print(f"Child errors: {child_errs}") log_info(f"Child errors: {child_errs}") if other_errs: print(f"Other errors: {other_errs}") log_info(f"Other errors: {other_errs}") if pruned: print(f"Pruned nodes: {pruned_nodes}") log_info(f"Pruned nodes: {pruned_nodes}") else: err_set = set() for err in errs: err_set.add(err[1]) print('***', sorted(err_set)) except Exception as e: print(f'validate.prune FAILED: {e}') log_info(f'validate.prune FAILED: {e}') return eml_node, unknown_nodes, attr_errs, child_errs, other_errs, pruned_nodes
def test_validate_annotation(): annotation = Node(names.ANNOTATION) property_uri = Node(names.PROPERTYURI) property_uri.content = "http://purl.obolibrary.org/obo/IAO_0000136" property_uri.add_attribute("label", "some property label") annotation.add_child(property_uri) value_uri = Node(names.VALUEURI) value_uri.content = "http://purl.obolibrary.org/obo/IAO_0000136" value_uri.add_attribute("label", "some value label") annotation.add_child(value_uri) validate.tree(annotation)
def validate_via_metapype(node): errs = [] try: start = time.perf_counter() validate.tree(node, errs) end = time.perf_counter() elapsed = end - start # if elapsed > 0.05: # print(f"validate: {node.name} {elapsed}") except Exception as e: print(f'validate_via_metapype: node={node.name} exception={e}') return errs
def test_validate_bad_tree(node): dataset: Node = node.find_child(names.DATASET) creator: Node = dataset.find_child(names.CREATOR) dataset.remove_child(creator) errs = list() assert validate.tree(node, errs) is None assert len(errs) != 0
def test_prune(): if "TEST_DATA" in os.environ: test_data = os.environ["TEST_DATA"] else: test_data = tests.test_data_path with open(f"{test_data}/eml.xml", "r") as f: xml = "".join(f.readlines()) eml = metapype_io.from_xml(xml) pruned = validate.prune(eml, strict=True) for node in pruned: print(f"pruned: {node[0].name} - {node[1]}") errs = [] validate.tree(eml, errs) for err in errs: print(err)
def test_missing_numerical_unit(): unit = Node(names.UNIT, parent=None) r = rule.get_rule(names.UNIT) with pytest.raises(MetapypeRuleError): r.validate_rule(unit) # Check error errs = [] validate.tree(unit, errs) assert len(errs) == 1 err_code, msg, node, *args = errs[0] assert err_code == ValidationError.MIN_CHOICE_UNMET assert args[0] == 'unit' # With a customUnit, it should be ok custom_unit = Node(names.CUSTOMUNIT, parent=unit) custom_unit.content = 'bushels per parsec' unit.add_child(custom_unit) validate.tree(unit)
def test_expand(): if "TEST_DATA" in os.environ: xml_path = os.environ["TEST_DATA"] else: xml_path = tests.test_data_path with open(f"{xml_path}/eml.xml", "r") as f: xml = "".join(f.readlines()) eml = metapype_io.from_xml(xml) validate.tree(eml) references.expand(eml) validate.tree(eml) creator = eml.find_descendant(names.CREATOR) creator.name = "node" creator.attributes = dict() metadata_provider = eml.find_descendant(names.METADATAPROVIDER) metadata_provider.name = "node" assert Node.is_equal(creator, metadata_provider)
def test_responsible_party(): creator = Node(names.CREATOR) creator.add_attribute("id", "creator") creator.add_namespace("eml", "https://eml.ecoinformatics.org/eml-2.2.0") individual_name = Node(names.INDIVIDUALNAME) creator.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Chase") given_name.add_attribute("lang", "Spanish") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Gaucho") sur_name.add_attribute("lang", "Spanish") individual_name.add_child(sur_name) individual_name = Node(names.INDIVIDUALNAME) creator.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Cactus") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Jack") individual_name.add_child(sur_name) phone = Node(names.PHONE, content="999-999-9999") creator.add_child(phone) validate.tree(creator)
def test_responsible_party_with_role(): personnel = Node(names.PERSONNEL) personnel.add_attribute("id", "personnel") personnel.add_namespace("eml", "https://eml.ecoinformatics.org/eml-2.2.0") individual_name = Node(names.INDIVIDUALNAME) personnel.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Chase") given_name.add_attribute("lang", "Spanish") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Gaucho") sur_name.add_attribute("lang", "Spanish") individual_name.add_child(sur_name) individual_name = Node(names.INDIVIDUALNAME) personnel.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Cactus") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Jack") individual_name.add_child(sur_name) phone = Node(names.PHONE, content="999-999-9999") personnel.add_child(phone) errs = [] # Without role, should get an error with pytest.raises(MetapypeRuleError): validate.tree(personnel) # Error should name 'role' as the cause validate.tree(personnel, errs) for err_code, msg, node, *args in errs: err_cause, min = args assert err_cause == 'role' # With role, it should be ok role = Node(names.ROLE, content="drummer") personnel.add_child(role) validate.tree(personnel, errs)
def test_bounding_altitudes(): bounding_coordinates = Node(names.BOUNDINGCOORDINATES, parent=None) bc_west = Node(names.WESTBOUNDINGCOORDINATE, parent=bounding_coordinates) bc_east = Node(names.EASTBOUNDINGCOORDINATE, parent=bounding_coordinates) bc_north = Node(names.NORTHBOUNDINGCOORDINATE, parent=bounding_coordinates) bc_south = Node(names.SOUTHBOUNDINGCOORDINATE, parent=bounding_coordinates) bc_west.content = "0.0" bc_east.content = "0.0" bc_north.content = "0.0" bc_south.content = "0.0" bounding_coordinates.add_child(bc_west) bounding_coordinates.add_child(bc_east) bounding_coordinates.add_child(bc_north) bounding_coordinates.add_child(bc_south) # without boundingAltitudes should be ok validate.node(bounding_coordinates) # boundingAltitudes should fail if not all required children present bounding_altitudes = Node(names.BOUNDINGALTITUDES, parent=bounding_coordinates) bounding_coordinates.add_child(bounding_altitudes) with pytest.raises(MetapypeRuleError): validate.tree(bounding_coordinates) altitude_minimum = Node(names.ALTITUDEMINIMUM, parent=bounding_altitudes) bounding_altitudes.add_child(altitude_minimum) with pytest.raises(MetapypeRuleError): validate.tree(bounding_coordinates) altitude_minimum.content = "0.0" with pytest.raises(MetapypeRuleError): validate.tree(bounding_coordinates) # boundingAltitudes should fail if not all required children have content altitude_maximum = Node(names.ALTITUDEMAXIMUM, parent=bounding_altitudes) bounding_altitudes.add_child(altitude_maximum) altitude_units = Node(names.ALTITUDEUNITS, parent=bounding_altitudes) bounding_altitudes.add_child(altitude_units) with pytest.raises(MetapypeRuleError): validate.tree(bounding_coordinates) # with content filled in, should pass altitude_maximum.content = "1000.0" altitude_units.content = "meter" validate.tree(bounding_coordinates)
def test_validate_prune(): if "TEST_DATA" in os.environ: xml_path = os.environ["TEST_DATA"] else: xml_path = tests.test_data_path with open(f"{xml_path}/eml.xml", "r") as f: xml = "".join(f.readlines()) eml = metapype_io.from_xml(xml) assert isinstance(eml, Node) referencePublication = Node("referencePublication") usageCitation = Node("usageCitation") dataset = eml.find_single_node_by_path([names.DATASET]) dataset.add_child(referencePublication) dataset.add_child(usageCitation) errs = list() validate.tree(eml, errs) assert len(errs) > 0 validate.prune(eml) errs = list() validate.tree(eml, errs) assert len(errs) == 0
def test_copy(): creator = Node(names.CREATOR) creator.add_attribute("id", "creator") creator.add_namespace("eml", "https://eml.ecoinformatics.org/eml-2.2.0") individual_name = Node(names.INDIVIDUALNAME) creator.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Chase") given_name.add_attribute("lang", "Spanish") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Gaucho") sur_name.add_attribute("lang", "Spanish") individual_name.add_child(sur_name) individual_name = Node(names.INDIVIDUALNAME) creator.add_child(individual_name) given_name = Node(names.GIVENNAME, content="Cactus") individual_name.add_child(given_name) sur_name = Node(names.SURNAME, content="Jack") individual_name.add_child(sur_name) validate.tree(creator) creator_copy = creator.copy() validate.tree(creator_copy) assert is_deep_copy(creator, creator_copy)
def construct_texttype_node(text, parent_name=None): if parent_name and parent_name not in TEXTTYPE_NODES: return text try: subtree = metapype_io.from_xml(remove_escapes(text), clean=True, literals=['literalLayout', 'markdown']) validate.tree(subtree) return subtree except Exception as e: if e.__class__.__name__ == 'XMLSyntaxError': if str(e).startswith('Start tag expected'): try: # We may have a naked string. Try adding the root node. text = f"<{parent_name}>{text}</{parent_name}>" subtree = metapype_io.from_xml( text, clean=True, literals=['literalLayout', 'markdown']) validate.tree(subtree) return subtree except Exception as e2: raise InvalidXMLError(str(e2)) raise InvalidXMLError(str(e))
def test_validate_tree(node): assert validate.tree(node) is None