1use lazy_static::lazy_static;
3use std::fmt::Debug;
4
5use super::*;
6use crate::ns::*;
7use crate::source::*;
8use crate::term::*;
9
10pub type StaticTerm = SimpleTerm<'static>;
12
13#[allow(missing_docs)]
14mod ns {
15 use super::*;
16 pub const NS: Namespace<&str> = Namespace::new_unchecked_const("http://example.org/");
17 lazy_static! {
18 pub static ref C1: NsTerm<'static> = NS.get("C1").unwrap();
19 pub static ref C2: NsTerm<'static> = NS.get("C2").unwrap();
20 pub static ref P1: NsTerm<'static> = NS.get("p1").unwrap();
21 pub static ref P2: NsTerm<'static> = NS.get("p2").unwrap();
22 pub static ref I1A: NsTerm<'static> = NS.get("I1A").unwrap();
23 pub static ref I1B: NsTerm<'static> = NS.get("I1B").unwrap();
24 pub static ref I2A: NsTerm<'static> = NS.get("I2A").unwrap();
25 pub static ref I2B: NsTerm<'static> = NS.get("I2B").unwrap();
26 }
27 pub const B1: BnodeId<&str> = BnodeId::new_unchecked_const("1");
28 pub const B2: BnodeId<&str> = BnodeId::new_unchecked_const("2");
29 pub const B3: BnodeId<&str> = BnodeId::new_unchecked_const("3");
30 pub const EN: LanguageTag<&str> = LanguageTag::new_unchecked_const("en");
31 pub const V1: VarName<&str> = VarName::new_unchecked_const("v1");
32 pub const V2: VarName<&str> = VarName::new_unchecked_const("v2");
33 pub const V3: VarName<&str> = VarName::new_unchecked_const("v3");
34}
35pub use ns::*;
36
37pub fn no_triple() -> impl TripleSource {
39 let v = Vec::<[StaticTerm; 3]>::new();
40 v.into_iter().into_source()
41}
42
43pub const SOME_TRIPLES_COUNT: usize = 18;
45
46pub fn some_triples() -> impl TripleSource {
48 let v = vec![
49 [*C1, rdf::type_, rdfs::Class],
50 [*C2, rdf::type_, rdfs::Class],
51 [*C2, rdf::type_, rdfs::Resource],
52 [*C2, rdfs::subClassOf, *C1],
53 [*C2, rdfs::subClassOf, rdfs::Resource],
54 [*P1, rdf::type_, rdf::Property],
56 [*P1, rdfs::domain, *C1],
57 [*P1, rdfs::range, *C2],
58 [*P2, rdf::type_, rdf::Property],
60 [*P2, rdfs::domain, *C2],
61 [*P2, rdfs::range, *C2],
62 [*I1A, rdf::type_, *C1],
64 [*I1B, rdf::type_, *C1],
65 [*I2A, rdf::type_, *C2],
66 [*I2B, rdf::type_, *C2],
67 [*I1A, *P1, *I2A],
68 [*I1B, *P1, *I2B],
69 [*I2A, *P2, *I2B],
70 ];
71 assert_eq!(v.len(), SOME_TRIPLES_COUNT);
72 v.into_iter().into_source()
73}
74
75pub(crate) fn t<T: Term>(t: T) -> StaticTerm {
77 t.into_term()
78}
79
80pub(crate) fn tt<T1: Term, T2: Term, T3: Term>(s: T1, p: T2, o: T3) -> StaticTerm {
82 StaticTerm::from_triple([t(s), t(p), t(o)])
83}
84
85pub const NODE_TYPES_COUNT: usize = 5;
88
89pub fn strict_node_types_triples() -> impl TripleSource {
92 let v = vec![
93 [t(rdf::type_), t(rdf::type_), t(rdf::Property)],
94 [t(B1), t(rdf::value), t("lit1")],
95 [t(B2), t(rdf::value), t(B1)],
96 [t(B2), t(rdf::value), t("lit2")],
97 [t(B2), t(rdf::value), t("lit2" * EN)],
98 ];
99 assert_eq!(v.len(), NODE_TYPES_COUNT);
100 v.into_iter().into_source()
101}
102
103pub fn generalized_node_types_triples() -> impl TripleSource {
106 let v = vec![
107 [t(rdf::type_), t(rdf::type_), t(rdf::Property)],
108 [t(B1), t(B2), t(B1)],
109 [t("lit2"), t("lit1"), t("lit1")],
110 [t(V1), t(V1), t(V2)],
111 [
112 tt(V1, B1, "lit1"),
113 tt(B2, "lit2", V2),
114 tt("lit2" * EN, B1, tt(V2, rdf::value, rdf::type_)),
115 ],
116 ];
117 assert_eq!(v.len(), NODE_TYPES_COUNT);
118 v.into_iter().into_source()
119}
120
121pub fn dump_graph<G: Graph>(g: &G)
123where
124 for<'x> GTerm<'x, G>: Debug,
125{
126 println!("<<<<");
127 for t in g.triples() {
128 let t = t.unwrap();
129 println!("{:?}\n{:?}\n{:?}\n\n", t.s(), t.p(), t.o());
130 }
131 println!(">>>>");
132}
133
134pub fn assert_consistent_hint(val: usize, hint: (usize, Option<usize>)) {
136 assert!(hint.0 <= val, "hint {:?} not consistent with {}", hint, val);
137 assert!(
138 val <= hint.1.unwrap_or(val),
139 "hint {:?} not consistent with {}",
140 hint,
141 val
142 )
143}
144
145pub fn assert_contains<'a, I, T, U>(collection: I, term: &U)
148where
149 I: IntoIterator<Item = &'a T>,
150 T: Term + 'a,
151 U: Term,
152{
153 assert!(collection.into_iter().any(|t| term.eq(t.borrow_term())))
154}
155
156#[macro_export]
177macro_rules! test_graph_impl {
178 ($graph_impl: ident) => {
179 $crate::test_graph_impl!(test, $graph_impl);
180 };
181 ($module_name: ident, $graph_impl: ident) => {
182 $crate::test_graph_impl!($module_name, $graph_impl, true);
183 };
184 ($module_name: ident, $graph_impl: ident, $is_set: expr) => {
185 $crate::test_graph_impl!($module_name, $graph_impl, $is_set, true);
186 };
187 ($module_name: ident, $graph_impl: ident, $is_set: expr, $is_gen: expr) => {
188 $crate::test_graph_impl!($module_name, $graph_impl, $is_set, $is_gen, $graph_impl::from_triple_source);
189 };
190 ($module_name: ident, $graph_impl: ident, $is_set: expr, $is_gen: expr, $graph_collector: path) => {
191 $crate::test_graph_impl!($module_name, $graph_impl, $is_set, $is_gen, $graph_collector, {
192 #[test]
194 fn simple_mutations() -> Result<(), Box<dyn std::error::Error>> {
195 let mut g: $graph_impl = $graph_collector(no_triple()).unwrap();
196 assert_eq!(g.triples().count(), 0);
197 assert!(MutableGraph::insert(
198 &mut g,
199 &*C1,
200 &rdf::type_,
201 &rdfs::Class
202 )? || !$is_set);
203 assert_eq!(g.triples().count(), 1);
204 assert!(MutableGraph::insert(&mut g, &*C1, &rdfs::subClassOf, &*C2)? || !$is_set);
205 assert_eq!(g.triples().count(), 2);
206 assert!(MutableGraph::remove(
207 &mut g,
208 &*C1,
209 &rdf::type_,
210 &rdfs::Class
211 )? || !$is_set);
212 assert_eq!(g.triples().count(), 1);
213 assert!(MutableGraph::remove(&mut g, &*C1, &rdfs::subClassOf, &*C2)? || !$is_set);
214 assert_eq!(g.triples().count(), 0);
215 Ok(())
216 }
217
218 #[test]
219 fn handle_duplicate() -> Result<(), Box<dyn std::error::Error>> {
220 let mut g: $graph_impl = $graph_collector(no_triple()).unwrap();
221 assert_eq!(g.triples().count(), 0);
222 assert!(MutableGraph::insert(
223 &mut g,
224 &*C1,
225 &rdf::type_,
226 &rdfs::Class
227 )? || !$is_set);
228 assert_eq!(g.triples().count(), 1);
229 assert!(!MutableGraph::insert(
230 &mut g,
231 &*C1,
232 &rdf::type_,
233 &rdfs::Class
234 )? || !$is_set);
235 if $is_set {
236 assert_eq!(g.triples().count(), 1);
237 } else {
238 assert!(g.triples().count() >= 1);
239 }
240 assert!(MutableGraph::remove(
241 &mut g,
242 &*C1,
243 &rdf::type_,
244 &rdfs::Class
245 )? || !$is_set);
246 assert_eq!(g.triples().count(), 0);
247 assert!(!MutableGraph::remove(
248 &mut g,
249 &*C1,
250 &rdf::type_,
251 &rdfs::Class
252 )? || !$is_set);
253 assert_eq!(g.triples().count(), 0);
254 Ok(())
255 }
256
257 #[test]
258 fn x_all_mutations() {
259 let mut g: $graph_impl = $graph_collector(no_triple()).unwrap();
260 assert_eq!(g.triples().count(), 0);
261 let inserted = g.insert_all(some_triples()).unwrap();
262 if $is_set {
263 assert_eq!(inserted, 18, "returned by insert_all");
264 }
265 assert_eq!(g.triples().count(), 18, "after insert_all");
266 if $is_set {
267 let inserted = g.insert_all(some_triples()).unwrap();
268 assert_eq!(inserted, 0, "returned by insert_all again");
269 assert_eq!(g.triples().count(), 18, "after insert_all again");
270 }
271 let removed = g.remove_all(some_triples()).unwrap();
272 if $is_set {
273 assert_eq!(removed, 18, "returned by remove_all");
274 }
275 assert_eq!(g.triples().count(), 0, "after remove_all");
276 if $is_set {
277 let removed = g.remove_all(some_triples()).unwrap();
278 assert_eq!(removed, 0, "returned by remove_all again");
279 assert_eq!(g.triples().count(), 0, "after remove_all again");
280 }
281 }
282
283 #[test]
284 fn remove_matching() -> Result<(), Box<dyn std::error::Error>> {
285 let mut g: $graph_impl = $graph_collector(some_triples()).unwrap();
286
287 let o_matcher: &[_] = &[*C1, *C2];
288 g.remove_matching(Any, [rdf::type_], o_matcher)?;
289 assert_consistent_hint(14, g.triples().size_hint());
290 Ok(())
291 }
292
293 #[test]
294 fn retain_matching() -> Result<(), Box<dyn std::error::Error>> {
295 let mut g: $graph_impl = $graph_collector(some_triples()).unwrap();
296
297 let o_matcher: &[_] = &[*C1, *C2];
298 g.retain_matching(Any, [rdf::type_], o_matcher)?;
299 assert_consistent_hint(4, g.triples().size_hint());
300 Ok(())
301 }
302 });
303 };
304 ($module_name: ident, $graph_impl: ident, $is_set: expr, $is_gen: expr, $graph_collector: path, { $($mt:tt)* }) => {
305 #[cfg(test)]
306 mod $module_name {
307 use $crate::graph::test::*;
308 use $crate::graph::*;
309 use $crate::ns::*;
310 use $crate::term::{SimpleTerm, Term, TermKind};
311 use $crate::term::matcher::Any;
312 use std::collections::HashSet;
313
314 #[allow(unused_imports)] use super::*;
316
317 #[test]
318 fn triples() -> Result<(), Box<dyn std::error::Error>> {
319 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
320
321 for iter in [Box::new(g.triples()) as Box<dyn Iterator<Item=_>>, Box::new(g.triples_matching(Any, Any, Any))] {
322 let hint = iter.size_hint();
323 let v: Vec<_> = iter.map(Result::unwrap).collect();
324 assert_eq!(v.len(), SOME_TRIPLES_COUNT);
325 assert_consistent_hint(v.len(), hint);
326 assert!(Graph::contains(&v, *C1, rdf::type_, rdfs::Class)?);
327 assert!(!Graph::contains(&v, *P1, rdf::type_, rdfs::Class)?);
328 }
329 Ok(())
330 }
331
332 #[test]
333 fn triples_with_s() -> Result<(), Box<dyn std::error::Error>> {
334 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
335
336 let iter = g.triples_matching([*C2], Any, Any);
337 let hint = iter.size_hint();
338 let v: Vec<_> = iter.map(Result::unwrap).collect();
339 assert_eq!(v.len(), 4);
340 assert_consistent_hint(v.len(), hint);
341 assert!(Graph::contains(&v, &*C2, &rdf::type_, &rdfs::Class)?);
342 assert!(!Graph::contains(&v, &*C1, &rdf::type_, &rdfs::Class)?);
343 Ok(())
344 }
345
346 #[test]
347 fn triples_with_p() -> Result<(), Box<dyn std::error::Error>> {
348 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
349
350 let iter = g.triples_matching(Any, [rdf::type_], Any);
351 let hint = iter.size_hint();
352 let v: Vec<_> = iter.map(Result::unwrap).collect();
353 assert_eq!(v.len(), 9);
354 assert_consistent_hint(v.len(), hint);
355 assert!(Graph::contains(&v, *C2, rdf::type_, rdfs::Resource)?);
356 assert!(!Graph::contains(
357 &v,
358 *C2,
359 rdfs::subClassOf,
360 rdfs::Resource
361 )?);
362 Ok(())
363 }
364
365 #[test]
366 fn triples_with_o() -> Result<(), Box<dyn std::error::Error>> {
367 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
368
369 let iter = g.triples_matching(Any, Any, [*C2]);
370 let hint = iter.size_hint();
371 let v: Vec<_> = iter.map(Result::unwrap).collect();
372 assert_eq!(v.len(), 5);
373 assert_consistent_hint(v.len(), hint);
374 assert!(Graph::contains(&v, *P2, rdfs::domain, *C2)?);
375 assert!(!Graph::contains(&v, *P1, rdfs::domain, *C1)?);
376 Ok(())
377 }
378
379 #[test]
380 fn triples_with_sp() -> Result<(), Box<dyn std::error::Error>> {
381 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
382
383 let iter = g.triples_matching([*C2], [rdf::type_], Any);
384 let hint = iter.size_hint();
385 let v: Vec<_> = iter.map(Result::unwrap).collect();
386 assert_eq!(v.len(), 2);
387 assert_consistent_hint(v.len(), hint);
388 assert!(Graph::contains(&v, *C2, &rdf::type_, rdfs::Class)?);
389 assert!(!Graph::contains(&v, *C2, &rdfs::subClassOf, *C1)?);
390 Ok(())
391 }
392
393 #[test]
394 fn triples_with_so() -> Result<(), Box<dyn std::error::Error>> {
395 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
396
397 let iter = g.triples_matching([*C2], Any, [rdfs::Resource]);
398 let hint = iter.size_hint();
399 let v: Vec<_> = iter.map(Result::unwrap).collect();
400 assert_eq!(v.len(), 2);
401 assert_consistent_hint(v.len(), hint);
402 assert!(Graph::contains(
403 &v,
404 *C2,
405 rdfs::subClassOf,
406 rdfs::Resource
407 )?);
408 assert!(!Graph::contains(&v, *C2, rdf::type_, rdfs::Class)?);
409 Ok(())
410 }
411
412 #[test]
413 fn triples_with_po() -> Result<(), Box<dyn std::error::Error>> {
414 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
415
416 let iter = g.triples_matching(Any, [rdf::type_], [rdfs::Class]);
417 let hint = iter.size_hint();
418 let v: Vec<_> = iter.map(Result::unwrap).collect();
419 assert_eq!(v.len(), 2);
420 assert_consistent_hint(v.len(), hint);
421 assert!(Graph::contains(&v, *C2, rdf::type_, rdfs::Class)?);
422 assert!(!Graph::contains(&v, *P2, rdf::type_, rdf::Property)?);
423 Ok(())
424 }
425
426 #[test]
427 fn triples_with_spo() -> Result<(), Box<dyn std::error::Error>> {
428 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
429
430 let iter = g.triples_matching([*C2], [rdf::type_], [rdfs::Resource]);
431 let hint = iter.size_hint();
432 let v: Vec<_> = iter.map(Result::unwrap).collect();
433 assert_eq!(v.len(), 1);
434 assert_consistent_hint(v.len(), hint);
435 assert!(Graph::contains(&v, *C2, rdf::type_, rdfs::Resource)?);
436 assert!(!Graph::contains(
437 &v,
438 *C1,
439 rdfs::subClassOf,
440 rdfs::Resource
441 )?);
442 Ok(())
443 }
444
445 #[test]
446 fn triples_matching() -> Result<(), Box<dyn std::error::Error>> {
447 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
448
449 let iter = g.triples_matching([*C2, *P2], [rdf::type_, rdfs::domain], |t: SimpleTerm<'_>| !Term::eq(&t, rdfs::Class));
450 let hint = iter.size_hint();
451 let v: Vec<_> = iter.map(Result::unwrap).collect();
452 assert_eq!(v.len(), 3);
453 assert_consistent_hint(v.len(), hint);
454 assert!(Graph::contains(&v, *C2, rdf::type_, rdfs::Resource)?);
455 assert!(!Graph::contains(
456 &v,
457 *C2,
458 rdf::type_,
459 rdfs::Class,
460 )?);
461 Ok(())
462 }
463
464 #[test]
465 fn contains() -> Result<(), Box<dyn std::error::Error>> {
466 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
467
468 assert!(Graph::contains(&g, &*C2, &rdfs::subClassOf, &*C1)?);
469 assert!(!Graph::contains(&g, &*C1, &rdfs::subClassOf, &*C2)?);
470 Ok(())
471 }
472
473 #[test]
474 fn subjects() -> Result<(), Box<dyn std::error::Error>> {
475 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
476
477 let subjects: HashSet<StaticTerm> = g.subjects().map(|t| t.unwrap().into_term()).collect();
478 assert_eq!(subjects.len(), 8);
479 assert_contains(&subjects, &*C1);
480 assert_contains(&subjects, &*C2);
481 assert_contains(&subjects, &*P1);
482 assert_contains(&subjects, &*P2);
483 assert_contains(&subjects, &*I1A);
484 assert_contains(&subjects, &*I1B);
485 assert_contains(&subjects, &*I2A);
486 assert_contains(&subjects, &*I2B);
487
488 let g = if $is_gen {
489 $graph_collector(generalized_node_types_triples()).unwrap()
490 } else {
491 $graph_collector(strict_node_types_triples()).unwrap()
492 };
493 let kinds: HashSet<_> = g.subjects().map(|t| t.unwrap().kind()).collect();
494 assert_eq!(kinds.len(), if $is_gen {5} else {2});
495 assert!(kinds.contains(&TermKind::Iri));
496 assert!(kinds.contains(&TermKind::BlankNode));
497 Ok(())
498 }
499
500 #[test]
501 fn predicates() -> Result<(), Box<dyn std::error::Error>> {
502 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
503
504 let predicates: HashSet<StaticTerm> = g.predicates().map(|t| t.unwrap().into_term()).collect();
505 assert_eq!(predicates.len(), 6);
506 assert_contains(&predicates, &rdf::type_);
507 assert_contains(&predicates, &rdfs::subClassOf);
508 assert_contains(&predicates, &rdfs::domain);
509 assert_contains(&predicates, &rdfs::range);
510 assert_contains(&predicates, &*P1);
511 assert_contains(&predicates, &*P2);
512
513 let g = if $is_gen {
514 $graph_collector(generalized_node_types_triples()).unwrap()
515 } else {
516 $graph_collector(strict_node_types_triples()).unwrap()
517 };
518 let kinds: HashSet<_> = g.predicates().map(|t| t.unwrap().kind()).collect();
519 assert_eq!(kinds.len(), if $is_gen {5} else {1});
520 assert!(kinds.contains(&TermKind::Iri));
521 Ok(())
522 }
523
524 #[test]
525 fn objects() -> Result<(), Box<dyn std::error::Error>> {
526 let g: $graph_impl = $graph_collector(some_triples()).unwrap();
527
528 let objects: HashSet<StaticTerm> = g.objects().map(|t| t.unwrap().into_term()).collect();
529 assert_eq!(objects.len(), 7);
530 assert_contains(&objects, &rdf::Property);
531 assert_contains(&objects, &rdfs::Class);
532 assert_contains(&objects, &rdfs::Resource);
533 assert_contains(&objects, &*C1);
534 assert_contains(&objects, &*C2);
535 assert_contains(&objects, &*I2A);
536 assert_contains(&objects, &*I2B);
537
538 let g = if $is_gen {
539 $graph_collector(generalized_node_types_triples()).unwrap()
540 } else {
541 $graph_collector(strict_node_types_triples()).unwrap()
542 };
543 let kinds: HashSet<_> = g.objects().map(|t| t.unwrap().kind()).collect();
544 assert_eq!(kinds.len(), if $is_gen {5} else {3});
545 assert!(kinds.contains(&TermKind::Iri));
546 assert!(kinds.contains(&TermKind::BlankNode));
547 assert!(kinds.contains(&TermKind::Literal));
548 Ok(())
549 }
550
551 #[test]
552 fn iris() -> Result<(), Box<dyn std::error::Error>> {
553 let g = if $is_gen {
554 $graph_collector(generalized_node_types_triples()).unwrap()
555 } else {
556 $graph_collector(strict_node_types_triples()).unwrap()
557 };
558
559 let iris: HashSet<StaticTerm> = g.iris().map(|t| t.unwrap().into_term()).collect();
560 dbg!(&iris);
561 assert_eq!(iris.len(), 3);
562 assert_contains(&iris, &rdf::Property);
563 assert_contains(&iris, &rdf::type_);
564 assert_contains(&iris, &rdf::value);
565 Ok(())
566 }
567
568 #[test]
569 fn bnodes() -> Result<(), Box<dyn std::error::Error>> {
570 let g = if $is_gen {
571 $graph_collector(generalized_node_types_triples()).unwrap()
572 } else {
573 $graph_collector(strict_node_types_triples()).unwrap()
574 };
575
576 let bnodes: HashSet<StaticTerm> = g.blank_nodes().map(|t| t.unwrap().into_term()).collect();
577 assert_eq!(bnodes.len(), 2);
578 assert_contains(&bnodes, &B1);
579 assert_contains(&bnodes, &B2);
580 Ok(())
581 }
582
583 #[test]
584 fn literals() -> Result<(), Box<dyn std::error::Error>> {
585 let g = if $is_gen {
586 $graph_collector(generalized_node_types_triples()).unwrap()
587 } else {
588 $graph_collector(strict_node_types_triples()).unwrap()
589 };
590 dbg!(&g);
591
592 let literals: HashSet<StaticTerm> = g.literals().map(|t| t.unwrap().into_term()).collect();
593 assert_eq!(literals.len(), 3);
594 assert_contains(&literals, &"lit1");
595 assert_contains(&literals, &"lit2");
596 assert_contains(&literals, &("lit2"*EN));
597 Ok(())
598 }
599
600 #[test]
601 fn quoted_triples() -> Result<(), Box<dyn std::error::Error>> {
602 if $is_gen {
603 let g: $graph_impl = $graph_collector(generalized_node_types_triples()).unwrap();
604
605 let triples: HashSet<StaticTerm> = g.quoted_triples().map(|t| t.unwrap().into_term()).collect();
606 assert_eq!(triples.len(), 4);
607 let t1 = StaticTerm::from_triple([
608 V1.as_simple(),
609 B1.as_simple(),
610 "lit1".as_simple(),
611 ]);
612 let t2 = StaticTerm::from_triple([
613 B2.as_simple(),
614 "lit2".as_simple(),
615 V2.as_simple(),
616 ]);
617 let t3 = StaticTerm::from_triple([
618 V2.as_simple(),
619 rdf::value.as_simple(),
620 rdf::type_.as_simple(),
621 ]);
622 let t4 = StaticTerm::from_triple([
623 "lit2"*EN,
624 B1.as_simple(),
625 t3.clone(),
626 ]);
627 assert_contains(&triples, &t1);
628 assert_contains(&triples, &t2);
629 assert_contains(&triples, &t3);
630 assert_contains(&triples, &t4);
631 } else {
632 let g: $graph_impl = $graph_collector(strict_node_types_triples()).unwrap();
633
634 let triples: HashSet<StaticTerm> = g.quoted_triples().map(|t| t.unwrap().into_term()).collect();
635 assert_eq!(triples.len(), 0);
636 }
637 Ok(())
638 }
639
640 #[test]
641 fn variables() -> Result<(), Box<dyn std::error::Error>> {
642 if $is_gen {
643 let g: $graph_impl = $graph_collector(generalized_node_types_triples()).unwrap();
644
645 let variables: HashSet<StaticTerm> = g.variables().map(|t| t.unwrap().into_term()).collect();
646 assert_eq!(variables.len(), 2);
647 assert_contains(&variables, &V1);
648 assert_contains(&variables, &V2);
649 } else {
650 let g: $graph_impl = $graph_collector(strict_node_types_triples()).unwrap();
651
652 let variables: HashSet<StaticTerm> = g.variables().map(|t| t.unwrap().into_term()).collect();
653 assert_eq!(variables.len(), 0);
654 }
655 Ok(())
656 }
657
658 $($mt)*
660 }
661 };
662}
663
664#[macro_export]
684macro_rules! test_immutable_graph_impl {
685 ($graph_impl: ident) => {
686 $crate::test_immutable_graph_impl!(test, $graph_impl);
687 };
688 ($module_name: ident, $graph_impl: ident) => {
689 $crate::test_immutable_graph_impl!($module_name, $graph_impl, true);
690 };
691 ($module_name: ident, $graph_impl: ident, $is_set: expr) => {
692 $crate::test_immutable_graph_impl!($module_name, $graph_impl, $is_set, true);
693 };
694 ($module_name: ident, $graph_impl: ident, $is_set: expr, $is_gen: expr) => {
695 $crate::test_immutable_graph_impl!(
696 $module_name,
697 $graph_impl,
698 $is_set,
699 $is_gen,
700 $graph_impl::from_triple_source
701 );
702 };
703 ($module_name: ident, $graph_impl: ident, $is_set: expr, $is_gen: expr, $graph_collector: path) => {
704 $crate::test_graph_impl!(
706 $module_name,
707 $graph_impl,
708 $is_set,
709 $is_gen,
710 $graph_collector,
711 {}
712 );
713 };
714}