use oxirs_core::assembler::{from_turtle, AssemblerBuilder, StoreBackend};
fn t(s: &str, p: &str, o: &str) -> (String, String, String) {
(s.to_owned(), p.to_owned(), o.to_owned())
}
const RDF_TYPE: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
const JA_RDF_DATASET: &str = "http://jena.hpl.hp.com/2005/11/Assembler#RDFDataset";
const JA_MEMORY_DATASET: &str = "http://jena.hpl.hp.com/2005/11/Assembler#MemoryDataset";
const JA_MEMORY_MODEL: &str = "http://jena.hpl.hp.com/2005/11/Assembler#MemoryModel";
const JA_NAMED_GRAPH: &str = "http://jena.hpl.hp.com/2005/11/Assembler#namedGraph";
const JA_GRAPH_NAME: &str = "http://jena.hpl.hp.com/2005/11/Assembler#graphName";
const JA_GRAPH: &str = "http://jena.hpl.hp.com/2005/11/Assembler#graph";
const JA_DEFAULT_GRAPH: &str = "http://jena.hpl.hp.com/2005/11/Assembler#defaultGraph";
const JA_CONTENT_URL: &str = "http://jena.hpl.hp.com/2005/11/Assembler#contentURL";
const TDB2_DATASET: &str = "http://jena.apache.org/2016/tdb#DatasetTDB2";
const TDB2_LOCATION: &str = "http://jena.apache.org/2016/tdb#location";
#[test]
fn test_assembler_config_is_empty_when_no_datasets() {
let config = AssemblerBuilder::from_triples(&[]).unwrap();
assert!(config.is_empty());
assert_eq!(config.len(), 0);
}
#[test]
fn test_assembler_config_find_dataset_found() {
let triples = vec![t("http://example.org/ds", RDF_TYPE, JA_MEMORY_DATASET)];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
let found = config.find_dataset("http://example.org/ds");
assert!(found.is_some(), "expected to find dataset by IRI");
assert_eq!(found.unwrap().resource_iri, "http://example.org/ds");
}
#[test]
fn test_assembler_config_find_dataset_not_found() {
let triples = vec![t("http://example.org/ds", RDF_TYPE, JA_MEMORY_DATASET)];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
let found = config.find_dataset("http://example.org/other");
assert!(found.is_none(), "should not find non-existent dataset");
}
#[test]
fn test_in_memory_dataset_from_triples() {
let triples = vec![t("http://example.org/mem", RDF_TYPE, JA_MEMORY_DATASET)];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
assert_eq!(config.len(), 1);
let ds = config.find_dataset("http://example.org/mem").unwrap();
assert_eq!(ds.backend, StoreBackend::InMemory);
assert!(ds.named_graphs.is_empty());
assert!(ds.default_graph.is_none());
}
#[test]
fn test_tdb2_dataset_from_triples() {
let triples = vec![
t("http://example.org/tdb", RDF_TYPE, TDB2_DATASET),
t("http://example.org/tdb", TDB2_LOCATION, "\"/data/mydb\""),
];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
assert_eq!(config.len(), 1);
let ds = config.find_dataset("http://example.org/tdb").unwrap();
match &ds.backend {
StoreBackend::Tdb2 { location } => {
assert_eq!(location.to_str().unwrap(), "/data/mydb");
}
other => panic!("expected Tdb2, got {other:?}"),
}
}
#[test]
fn test_named_graph_from_triples() {
let triples = vec![
t("http://example.org/ds", RDF_TYPE, JA_RDF_DATASET),
t("http://example.org/ds", JA_NAMED_GRAPH, "_:b0"),
t("_:b0", JA_GRAPH_NAME, "http://example.org/g1"),
t("_:b0", JA_GRAPH, "http://example.org/model1"),
t("http://example.org/model1", RDF_TYPE, JA_MEMORY_MODEL),
];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
let ds = config.find_dataset("http://example.org/ds").unwrap();
assert_eq!(ds.named_graphs.len(), 1);
let ng = &ds.named_graphs[0];
assert_eq!(
ng.graph_name.as_deref(),
Some("http://example.org/g1"),
"graph name IRI should be preserved"
);
assert_eq!(ng.backend, StoreBackend::InMemory);
}
#[test]
fn test_default_graph_from_triples() {
let triples = vec![
t("http://example.org/ds", RDF_TYPE, JA_RDF_DATASET),
t(
"http://example.org/ds",
JA_DEFAULT_GRAPH,
"http://example.org/model1",
),
t("http://example.org/model1", RDF_TYPE, JA_MEMORY_MODEL),
];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
let ds = config.find_dataset("http://example.org/ds").unwrap();
assert!(ds.named_graphs.is_empty());
let dg = ds.default_graph.as_ref().unwrap();
assert!(dg.graph_name.is_none(), "default graph has no graph name");
assert_eq!(dg.backend, StoreBackend::InMemory);
}
#[test]
fn test_content_url_from_triples() {
let triples = vec![
t("http://example.org/ds", RDF_TYPE, JA_MEMORY_DATASET),
t("http://example.org/ds", JA_NAMED_GRAPH, "_:b0"),
t("_:b0", JA_GRAPH_NAME, "http://example.org/g1"),
t("_:b0", JA_GRAPH, "http://example.org/m1"),
t(
"http://example.org/m1",
JA_CONTENT_URL,
"\"http://example.org/data.ttl\"",
),
];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
let ds = config.find_dataset("http://example.org/ds").unwrap();
let ng = &ds.named_graphs[0];
assert_eq!(ng.content_urls.len(), 1);
assert_eq!(ng.content_urls[0], "http://example.org/data.ttl");
}
#[test]
fn test_from_turtle_memory_dataset() {
let ttl = r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
<http://example.org/ds> a ja:MemoryDataset .
"#;
let config = from_turtle(ttl).unwrap();
assert_eq!(config.len(), 1);
let ds = config.find_dataset("http://example.org/ds").unwrap();
assert_eq!(ds.backend, StoreBackend::InMemory);
}
#[test]
fn test_from_turtle_tdb2_dataset_with_location() {
let location = std::env::temp_dir()
.join(format!("oxirs_assembler_test_tdb2_{}", std::process::id()))
.display()
.to_string();
let ttl = format!(
r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix tdb2: <http://jena.apache.org/2016/tdb#> .
<http://example.org/tdb> a tdb2:DatasetTDB2 ;
tdb2:location "{location}" .
"#
);
let config = from_turtle(&ttl).unwrap();
assert_eq!(config.len(), 1);
let ds = config.find_dataset("http://example.org/tdb").unwrap();
match &ds.backend {
StoreBackend::Tdb2 { location: loc } => {
assert_eq!(loc.to_str().unwrap(), location);
}
other => panic!("expected Tdb2, got {other:?}"),
}
}
#[test]
fn test_from_turtle_named_graph() {
let ttl = r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
<http://example.org/ds> a ja:RDFDataset ;
ja:namedGraph [
ja:graphName <http://example.org/graph1> ;
ja:graph <http://example.org/model1>
] .
<http://example.org/model1> a ja:MemoryModel .
"#;
let config = from_turtle(ttl).unwrap();
let ds = config.find_dataset("http://example.org/ds").unwrap();
assert_eq!(ds.named_graphs.len(), 1);
let ng = &ds.named_graphs[0];
assert_eq!(ng.graph_name.as_deref(), Some("http://example.org/graph1"));
assert_eq!(ng.backend, StoreBackend::InMemory);
}
#[test]
fn test_from_turtle_multiple_datasets() {
let location = std::env::temp_dir()
.join(format!("oxirs_assembler_test_multi_{}", std::process::id()))
.display()
.to_string();
let ttl = format!(
r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix tdb2: <http://jena.apache.org/2016/tdb#> .
<http://example.org/ds1> a ja:MemoryDataset .
<http://example.org/ds2> a tdb2:DatasetTDB2 ;
tdb2:location "{location}" .
"#
);
let config = from_turtle(&ttl).unwrap();
assert_eq!(config.len(), 2, "two datasets should be found");
assert!(config.find_dataset("http://example.org/ds1").is_some());
assert!(config.find_dataset("http://example.org/ds2").is_some());
}
#[test]
fn test_from_turtle_empty_returns_empty_config() {
let ttl = r#"
@prefix ex: <http://example.org/> .
# No dataset declarations — just a comment
"#;
let config = from_turtle(ttl).unwrap();
assert!(config.is_empty());
}
#[test]
fn test_from_turtle_unknown_backend_preserved() {
let ttl = r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix ex: <http://example.org/> .
ex:ds a ex:CustomBackend .
"#;
let config = from_turtle(ttl).unwrap();
assert_eq!(
config.len(),
1,
"unrecognised type should still produce a dataset entry"
);
let ds = config.find_dataset("http://example.org/ds").unwrap();
match &ds.backend {
StoreBackend::Unknown(type_iri) => {
assert_eq!(type_iri, "http://example.org/CustomBackend");
}
other => panic!("expected Unknown, got {other:?}"),
}
}
#[test]
fn test_from_turtle_rdf_dataset_type() {
let ttl = r#"
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
<http://example.org/generic> a ja:RDFDataset .
"#;
let config = from_turtle(ttl).unwrap();
assert_eq!(config.len(), 1);
let ds = config.find_dataset("http://example.org/generic").unwrap();
assert_eq!(ds.backend, StoreBackend::InMemory);
}
#[test]
fn test_from_triples_unknown_backend_round_trips() {
let triples = vec![t(
"http://example.org/ds",
RDF_TYPE,
"http://example.org/FutureBackend",
)];
let config = AssemblerBuilder::from_triples(&triples).unwrap();
assert_eq!(
config.len(),
1,
"unknown rdf:type should still produce a dataset entry"
);
let ds = config.find_dataset("http://example.org/ds").unwrap();
match &ds.backend {
StoreBackend::Unknown(type_iri) => {
assert_eq!(type_iri, "http://example.org/FutureBackend");
}
other => panic!("expected Unknown, got {other:?}"),
}
}