From 231d72c50988019be2411b22316b0042385289ed Mon Sep 17 00:00:00 2001 From: MBueschelberger <46421269+MBueschelberger@users.noreply.github.com> Date: Thu, 13 Oct 2022 11:08:47 +0200 Subject: [PATCH] Enh/attributes in schema validation (#822) * add checking of data properties (attributes) in schema validation * Use FOAF from web archive --- osp/core/utils/schema_validation.py | 20 +++++++++-- tests/test_utils.py | 7 ++++ ..._validation_schema_city_with_attribute.yml | 33 +++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 tests/test_validation_schema_city_with_attribute.yml diff --git a/osp/core/utils/schema_validation.py b/osp/core/utils/schema_validation.py index 618dc811..bf5f9f58 100644 --- a/osp/core/utils/schema_validation.py +++ b/osp/core/utils/schema_validation.py @@ -5,6 +5,7 @@ import yaml from osp.core.namespaces import get_entity +from osp.core.ontology import OntologyAttribute, OntologyRelationship logger = logging.getLogger(__name__) @@ -97,9 +98,22 @@ def _load_data_model_from_yaml(data_model_file): def _check_cuds_object_cardinality(origin_cuds, dest_oclass, rel, constraints): - actual_cardinality = len( - origin_cuds.get(rel=get_entity(rel), oclass=get_entity(dest_oclass)) - ) + rel_entity = get_entity(rel) + + if type(rel_entity) == OntologyRelationship: + actual_cardinality = len( + origin_cuds.get(rel=rel_entity, oclass=get_entity(dest_oclass)) + ) + elif type(rel_entity) == OntologyAttribute: + # No datatype checking since this is already done when Cuds are + # instantiated or imported from a file + actual_cardinality = ( + 1 if rel_entity in origin_cuds.get_attributes() else 0 + ) + else: + raise ConsistencyError( + f"Relation '{rel}' not supported for {origin_cuds.oclass}." + ) min, max = _interpret_cardinality_value_from_constraints(constraints) if actual_cardinality < min or actual_cardinality > max: diff --git a/tests/test_utils.py b/tests/test_utils.py index ea373297..44492af5 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -134,6 +134,11 @@ def test_validate_tree_against_schema(self): "test_validation_schema_city_with_optional_subtree.yml", ) + schema_file_with_attribute = os.path.join( + os.path.dirname(__file__), + "test_validation_schema_city_with_attribute.yml", + ) + c = city.City(name="freiburg") # empty city is not valid @@ -188,6 +193,8 @@ def test_validate_tree_against_schema(self): schema_file_with_missing_entity, ) + validate_tree_against_schema(c, schema_file_with_attribute) + def test_branch(self): """Test the branch function.""" x = branch( diff --git a/tests/test_validation_schema_city_with_attribute.yml b/tests/test_validation_schema_city_with_attribute.yml new file mode 100644 index 00000000..4b62e872 --- /dev/null +++ b/tests/test_validation_schema_city_with_attribute.yml @@ -0,0 +1,33 @@ +version: "1.0.0" + +oclass: city.City + +model: + city.City: + city.name: + STRING: + cardinality: 1 + city.hasInhabitant: + city.Citizen: + cardinality: 1-2 + city.hasPart: + city.Neighborhood: + cardinality: 1 + + city.Neighborhood: + city.name: + STRING: + cardinality: 1 + city.hasPart: + city.Street: + cardinality: 1+ + + city.Street: + city.name: + STRING: + cardinality: 1 + + city.Citizen: + city.name: + STRING: + cardinality: 1