use rudof_iri::IriS;
use rudof_rdf::rdf_core::RDFFormat;
use rudof_rdf::rdf_impl::{OxigraphInMemory, ReaderMode};
use shex_ast::ir::external_resolver::SchemaExternalResolver;
use shex_ast::ir::shape_label::ShapeLabel;
use shex_ast::ir::{map_state::MapState, schema_ir::SchemaIR, semantic_actions_registry::SemanticActionsRegistry};
use shex_ast::{Node, ResolveMethod, ShExParser, ir::ast2ir::AST2IR};
use shex_validation::{Validator, ValidatorConfig};
const SCHEMA: &str = "<http://a.example/Sext> EXTERNAL";
const EXTERNS: &str = "<http://a.example/Sext> { <http://a.example/p2> . }";
const DATA: &str = r#"<http://a.example/n1> <http://a.example/p1> <http://a.example/n2> .
<http://a.example/n2> <http://a.example/p2> "X" ."#;
fn compile(schema_src: &str, config: &ValidatorConfig) -> SchemaIR {
let base = IriS::new_unchecked("http://a.example/");
let ast = ShExParser::parse(schema_src, Some(base.clone()), &base).expect("parse main schema");
let mut map_state = MapState::default();
let registry = SemanticActionsRegistry::default();
registry.set_map_state(&mut map_state);
let mut compiler = AST2IR::new(&ResolveMethod::default(), map_state);
let mut compiled = SchemaIR::new(registry);
compiler
.compile(
&ast,
&base,
&Some(base.clone()),
&mut compiled,
config.external_resolvers(),
)
.expect("compile to IR");
compiled
}
fn validate(focus: &str, config: ValidatorConfig) -> bool {
let compiled = compile(SCHEMA, &config);
let mut validator = Validator::new(&compiled, &config).expect("validator");
let graph = OxigraphInMemory::from_str(DATA, &RDFFormat::Turtle, None, &ReaderMode::Strict).expect("parse graph");
let node = Node::parse(focus, None).expect("parse focus");
let shape = ShapeLabel::iri(IriS::new_unchecked("http://a.example/Sext"));
let result = validator
.validate_node_shape(&node, &shape, &graph, &compiled, &Some(graph.prefixmap().clone()))
.expect("validate");
result.get_info(&node, &shape).expect("status").is_conformant()
}
#[test]
fn default_config_rejects_external_shape() {
assert!(!validate("http://a.example/n2", ValidatorConfig::default()));
assert!(!validate("http://a.example/n1", ValidatorConfig::default()));
}
#[test]
fn schema_resolver_substitutes_and_validates() {
let base = IriS::new_unchecked("http://a.example/");
let externs_ast = ShExParser::parse(EXTERNS, Some(base.clone()), &base).expect("parse externs");
let resolver = SchemaExternalResolver::from_schema("test-externs", externs_ast);
let config_with_externs = || ValidatorConfig::default().with_external_resolver(resolver.clone());
assert!(validate("http://a.example/n2", config_with_externs()));
assert!(!validate("http://a.example/n1", config_with_externs()));
}