-
Notifications
You must be signed in to change notification settings - Fork 68
Description
JavaScript constraint functions defined in external .js files are not executing the actual code in the file. The validation behaves as if a different version of the function is being used, suggesting a caching issue or file loading problem.
Environment
- pyshacl version: 0.30.1
- pyduktape2 version: 0.5.0
- Python version: 3.10.12
- OS: WSL Ubuntu on Windows
- rdflib version: 7.4.0
Expected Behavior
When a SHACL-JS constraint references an external JavaScript file, the current content of that file should be loaded and executed during validation.
Actual Behavior
The validation executes a different version of the JavaScript function than what is currently in the file, suggesting either:
- The JavaScript file is cached and not reloaded
- The wrong file is being loaded
Minimal Reproduction Case
1. Setup Files
data.ttl:
@prefix ex: <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:Item1 a ex:Product ;
ex:name "Test Name" .shape.ttl:
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ex: <http://example.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:ProductNameShape
a sh:NodeShape ;
sh:targetClass ex:Product ;
sh:property [
sh:path ex:name ;
sh:js [
a sh:JSConstraint ;
sh:message "Name must be between 3 and 100 characters" ;
sh:jsFunctionName "validateName" ;
sh:jsLibrary [
sh:jsLibraryURL "validate.js"^^xsd:anyURI ;
] ;
] ;
] .validate.js:
function validateName($value) {
var name = $value;
var length = name.length;
// Return true if length is between 3 and 100
return length >= 3 && length <= 100;
}2. Run Validation
from pyshacl import validate
r = validate(
'data.ttl',
shacl_graph='shape.ttl',
js=True,
advanced=True
)
conforms, results_graph, results_text = r
print(f"Conforms: {conforms}")
print(results_text)3. Observe the Problem
Test Case: "Test Name" = 9 characters
Expected Result:
- Since 9 is between 3 and 100, the function should return
true - Validation should PASS (conforms = True)
Actual Result:
Conforms: False
Results (1):
Constraint Violation in JSConstraint
Focus Node: ex:Item1
Value Node: Literal("Test Name")
Message: Name must be between 3 and 100 characters
The validation FAILS, meaning the JavaScript function returned false, but according to the code return length >= 3 && length <= 100, it should return true for 9 characters.
Additional Evidence
Test with Multiple Items
data.ttl with 3 items:
@prefix ex: <http://example.org/> .
ex:Item1 a ex:Product ;
ex:name "Hello World" . # 11 characters
ex:Item2 a ex:Product ;
ex:name "X" . # 1 character
ex:Item3 a ex:Product ;
ex:name "Sample Product" . # 14 charactersCurrent JavaScript function:
function validateName($value) {
var name = $value;
var length = name.length;
return length >= 3 && length <= 100; // Accept 3-100 chars
}Expected Results:
- "X" (1 char) → FAIL (< 3)
- "Hello World" (11 chars) → PASS (3 ≤ 11 ≤ 100)
- "Sample Product" (14 chars) → PASS (3 ≤ 14 ≤ 100)
- Total: 1 failure
Actual Results:
Validation FAILED
Total errors: 3
All 3 items fail validation
This confirms the JavaScript is not executing the current code. It appears to be executing an older version where the condition was different (possibly >= 90 && <= 100).
Impact
This makes SHACL-JS unreliable for production use because:
- Changes to JavaScript validation logic don't take effect
- No way to debug or verify which version of the code is executing
- Unpredictable validation behavior
- Cannot trust that the JavaScript function in the file is what's being executed
References:
- SHACL-JS Spec: https://www.w3.org/TR/shacl-js/
- pyshacl Repository: https://github.com/RDFLib/pySHACL
- Duktape: https://duktape.org/