use std::fmt::Debug;
use super::*;
use crate::graph::test::*;
use crate::ns::*;
use crate::quad::*;
use crate::source::*;
use lazy_static::lazy_static;
#[allow(missing_docs)]
mod ns {
use super::*;
lazy_static! {
pub static ref G1: NsTerm<'static> = NS.get("G1").unwrap();
pub static ref G2: NsTerm<'static> = NS.get("G2").unwrap();
pub static ref DG: Option<NsTerm<'static>> = None;
pub static ref GN1: Option<NsTerm<'static>> = Some(*G1);
pub static ref GN2: Option<NsTerm<'static>> = Some(*G2);
}
}
pub use ns::*;
pub fn no_quad() -> impl QuadSource {
let v = Vec::<Spog<StaticTerm>>::new();
v.into_iter().into_source()
}
pub const SOME_QUADS_COUNT: usize = 18;
pub fn some_quads() -> impl QuadSource {
let v: Vec<Spog<NsTerm<'static>>> = vec![
([*C1, rdf::type_, rdfs::Class], *DG),
([*C1, rdf::type_, rdfs::Class], *GN1),
([*C2, rdf::type_, rdfs::Class], *DG),
([*C2, rdfs::subClassOf, *C1], *GN1),
([*C2, rdfs::subClassOf, rdfs::Resource], *GN1),
([*P1, rdf::type_, rdf::Property], *DG),
([*P1, rdfs::domain, *C1], *GN1),
([*P1, rdfs::range, *C2], *GN1),
([*P2, rdf::type_, rdf::Property], *DG),
([*P2, rdfs::domain, *C2], *GN1),
([*P2, rdfs::range, *C2], *GN1),
([*I1A, rdf::type_, *C1], *GN2),
([*I1B, rdf::type_, *C1], *GN2),
([*I2A, rdf::type_, *C2], *GN2),
([*I2B, rdf::type_, *C2], *GN2),
([*I1A, *P1, *I2A], *GN2),
([*I1B, *P1, *I2B], *GN2),
([*I2A, *P2, *I2B], *GN2),
];
assert_eq!(v.len(), SOME_QUADS_COUNT);
v.into_iter().into_source()
}
pub const NODE_TYPES_COUNT: usize = 5;
pub fn strict_node_types_quads() -> impl QuadSource {
let v: Vec<Spog<StaticTerm>> = vec![
(
[t(rdf::type_), t(rdf::type_), t(rdf::Property)],
Some(t(rdf::type_)),
),
([t(B1), t(rdf::value), t("lit1")], Some(t(B3))),
([t(B2), t(rdf::value), t(B1)], None),
([t(B2), t(rdf::value), t("lit2")], None),
([t(B2), t(rdf::value), t("lit2" * EN)], None),
];
assert_eq!(v.len(), NODE_TYPES_COUNT);
v.into_iter().into_source()
}
pub fn generalized_node_types_quads() -> impl QuadSource {
let v: Vec<Spog<StaticTerm>> = vec![
(
[t(rdf::type_), t(rdf::type_), t(rdf::Property)],
Some(t(rdf::type_)),
),
([t(B1), t(B2), t(B1)], Some(t(B3))),
([t("lit2"), t("lit1"), t("lit1")], Some(t("lit3"))),
([t(V1), t(V1), t(V2)], Some(t(V3))),
(
[
tt(V1, B1, "lit1"),
tt(B2, "lit2", V2),
tt("lit2" * EN, B1, tt(V2, rdf::value, rdf::type_)),
],
Some(tt(V3, rdf::value, rdf::type_)),
),
];
assert_eq!(v.len(), NODE_TYPES_COUNT);
v.into_iter().into_source()
}
pub fn dump_dataset<D: Dataset>(d: &D)
where
for<'x> DTerm<'x, D>: Debug,
{
println!("<<<<");
for q in d.quads() {
let q = q.unwrap();
println!("{:?}\n{:?}\n{:?}\n{:?}\n\n", q.s(), q.p(), q.o(), q.g());
}
println!(">>>>");
}
#[macro_export]
macro_rules! test_dataset_impl {
($dataset_impl: ident) => {
$crate::test_dataset_impl!(test, $dataset_impl);
};
($module_name: ident, $dataset_impl: ident) => {
$crate::test_dataset_impl!($module_name, $dataset_impl, true);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr) => {
$crate::test_dataset_impl!($module_name, $dataset_impl, $is_set, true);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr, $is_gen: expr) => {
$crate::test_dataset_impl!($module_name, $dataset_impl, $is_set, $is_gen, $dataset_impl::from_quad_source);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr, $is_gen: expr, $dataset_collector: path) => {
$crate::test_dataset_impl!($module_name, $dataset_impl, $is_set, $is_gen, $dataset_collector, {
#[test]
fn simple_mutations() -> Result<(), Box<dyn std::error::Error>> {
let mut d: $dataset_impl = $dataset_collector(no_quad()).unwrap();
assert_eq!(d.quads().count(), 0);
assert!(MutableDataset::insert(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 1);
assert!(MutableDataset::insert(
&mut d,
&*C1,
&rdfs::subClassOf,
&*C2,
GN1.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 2);
assert!(MutableDataset::remove(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 1);
assert!(MutableDataset::remove(
&mut d,
&*C1,
&rdfs::subClassOf,
&*C2,
GN1.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 0);
Ok(())
}
#[test]
fn handle_duplicate() -> Result<(), Box<dyn std::error::Error>> {
let mut d: $dataset_impl = $dataset_collector(no_quad()).unwrap();
assert_eq!(d.quads().count(), 0);
assert!(MutableDataset::insert(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 1);
assert!(!MutableDataset::insert(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
if $is_set {
assert_eq!(d.quads().count(), 1);
} else {
assert!(d.quads().count() >= 1);
}
assert!(MutableDataset::remove(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 0);
assert!(!MutableDataset::remove(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 0);
Ok(())
}
#[test]
fn different_graphs_do_not_count_as_duplicate() -> Result<(), Box<dyn std::error::Error>> {
let mut d: $dataset_impl = $dataset_collector(no_quad()).unwrap();
assert_eq!(d.quads().count(), 0);
assert!(MutableDataset::insert(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 1);
assert!(MutableDataset::insert(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
GN1.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 2);
assert!(MutableDataset::remove(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
DG.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 1);
assert!(MutableDataset::remove(
&mut d,
&*C1,
&rdf::type_,
&rdfs::Class,
GN1.as_ref(),
)? || !$is_set);
assert_eq!(d.quads().count(), 0);
Ok(())
}
#[test]
fn x_all_mutations() {
let mut d: $dataset_impl = $dataset_collector(no_quad()).unwrap();
assert_eq!(d.quads().count(), 0);
let inserted = d.insert_all(some_quads()).unwrap();
if $is_set {
assert_eq!(inserted, 18, "returned by insert_all");
}
assert_eq!(d.quads().count(), 18, "after insert_all");
if $is_set {
let inserted = d.insert_all(some_quads()).unwrap();
assert_eq!(inserted, 0, "returned by insert_all again");
assert_eq!(d.quads().count(), 18, "after insert_all again");
}
let removed = d.remove_all(some_quads()).unwrap();
if $is_set {
assert_eq!(removed, 18, "returned by remove_all");
}
assert_eq!(d.quads().count(), 0, "after remove_all");
if $is_set {
let removed = d.remove_all(some_quads()).unwrap();
assert_eq!(removed, 0, "returned by remove_all again");
assert_eq!(d.quads().count(), 0, "after remove_all again");
}
}
#[test]
fn remove_matching() -> Result<(), Box<dyn std::error::Error>> {
let mut d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
d.remove_matching(Any, [rdf::type_], [*C1, *C2], Any)?;
assert_consistent_hint(14, d.quads().size_hint());
Ok(())
}
#[test]
fn retain_matching() -> Result<(), Box<dyn std::error::Error>> {
let mut d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
d.retain_matching(Any, [rdf::type_], [*C1, *C2], Any)?;
assert_consistent_hint(4, d.quads().size_hint());
Ok(())
}
});
};
($module_name: ident, $dataset_impl: ident, $is_set: expr, $is_gen: expr, $dataset_collector: path, { $($mt:tt)* }) => {
#[cfg(test)]
mod $module_name {
use $crate::dataset::test::*;
use $crate::dataset::*;
use $crate::graph::test::*;
use $crate::ns::*;
use $crate::term::{Term, TermKind};
use $crate::term::matcher::Any;
use std::collections::HashSet;
#[allow(unused_imports)] use super::*;
#[test]
fn quads() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
for iter in [Box::new(d.quads()) as Box<dyn Iterator<Item=_>>, Box::new(d.quads_matching(Any, Any, Any, Any))] {
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), d.quads().count());
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, &rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(Dataset::contains(&v, *C1, &rdf::type_, rdfs::Class, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *P1, &rdf::type_, rdfs::Class, DG.as_ref())?);
}
Ok(())
}
#[test]
fn quads_with_s() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C2], Any, Any, Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 3);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, &*C2, &rdf::type_, &rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
&*C2,
&rdf::type_,
&rdfs::Class,
GN1.as_ref(),
)?);
assert!(!Dataset::contains(
&v,
&*C2,
&rdf::type_,
&rdf::Property,
DG.as_ref(),
)?);
Ok(())
}
#[test]
fn quads_with_p() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, [rdfs::subClassOf], Any, Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
&*C2,
&rdfs::subClassOf,
&rdfs::Class,
DG.as_ref(),
)?);
Ok(())
}
#[test]
fn quads_with_o() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, Any, [*I2B], Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *I1B, *P1, *I2B, GN2.as_ref())?);
assert!(!Dataset::contains(&v, *I1B, *P1, *I2B, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *I2A, *P1, *I2B, GN2.as_ref())?);
Ok(())
}
#[test]
fn quads_with_g() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, Any, Any, [GN1.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 7);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_sp() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C2], [rdf::type_], Any, Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C2,
rdf::type_,
rdfs::Class,
GN1.as_ref(),
)?);
assert!(!Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_so() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C2], Any, [*C1], Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, DG.as_ref())?);
assert!(!Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_po() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, [rdf::type_], [rdfs::Class], Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 3);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C1,
rdf::type_,
rdfs::Class,
GN2.as_ref(),
)?);
assert!(!Dataset::contains(
&v,
*P1,
rdf::type_,
rdf::Property,
DG.as_ref(),
)?);
Ok(())
}
#[test]
fn quads_with_sg() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C2], Any, Any, [GN1.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, DG.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_pg() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, [rdf::type_], Any, [GN1.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, GN1.as_ref())?);
Ok(())
}
#[test]
fn quads_with_og() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, Any, [*C1], [GN1.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdfs::subClassOf, *C1, DG.as_ref())?);
assert!(!Dataset::contains(&v, *I1A, rdf::type_, *C1, GN2.as_ref())?);
Ok(())
}
#[test]
fn quads_with_spo() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C1], [rdf::type_], [rdfs::Class], Any);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, GN1.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_spg() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C1], [rdf::type_], Any, [DG.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C1,
rdf::type_,
rdfs::Class,
GN1.as_ref(),
)?);
Ok(())
}
#[test]
fn quads_with_sog() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C1], Any, [rdfs::Class], [DG.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C1,
rdf::type_,
rdfs::Class,
GN1.as_ref(),
)?);
assert!(!Dataset::contains(&v, *C2, &rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn quads_with_pog() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching(Any, [rdf::type_], [rdfs::Class], [DG.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 2);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C1,
rdf::type_,
rdfs::Class,
GN1.as_ref(),
)?);
Ok(())
}
#[test]
fn quads_with_spog() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let iter = d.quads_matching([*C1], [rdf::type_], [rdfs::Class], [DG.as_ref()]);
let hint = iter.size_hint();
let v: Vec<_> = iter.map(Result::unwrap).collect();
assert_eq!(v.len(), 1);
assert_consistent_hint(v.len(), hint);
assert!(Dataset::contains(&v, *C1, rdf::type_, rdfs::Class, DG.as_ref())?);
assert!(!Dataset::contains(
&v,
*C1,
rdf::type_,
rdfs::Class,
GN1.as_ref(),
)?);
assert!(!Dataset::contains(&v, *C2, rdf::type_, rdfs::Class, DG.as_ref())?);
Ok(())
}
#[test]
fn contains() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
assert!(Dataset::contains(&d, &*C2, &rdfs::subClassOf, &*C1, GN1.as_ref())?);
assert!(!Dataset::contains(&d, &*C1, &rdfs::subClassOf, &*C2, GN1.as_ref())?);
Ok(())
}
#[test]
fn subjects() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let subjects: HashSet<StaticTerm> = d.subjects().map(|t| t.unwrap().into_term()).collect();
assert_eq!(subjects.len(), 8);
assert_contains(&subjects, &*C1);
assert_contains(&subjects, &*C2);
assert_contains(&subjects, &*P1);
assert_contains(&subjects, &*P2);
assert_contains(&subjects, &*I1A);
assert_contains(&subjects, &*I1B);
assert_contains(&subjects, &*I2A);
assert_contains(&subjects, &*I2B);
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let kinds: HashSet<_> = d.subjects().map(|t| t.unwrap().kind()).collect();
assert_eq!(kinds.len(), if $is_gen {5} else {2});
assert!(kinds.contains(&TermKind::Iri));
assert!(kinds.contains(&TermKind::BlankNode));
Ok(())
}
#[test]
fn predicates() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let predicates: HashSet<StaticTerm> = d.predicates().map(|t| t.unwrap().into_term()).collect();
assert_eq!(predicates.len(), 6);
assert_contains(&predicates, &rdf::type_);
assert_contains(&predicates, &rdfs::subClassOf);
assert_contains(&predicates, &rdfs::domain);
assert_contains(&predicates, &rdfs::range);
assert_contains(&predicates, &*P1);
assert_contains(&predicates, &*P2);
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let kinds: HashSet<_> = d.predicates().map(|t| t.unwrap().kind()).collect();
assert_eq!(kinds.len(), if $is_gen {5} else {1});
assert!(kinds.contains(&TermKind::Iri));
Ok(())
}
#[test]
fn objects() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let objects: HashSet<StaticTerm> = d.objects().map(|t| t.unwrap().into_term()).collect();
assert_eq!(objects.len(), 7);
assert_contains(&objects, &rdf::Property);
assert_contains(&objects, &rdfs::Class);
assert_contains(&objects, &rdfs::Resource);
assert_contains(&objects, &*C1);
assert_contains(&objects, &*C2);
assert_contains(&objects, &*I2A);
assert_contains(&objects, &*I2B);
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let kinds: HashSet<_> = d.objects().map(|t| t.unwrap().kind()).collect();
assert_eq!(kinds.len(), if $is_gen {5} else {3});
assert!(kinds.contains(&TermKind::Iri));
assert!(kinds.contains(&TermKind::BlankNode));
assert!(kinds.contains(&TermKind::Literal));
Ok(())
}
#[test]
fn graph_names() -> Result<(), Box<dyn std::error::Error>> {
let d: $dataset_impl = $dataset_collector(some_quads()).unwrap();
let graph_names: HashSet<StaticTerm> = d.graph_names().map(|t| t.unwrap().into_term()).collect();
assert_eq!(graph_names.len(), 2);
assert_contains(&graph_names, &*G1);
assert_contains(&graph_names, &*G2);
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let kinds: HashSet<_> = d.graph_names().map(|t| t.unwrap().kind()).collect();
assert_eq!(kinds.len(), if $is_gen {5} else {2});
assert!(kinds.contains(&TermKind::Iri));
assert!(kinds.contains(&TermKind::BlankNode));
Ok(())
}
#[test]
fn iris() -> Result<(), Box<dyn std::error::Error>> {
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let iris: HashSet<StaticTerm> = d.iris().map(|t| t.unwrap().into_term()).collect();
assert_eq!(iris.len(), 3);
assert_contains(&iris, &rdf::Property);
assert_contains(&iris, &rdf::type_);
assert_contains(&iris, &rdf::value);
Ok(())
}
#[test]
fn bnodes() -> Result<(), Box<dyn std::error::Error>> {
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let bnodes: HashSet<StaticTerm> = d.blank_nodes().map(|t| t.unwrap().into_term()).collect();
assert_eq!(bnodes.len(), 3);
assert_contains(&bnodes, &B1);
assert_contains(&bnodes, &B2);
assert_contains(&bnodes, &B3);
Ok(())
}
#[test]
fn literals() -> Result<(), Box<dyn std::error::Error>> {
let d = if $is_gen {
$dataset_collector(generalized_node_types_quads()).unwrap()
} else {
$dataset_collector(strict_node_types_quads()).unwrap()
};
let literals: HashSet<StaticTerm> = d.literals().map(|t| t.unwrap().into_term()).collect();
assert_eq!(literals.len(), if $is_gen {4} else {3});
assert_contains(&literals, &"lit1");
assert_contains(&literals, &"lit2");
assert_contains(&literals, &("lit2"*EN));
if $is_gen {
assert_contains(&literals, &"lit3");
}
Ok(())
}
#[test]
fn quoted_triples() -> Result<(), Box<dyn std::error::Error>> {
if $is_gen {
let d: $dataset_impl = $dataset_collector(generalized_node_types_quads()).unwrap();
let quads: HashSet<StaticTerm> = d.quoted_triples().map(|t| t.unwrap().into_term()).collect();
assert_eq!(quads.len(), 5);
let t1 = StaticTerm::from_triple([
V1.as_simple(),
B1.as_simple(),
"lit1".as_simple(),
]);
let t2 = StaticTerm::from_triple([
B2.as_simple(),
"lit2".as_simple(),
V2.as_simple(),
]);
let t3 = StaticTerm::from_triple([
V2.as_simple(),
rdf::value.as_simple(),
rdf::type_.as_simple(), ]);
let t4 = StaticTerm::from_triple([
"lit2"*EN,
B1.as_simple(),
t3.clone(),
]);
let t5 = StaticTerm::from_triple([
V3.as_simple(),
rdf::value.as_simple(),
rdf::type_.as_simple(),
]);
assert_contains(&quads, &t1);
assert_contains(&quads, &t2);
assert_contains(&quads, &t3);
assert_contains(&quads, &t4);
assert_contains(&quads, &t5);
} else {
let d: $dataset_impl = $dataset_collector(strict_node_types_quads()).unwrap();
let quads: HashSet<StaticTerm> = d.quoted_triples().map(|t| t.unwrap().into_term()).collect();
assert_eq!(quads.len(), 0);
}
Ok(())
}
#[test]
fn variables() -> Result<(), Box<dyn std::error::Error>> {
if $is_gen {
let d: $dataset_impl = $dataset_collector(generalized_node_types_quads()).unwrap();
let variables: HashSet<StaticTerm> = d.variables().map(|t| t.unwrap().into_term()).collect();
assert_eq!(variables.len(), 3);
assert_contains(&variables, &V1);
assert_contains(&variables, &V2);
assert_contains(&variables, &V3);
} else {
let d: $dataset_impl = $dataset_collector(strict_node_types_quads()).unwrap();
let variables: HashSet<StaticTerm> = d.variables().map(|t| t.unwrap().into_term()).collect();
assert_eq!(variables.len(), 0);
}
Ok(())
}
$($mt)*
}
};
}
#[macro_export]
macro_rules! test_immutable_dataset_impl {
($dataset_impl: ident) => {
$crate::test_immutable_dataset_impl!(test, $dataset_impl);
};
($module_name: ident, $dataset_impl: ident) => {
$crate::test_immutable_dataset_impl!($module_name, $dataset_impl, true);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr) => {
$crate::test_immutable_dataset_impl!($module_name, $dataset_impl, $is_set, true);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr, $is_gen: expr) => {
$crate::test_immutable_dataset_impl!(
$module_name,
$dataset_impl,
$is_set,
$is_gen,
$dataset_impl::from_quad_source
);
};
($module_name: ident, $dataset_impl: ident, $is_set: expr, $is_gen: expr, $dataset_collector: path) => {
$crate::test_dataset_impl!(
$module_name,
$dataset_impl,
$is_set,
$is_gen,
$dataset_collector,
{}
);
};
}