zazuko / rdf-validate-shacl

Validate RDF data purely in JavaScript. An implementation of the W3C SHACL specification on top of the RDFJS stack.
MIT License
98 stars 13 forks source link

Closed shapes lead to a TypeError #25

Closed NSeydoux closed 4 years ago

NSeydoux commented 4 years ago

When trying to validate a closed shape (i.e. with sh:closed true), the following error is thrown:

(node:6649) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'equals' of undefined
    at RDFLibGraph.rdfListToArray (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/rdflib-graph.js:74:22)
    at validateClosed (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/validators.js:35:36)
    at ValidationFunction.execute (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/validation-function.js:11:22)
    at ValidationEngine.validateNodeAgainstConstraint (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/validation-engine.js:213:42)
    at ValidationEngine.validateNodeAgainstShape (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/validation-engine.js:171:16)
    at ValidationEngine.validateAll (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/src/validation-engine.js:144:20)
    at SHACLValidator.validate (/home/nseydoux/dev/sandbox/shapes-hal/node_modules/rdf-validate-shacl/index.js:35:27)
    at main (/home/nseydoux/dev/sandbox/shapes-hal/index.js:51:36)
    at Object.<anonymous> (/home/nseydoux/dev/sandbox/shapes-hal/index.js:68:1)
    at Module._compile (internal/modules/cjs/loader.js:1147:30)

To reproduce

Run the following code snippet:

const SHACLValidator = require("rdf-validate-shacl")
const {Parser} = require("n3")

const ttlData = `
@prefix ex: <http://example.org#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

ex:Alice
a ex:Person ;
ex:ssn "987-65-432A" .

ex:Bob
a ex:Person ;
ex:ssn "123-45-6789" ;
ex:ssn "124-35-6789" .

ex:Calvin
a ex:Person ;
ex:birthDate "1971-07-07"^^xsd:date ;
ex:worksFor ex:UntypedCompany .`

const ttlShape = `
@prefix ex: <http://example.org#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

ex:PersonShape
a sh:NodeShape ;
sh:targetClass ex:Person ;    # Applies to all persons
sh:property [                 # _:b1
    sh:path ex:ssn ;           # constrains the values of ex:ssn
    sh:maxCount 1 ;
    sh:datatype xsd:string ;
] ;
sh:property [                 # _:b2
    sh:path ex:worksFor ;
    sh:class ex:Company ;
    sh:nodeKind sh:IRI ;
] ;
#sh:closed true ;
sh:ignoredProperties ( rdf:type ) .`

async function main() {
    const parser = new Parser();
    const data = parser.parse(ttlData);
    const shapes = parser.parse(ttlShape);

    const validator = new SHACLValidator(shapes)
    console.log("coucou1")
    const report = await validator.validate(data)
     console.log("coucou2")
    // Check conformance: `true` or `false`
    console.log(report.conforms)

    for (const result of report.results) {
      // See https://www.w3.org/TR/shacl/#results-validation-result for details
      // about each method
      console.log(result.message)
      console.log(result.path)
      console.log(result.focusNode)
      console.log(result.severity)
      console.log(result.sourceConstraintComponent)
      console.log(result.sourceShape)
    }
} 

main()

The rdf-validate-shacl version is 0.1.1.

martinmaillard commented 4 years ago

This error is caused by a conflict between blank node IDs. The proper way to solve this would be to use the same data factory throughout the whole process:

const { DataFactory } = require('n3');

const parser = new Parser({ factory: DataFactory }); // <- factory option
const data = parser.parse(ttlData);
const shapes = parser.parse(ttlShape);

const validator = new SHACLValidator(shapes, { factory: DataFactory }) // <- factory option
const report = await validator.validate(data)

But because of an issue in N3.js, it won't solve your problem just yet. I'm working on it ⏳

NSeydoux commented 4 years ago

Thanks ! Does this mean that the issue would disappear altogether if the shape did not include blank nodes at all ?

martinmaillard commented 4 years ago

It should, yes :)

martinmaillard commented 4 years ago

Upgrading N3.js to 1.3.6 should fix your issue :)