#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use ggen_engine::law_engine::{GraphLawEngine, LawEngine};
const FACTS_NTRIPLES: &str = "<http://example.org/rex> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Dog> .\n";
const RULE_N3: &str = "@prefix ex: <http://example.org/>. {?s a ex:Dog} => {?s a ex:Animal}.";
#[test]
fn materialize_without_rules_derives_nothing_new() {
let engine = GraphLawEngine::new();
let outcome = engine
.materialize(FACTS_NTRIPLES, "")
.expect("materialize with no rules must still succeed");
assert_eq!(outcome.rules_loaded, 0);
assert!(
outcome.derived.is_empty(),
"no rules loaded -> nothing new can be derived: {:?}",
outcome.derived
);
}
#[test]
fn materialize_with_n3_rule_derives_new_fact() {
let engine = GraphLawEngine::new();
let outcome = engine
.materialize(FACTS_NTRIPLES, RULE_N3)
.expect("materialize with a loaded rule must succeed");
assert_eq!(outcome.rules_loaded, 1);
assert!(
outcome
.derived
.iter()
.any(|l| l.contains("example.org/rex") && l.contains("example.org/Animal")),
"expected a derived `rex a Animal` fact, got: {:?}",
outcome.derived
);
}
#[test]
fn validate_shacl_reports_real_violation() {
const SHAPES_TTL: &str = r"
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ex: <http://example.org/> .
ex:DogShape a sh:NodeShape ;
sh:targetClass ex:Dog ;
sh:property [ sh:path ex:name ; sh:minCount 1 ] .
";
let engine = GraphLawEngine::new();
let outcome = engine
.validate_shacl(FACTS_NTRIPLES, SHAPES_TTL)
.expect("SHACL validation call must succeed even when facts don't conform");
assert!(
!outcome.conforms,
"rex has no ex:name -- must NOT conform: {outcome:?}"
);
assert!(
outcome.violations.iter().any(|v| v.contains("rex")),
"violation must name the focus node: {:?}",
outcome.violations
);
}
#[test]
fn check_denials_reports_violated_denial_after_materialization() {
const DENIAL_N3: &str = "@prefix ex: <http://example.org/>. {?s a ex:Animal} => false.";
let rules = format!("{RULE_N3}\n{DENIAL_N3}");
let engine = GraphLawEngine::new();
let denials = engine
.check_denials(FACTS_NTRIPLES, &rules)
.expect("check_denials call must succeed");
assert!(
!denials.is_empty(),
"the derived `rex a Animal` fact must trip the denial rule: {denials:?}"
);
}