Skip to content

Commit

Permalink
lists in result messages
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomociti committed Apr 12, 2024
1 parent f2411d6 commit e2f77f9
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/eighty-snakes-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"rdf-validate-shacl": patch
---

Improved result messages with lists
20 changes: 18 additions & 2 deletions src/validation-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,16 @@ function localName(uri) {
return uri.substring(index + 1)
}

function nodeLabel(node) {
function * take(n, iterable) {
let i = 0
for (const item of iterable) {
if (i++ === n) break
yield item
}
}

function nodeLabel(constraint, param) {
const node = constraint.getParameterValue(param)
if (!node) {
return 'NULL'
}
Expand All @@ -331,6 +340,13 @@ function nodeLabel(node) {
}

if (node.termType === 'BlankNode') {
const pointer = constraint.shapeNodePointer.out(param)
const list = pointer.list()
if (list) {
const items = Array.from(take(3, list))
return items.join(', ') + (items.length === 3 ? ' ...' : '')
}

return 'Blank node ' + node.value
}

Expand All @@ -340,7 +356,7 @@ function nodeLabel(node) {
function withSubstitutions(messageTerm, constraint, factory) {
const message = constraint.component.parameters.reduce((message, param) => {
const paramName = localName(param.value)
const paramValue = nodeLabel(constraint.getParameterValue(param))
const paramValue = nodeLabel(constraint, param)
return message
.replace(`{$${paramName}}`, paramValue)
.replace(`{?${paramName}}`, paramValue)
Expand Down
2 changes: 1 addition & 1 deletion src/validators-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default {
[ns.sh.InConstraintComponent.value]: {
validator: {
func: validators.validateIn,
message: 'Value is not in {$in}',
message: 'Value is not one of the allowed values: {$in}',
},
},
[ns.sh.LanguageInConstraintComponent.value]: {
Expand Down
11 changes: 11 additions & 0 deletions test/data/validation-message/message-with-list.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<Alice> a <Person> ; <category> "f" .

<ShapeWithList> a sh:NodeShape ;
sh:targetClass <Person> ;
sh:property [
sh:path <category> ;
sh:in ("a" "b" "c" "d" "e") ;
] .
13 changes: 13 additions & 0 deletions test/validation_message_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,17 @@ describe('validation messages', () => {
{ value: 'Mon message de validation', language: 'fr' },
]))
})

it('Lists first items in message', async () => {
const dataPath = path.join(rootPath, 'message-with-list.ttl')
const data = await loadDataset(dataPath)
const shapes = data

const validator = new SHACLValidator(shapes)
const report = validator.validate(data)

assert.strictEqual(report.results.length, 1)
assert.strictEqual(report.results[0].message.length, 1)
assert.strictEqual(report.results[0].message[0].value, 'Value is not one of the allowed values: a, b, c ...')
})
})

0 comments on commit e2f77f9

Please sign in to comment.