From cc17b124fa5e5ac184aabe93e24b055f3e163277 Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Fri, 24 May 2024 15:32:45 +0200 Subject: [PATCH 1/4] test: add InferencingTestCaseType --- .../testcases/InferencingTestCaseType.java | 120 ++++++++++++++++++ .../shacl/testcases/TestCaseTypes.java | 2 +- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java diff --git a/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java b/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java new file mode 100644 index 00000000..4710b170 --- /dev/null +++ b/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java @@ -0,0 +1,120 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + */ +package org.topbraid.shacl.testcases; + +import org.apache.jena.graph.Triple; +import org.apache.jena.query.Dataset; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.vocabulary.RDF; +import org.topbraid.jenax.functions.CurrentThreadFunctionRegistry; +import org.topbraid.jenax.util.ARQFactory; +import org.topbraid.jenax.util.JenaUtil; +import org.topbraid.shacl.engine.ShapesGraph; +import org.topbraid.shacl.engine.ShapesGraphFactory; +import org.topbraid.shacl.rules.RuleEngine; +import org.topbraid.shacl.testcases.context.TestCaseContextFactory; +import org.topbraid.shacl.util.ModelPrinter; +import org.topbraid.shacl.util.SHACLUtil; +import org.topbraid.shacl.vocabulary.DASH; + +import java.net.URI; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Ashley Caselli + */ +public class InferencingTestCaseType extends TestCaseType { + + private static final List contextFactories = new LinkedList<>(); + + + public static void registerContextFactory(TestCaseContextFactory factory) { + contextFactories.add(factory); + } + + + public InferencingTestCaseType() { + super(DASH.InferencingTestCase); + } + + + @Override + protected TestCase createTestCase(Resource graph, Resource resource) { + return new InferencingTestCase(graph, resource); + } + + + private static class InferencingTestCase extends TestCase { + + InferencingTestCase(Resource graph, Resource resource) { + super(graph, resource); + } + + + @Override + public void run(Model results) { + Resource testCase = getResource(); + + Runnable tearDownCTFR = CurrentThreadFunctionRegistry.register(testCase.getModel()); + + Model dataModel = getResource().getModel(); + + Dataset dataset = ARQFactory.get().getDataset(dataModel); + URI shapesGraphURI = SHACLUtil.withShapesGraph(dataset); + ShapesGraph shapesGraph = ShapesGraphFactory.get().createShapesGraph(dataset.getNamedModel(shapesGraphURI.toString())); + + RuleEngine ruleEngine = new RuleEngine(dataset, shapesGraphURI, shapesGraph, dataModel); + try { + ruleEngine.executeAll(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + tearDownCTFR.run(); + } + + Model actualResults = ruleEngine.getInferencesModel(); + Model expectedModel = JenaUtil.createDefaultModel(); + + List expectedResults = getResource().listProperties(DASH.expectedResult).toList(); + boolean valid = false; + for (Statement s : expectedResults) { + valid = false; + expectedModel.add(s); + Resource expectedInferredBN = s.getObject().asResource(); + Triple expectedInferredTriple = Triple.create(expectedInferredBN.getProperty(RDF.subject).getObject().asNode(), + expectedInferredBN.getProperty(RDF.predicate).getObject().asNode(), + expectedInferredBN.getProperty(RDF.object).getObject().asNode()); + if (actualResults.getGraph().contains(expectedInferredTriple)) { + valid = true; + } + } + + if (valid) { + createResult(results, DASH.SuccessTestCaseResult); + } else { + System.out.println("Expected: " + ModelPrinter.get().print(expectedModel) + "\nActual: " + ModelPrinter.get().print(actualResults)); + Resource failure = createFailure(results, + "Mismatching inference results. Expected " + expectedModel.size() + " triples, found " + actualResults.size()); + failure.addProperty(DASH.expectedResult, ModelPrinter.get().print(expectedModel)); + } + } + + } +} diff --git a/src/main/java/org/topbraid/shacl/testcases/TestCaseTypes.java b/src/main/java/org/topbraid/shacl/testcases/TestCaseTypes.java index edf23ed4..cc509f9d 100644 --- a/src/main/java/org/topbraid/shacl/testcases/TestCaseTypes.java +++ b/src/main/java/org/topbraid/shacl/testcases/TestCaseTypes.java @@ -30,7 +30,7 @@ public class TestCaseTypes { static { types.add(new FunctionTestCaseType()); types.add(new GraphValidationTestCaseType()); - //types.add(new InferencingTestCaseType()); + types.add(new InferencingTestCaseType()); types.add(new JSTestCaseType()); types.add(new QueryTestCaseType()); } From 2c84387df61b9ed2182e8cf2c0931c629d8be709 Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Fri, 24 May 2024 15:35:22 +0200 Subject: [PATCH 2/4] test(person2schema): add missing test data --- .../tests/rules/triple/person2schema.test.ttl | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl b/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl index 99b5bd79..bd32b4b0 100644 --- a/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl +++ b/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl @@ -7,8 +7,10 @@ @prefix dash: . @prefix ex: . @prefix owl: . +@prefix person: . @prefix rdf: . @prefix rdfs: . +@prefix schema: . @prefix sh: . @prefix xsd: . @@ -17,7 +19,7 @@ rdfs:label "Test of person2schema" ; owl:imports ; owl:imports ; - owl:imports ; + owl:imports ; owl:versionInfo "Created with TopBraid Composer" ; sh:declare [ rdf:type sh:PrefixDeclaration ; @@ -33,48 +35,55 @@ ex:InferencingTestCase rdf:type dash:InferencingTestCase ; dash:expectedResult [ - rdf:object ; - rdf:predicate ; - rdf:subject ; + rdf:object person:JohnDoe-Address ; + rdf:predicate schema:address ; + rdf:subject person:JohnDoe ; ] ; dash:expectedResult [ - rdf:object ; + rdf:object schema:Person ; rdf:predicate rdf:type ; - rdf:subject ; + rdf:subject person:JohnDoe ; ] ; dash:expectedResult [ - rdf:object ; + rdf:object schema:PostalAddress ; rdf:predicate rdf:type ; - rdf:subject ; + rdf:subject person:JohnDoe-Address ; ] ; dash:expectedResult [ rdf:object 12345 ; - rdf:predicate ; - rdf:subject ; + rdf:predicate schema:postalCode ; + rdf:subject person:JohnDoe-Address ; ] ; dash:expectedResult [ rdf:object "Doe" ; - rdf:predicate ; - rdf:subject ; + rdf:predicate schema:familyName ; + rdf:subject person:JohnDoe ; ] ; dash:expectedResult [ rdf:object "John" ; - rdf:predicate ; - rdf:subject ; + rdf:predicate schema:givenName ; + rdf:subject person:JohnDoe ; ] ; . +person:JohnDoe + rdf:type person:Person ; + person:lastName "Doe" ; + person:firstName "John" ; + person:zipCode 12345 ; + rdfs:label "John Doe" ; +. ex:Person2SchemaMappingShape rdf:type sh:NodeShape ; rdfs:label "Person-to-Schema Mapping Shape" ; sh:rule [ rdf:type sh:TripleRule ; - sh:object ; + sh:object schema:Person ; sh:predicate rdf:type ; sh:subject sh:this ; ] ; sh:rule [ rdf:type sh:TripleRule ; - sh:object ; + sh:object schema:PostalAddress ; sh:predicate rdf:type ; sh:subject [ ex:deriveURI ( @@ -86,25 +95,25 @@ ex:Person2SchemaMappingShape sh:rule [ rdf:type sh:TripleRule ; sh:object [ - sh:path ; + sh:path person:firstName ; ] ; - sh:predicate ; + sh:predicate schema:givenName ; sh:subject sh:this ; ] ; sh:rule [ rdf:type sh:TripleRule ; sh:object [ - sh:path ; + sh:path person:lastName ; ] ; - sh:predicate ; + sh:predicate schema:familyName ; sh:subject sh:this ; ] ; sh:rule [ rdf:type sh:TripleRule ; sh:object [ - sh:path ; + sh:path person:zipCode ; ] ; - sh:predicate ; + sh:predicate schema:postalCode ; sh:subject [ ex:deriveURI ( sh:this @@ -120,10 +129,10 @@ ex:Person2SchemaMappingShape "-Address" ) ; ] ; - sh:predicate ; + sh:predicate schema:address ; sh:subject sh:this ; ] ; - sh:targetClass ; + sh:targetClass person:Person ; . ex:deriveURI rdf:type sh:SPARQLFunction ; @@ -142,8 +151,10 @@ ex:deriveURI ] ; sh:prefixes ; sh:returnType rdfs:Resource ; - sh:select """SELECT ?result -WHERE { - BIND (IRI(CONCAT(str($base), $concat)) AS ?result) -}""" ; + sh:select """ + SELECT ?result + WHERE { + BIND (IRI(CONCAT(str($base), $concat)) AS ?result) + } + """ ; . From 8f207e5918f6779db919717ba6390cff615915f6 Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Sat, 25 May 2024 13:47:56 -0400 Subject: [PATCH 3/4] test(person2schema): fix import IRI --- src/test/resources/sh/tests/rules/triple/person2schema.test.ttl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl b/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl index bd32b4b0..f1bc5608 100644 --- a/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl +++ b/src/test/resources/sh/tests/rules/triple/person2schema.test.ttl @@ -19,7 +19,7 @@ rdfs:label "Test of person2schema" ; owl:imports ; owl:imports ; - owl:imports ; + owl:imports ; owl:versionInfo "Created with TopBraid Composer" ; sh:declare [ rdf:type sh:PrefixDeclaration ; From 0d6dc28bd4654bb63a409def4936f6723730ae3c Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Tue, 8 Oct 2024 11:02:34 +0200 Subject: [PATCH 4/4] refactor: update variable names for clarity in InferencingTestCaseType --- .../shacl/testcases/InferencingTestCaseType.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java b/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java index 4710b170..4acd177d 100644 --- a/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java +++ b/src/main/java/org/topbraid/shacl/testcases/InferencingTestCaseType.java @@ -97,11 +97,11 @@ public void run(Model results) { for (Statement s : expectedResults) { valid = false; expectedModel.add(s); - Resource expectedInferredBN = s.getObject().asResource(); - Triple expectedInferredTriple = Triple.create(expectedInferredBN.getProperty(RDF.subject).getObject().asNode(), - expectedInferredBN.getProperty(RDF.predicate).getObject().asNode(), - expectedInferredBN.getProperty(RDF.object).getObject().asNode()); - if (actualResults.getGraph().contains(expectedInferredTriple)) { + Resource expectedInferredNode = s.getObject().asResource(); + Triple expectedInferredNodeAsTriple = Triple.create(expectedInferredNode.getProperty(RDF.subject).getObject().asNode(), + expectedInferredNode.getProperty(RDF.predicate).getObject().asNode(), + expectedInferredNode.getProperty(RDF.object).getObject().asNode()); + if (actualResults.getGraph().contains(expectedInferredNodeAsTriple)) { valid = true; } }