From b762d5a3b589ffff99896720ef36b2f3a13bd1a5 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 20 Sep 2022 11:31:06 -0400 Subject: [PATCH 1/2] Add test for lexical space of xsd:decimal This patch adds a unit test for `xsd:decimal` values, both in PASS and XFAIL cases. There is one issue apparent, left as a TODO in the last test. Signed-off-by: Alex Nelson --- test/test_decimals.py | 181 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 test/test_decimals.py diff --git a/test/test_decimals.py b/test/test_decimals.py new file mode 100644 index 0000000..6e7ab83 --- /dev/null +++ b/test/test_decimals.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +# + +# This software was developed at the National Institute of Standards +# and Technology by employees of the Federal Government in the course +# of their official duties. Pursuant to title 17 Section 105 of the +# United States Code this software is not subject to copyright +# protection and is in the public domain. NIST assumes no +# responsibility whatsoever for its use by other parties, and makes +# no guarantees, expressed or implied, about its quality, +# reliability, or any other characteristic. +# +# We would appreciate acknowledgement if the software is used. + +""" +Test that values declared as XSD decimal type are confirmed to be conformant with datatype constraints. + +_PASS and _XFAIL name portions on tests in this script denote whether the input data graph should have a True or False conformance result. +""" + +from rdflib import Graph, RDF, SH + +from pyshacl import validate + +ontology_file_text = """ +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . +@prefix exOnt: . + + a owl:Ontology ; + rdfs:label "An example extra-ontology file."@en . + +exOnt:NumberHolder a owl:Class . + +exOnt:propBoolean a owl:DatatypeProperty ; + rdfs:domain exOnt:NumberHolder ; + rdfs:range xsd:boolean . + +exOnt:propDecimal a owl:DatatypeProperty ; + rdfs:domain exOnt:NumberHolder ; + rdfs:range xsd:decimal . +""" + +shacl_file_text = """ +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix exShape: . +@prefix exOnt: . + + a owl:Ontology ; + rdfs:label "Example Shapes File"@en . + +exShape:NumberHolderShape + sh:property + [ + sh:datatype xsd:boolean ; + sh:path exOnt:propBoolean ; + ] , + [ + sh:datatype xsd:decimal ; + sh:path exOnt:propDecimal ; + ] ; + sh:targetClass exOnt:NumberHolder ; + . +""" + +data_file_text_PASS = """ +@prefix rdf: . +@prefix xsd: . +@prefix exOnt: . +@prefix ex: . + +ex:holder0 a exOnt:NumberHolder ; + exOnt:propDecimal + "1"^^xsd:decimal , + "2."^^xsd:decimal , + "3.4"^^xsd:decimal , + "5.6666666666666666667"^^xsd:decimal , + "-8"^^xsd:decimal , + "-9."^^xsd:decimal , + "-0."^^xsd:decimal ; + . +""" + + +def test_validate_with_ontology() -> None: + g = Graph().parse(data=data_file_text_PASS, format='turtle') + e = Graph().parse(data=ontology_file_text, format='turtle') + g_len = len(g) + res = validate( + g, shacl_graph=shacl_file_text, shacl_graph_format='turtle', ont_graph=e, inference='both', debug=True + ) + conforms, graph, string = res + g_len2 = len(g) + assert conforms + assert g_len2 == g_len + + +data_file_text_XFAIL_unrelated = """ +@prefix rdf: . +@prefix xsd: . +@prefix exOnt: . +@prefix ex: . + +ex:holder1 a exOnt:NumberHolder ; + exOnt:propBoolean + "Not boolean" ; + exOnt:propDecimal + "1"^^xsd:decimal , + "2."^^xsd:decimal , + "3.4"^^xsd:decimal , + "5.67"^^xsd:decimal , + "-8"^^xsd:decimal , + "-9."^^xsd:decimal , + "-0."^^xsd:decimal ; + . +""" + + +def test_validate_with_ontology_XFAIL_unrelated() -> None: + res = validate( + data_file_text_XFAIL_unrelated, + shacl_graph=shacl_file_text, + data_graph_format='turtle', + shacl_graph_format='turtle', + ont_graph=ontology_file_text, + ont_graph_format="turtle", + inference="both", + debug=True, + ) + conforms, graph, string = res + validation_result_tally = 0 + for triple in graph.triples((None, RDF.type, SH.ValidationResult)): + validation_result_tally += 1 + assert not conforms + assert validation_result_tally == 1 + + +data_file_text_XFAIL_lexical_space = """ +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . +@prefix exOnt: . +@prefix ex: . + +ex:holder2 a exOnt:NumberHolder ; + rdfs:comment "Each value has an error. All values use an invalid lexical value."@en ; + rdfs:seeAlso ; + exOnt:propDecimal + "1.."^^xsd:decimal , + "2.3."^^xsd:decimal , + "4a"^^xsd:decimal , + "5x"^^xsd:decimal , + "6y."^^xsd:decimal ; + . +""" + + +def test_validate_with_ontology_XFAIL_lexical_space() -> None: + # TODO A runtime error is raised if the inference value is 'owlrl' or 'both', but 'none' and 'rdfs' do not raise a runtime error. Discuss how to flag this test case. + res = validate( + data_file_text_XFAIL_lexical_space, + shacl_graph=shacl_file_text, + data_graph_format='turtle', + shacl_graph_format='turtle', + ont_graph=ontology_file_text, + ont_graph_format="turtle", + # inference="both", + debug=True, + ) + conforms, graph, string = res + validation_result_tally = 0 + for triple in graph.triples((None, RDF.type, SH.ValidationResult)): + validation_result_tally += 1 + assert not conforms + assert validation_result_tally == 5 From 0f7cb839a2fe6a9445c249ce78b23b32c278cce4 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 20 Sep 2022 11:37:03 -0400 Subject: [PATCH 2/2] Enable OWL-RL inferencing for bad decimal lexical space values With the current import of OWL-RL, 6.0.2, this raises a runtime error. Signed-off-by: Alex Nelson --- test/test_decimals.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_decimals.py b/test/test_decimals.py index 6e7ab83..e2e4b8e 100644 --- a/test/test_decimals.py +++ b/test/test_decimals.py @@ -162,7 +162,6 @@ def test_validate_with_ontology_XFAIL_unrelated() -> None: def test_validate_with_ontology_XFAIL_lexical_space() -> None: - # TODO A runtime error is raised if the inference value is 'owlrl' or 'both', but 'none' and 'rdfs' do not raise a runtime error. Discuss how to flag this test case. res = validate( data_file_text_XFAIL_lexical_space, shacl_graph=shacl_file_text, @@ -170,7 +169,7 @@ def test_validate_with_ontology_XFAIL_lexical_space() -> None: shacl_graph_format='turtle', ont_graph=ontology_file_text, ont_graph_format="turtle", - # inference="both", + inference="both", debug=True, ) conforms, graph, string = res