|
|
|
@ -3,6 +3,7 @@ use crate::vocab::*; |
|
|
|
|
use anyhow::{anyhow, Result}; |
|
|
|
|
use oxigraph::model::vocab::*; |
|
|
|
|
use oxigraph::model::*; |
|
|
|
|
use std::collections::VecDeque; |
|
|
|
|
use std::fmt; |
|
|
|
|
|
|
|
|
|
pub struct Test { |
|
|
|
@ -50,15 +51,15 @@ impl fmt::Display for Test { |
|
|
|
|
|
|
|
|
|
pub struct TestManifest { |
|
|
|
|
graph: Graph, |
|
|
|
|
tests_to_do: Vec<Term>, |
|
|
|
|
manifests_to_do: Vec<String>, |
|
|
|
|
tests_to_do: VecDeque<Term>, |
|
|
|
|
manifests_to_do: VecDeque<String>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl TestManifest { |
|
|
|
|
pub fn new<S: ToString>(manifest_urls: impl IntoIterator<Item = S>) -> Self { |
|
|
|
|
Self { |
|
|
|
|
graph: Graph::new(), |
|
|
|
|
tests_to_do: Vec::new(), |
|
|
|
|
tests_to_do: VecDeque::new(), |
|
|
|
|
manifests_to_do: manifest_urls |
|
|
|
|
.into_iter() |
|
|
|
|
.map(|url| url.to_string()) |
|
|
|
@ -71,15 +72,19 @@ impl Iterator for TestManifest { |
|
|
|
|
type Item = Result<Test>; |
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Result<Test>> { |
|
|
|
|
match self.tests_to_do.pop() { |
|
|
|
|
Some(Term::NamedNode(test_node)) => { |
|
|
|
|
let kind = match self |
|
|
|
|
.graph |
|
|
|
|
.object_for_subject_predicate(&test_node, rdf::TYPE) |
|
|
|
|
{ |
|
|
|
|
Some(TermRef::NamedNode(c)) => c.into_owned(), |
|
|
|
|
_ => return self.next(), //We ignore the test
|
|
|
|
|
}; |
|
|
|
|
loop { |
|
|
|
|
return match self.tests_to_do.pop_front().map(|term| match term { |
|
|
|
|
Term::NamedNode(n) => Ok(n), |
|
|
|
|
Term::BlankNode(n) => Ok(NamedNode::new(format!( |
|
|
|
|
"http://oxigraph.org/.well-known/genid/{}", |
|
|
|
|
n.as_str() |
|
|
|
|
))?), |
|
|
|
|
_ => Err(anyhow!("Invalid test identifier. Got {}", term)), |
|
|
|
|
}) { |
|
|
|
|
Some(Ok(test_node)) => { |
|
|
|
|
if self.graph.triples_for_subject(&test_node).next().is_none() { |
|
|
|
|
continue; // This test does not exists
|
|
|
|
|
} |
|
|
|
|
let name = match self |
|
|
|
|
.graph |
|
|
|
|
.object_for_subject_predicate(&test_node, mf::NAME) |
|
|
|
@ -87,6 +92,19 @@ impl Iterator for TestManifest { |
|
|
|
|
Some(TermRef::Literal(c)) => Some(c.value().to_string()), |
|
|
|
|
_ => None, |
|
|
|
|
}; |
|
|
|
|
let kind = match self |
|
|
|
|
.graph |
|
|
|
|
.object_for_subject_predicate(&test_node, rdf::TYPE) |
|
|
|
|
{ |
|
|
|
|
Some(TermRef::NamedNode(c)) => c.into_owned(), |
|
|
|
|
_ => { |
|
|
|
|
return Some(Err(anyhow!( |
|
|
|
|
"The test {} named {} has no rdf:type", |
|
|
|
|
test_node, |
|
|
|
|
name.as_deref().unwrap_or("") |
|
|
|
|
))) |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
let comment = match self |
|
|
|
|
.graph |
|
|
|
|
.object_for_subject_predicate(&test_node, rdfs::COMMENT) |
|
|
|
@ -107,11 +125,13 @@ impl Iterator for TestManifest { |
|
|
|
|
vec![], |
|
|
|
|
), |
|
|
|
|
Some(TermRef::BlankNode(n)) => { |
|
|
|
|
let query = match self.graph.object_for_subject_predicate(n, qt::QUERY) { |
|
|
|
|
let query = match self.graph.object_for_subject_predicate(n, qt::QUERY) |
|
|
|
|
{ |
|
|
|
|
Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), |
|
|
|
|
_ => None, |
|
|
|
|
}; |
|
|
|
|
let update = match self.graph.object_for_subject_predicate(n, ut::REQUEST) { |
|
|
|
|
let update = |
|
|
|
|
match self.graph.object_for_subject_predicate(n, ut::REQUEST) { |
|
|
|
|
Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), |
|
|
|
|
_ => None, |
|
|
|
|
}; |
|
|
|
@ -144,7 +164,10 @@ impl Iterator for TestManifest { |
|
|
|
|
graph.as_str().to_owned(), |
|
|
|
|
)) |
|
|
|
|
} else { |
|
|
|
|
Some((graph.into_owned(), graph.as_str().to_owned())) |
|
|
|
|
Some(( |
|
|
|
|
graph.into_owned(), |
|
|
|
|
graph.as_str().to_owned(), |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
@ -169,7 +192,10 @@ impl Iterator for TestManifest { |
|
|
|
|
self.graph.object_for_subject_predicate(g, qt::ENDPOINT), |
|
|
|
|
self.graph.object_for_subject_predicate(g, qt::DATA), |
|
|
|
|
) { |
|
|
|
|
Some((endpoint.as_str().to_owned(), data.as_str().to_owned())) |
|
|
|
|
Some(( |
|
|
|
|
endpoint.as_str().to_owned(), |
|
|
|
|
data.as_str().to_owned(), |
|
|
|
|
)) |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
|
} |
|
|
|
@ -214,7 +240,10 @@ impl Iterator for TestManifest { |
|
|
|
|
graph.as_str().to_owned(), |
|
|
|
|
)) |
|
|
|
|
} else { |
|
|
|
|
Some((graph.into_owned(), graph.as_str().to_owned())) |
|
|
|
|
Some(( |
|
|
|
|
graph.into_owned(), |
|
|
|
|
graph.as_str().to_owned(), |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
@ -242,9 +271,9 @@ impl Iterator for TestManifest { |
|
|
|
|
result_graph_data, |
|
|
|
|
})) |
|
|
|
|
} |
|
|
|
|
Some(_) => self.next(), |
|
|
|
|
Some(Err(error)) => Some(Err(error)), |
|
|
|
|
None => { |
|
|
|
|
match self.manifests_to_do.pop() { |
|
|
|
|
match self.manifests_to_do.pop_front() { |
|
|
|
|
Some(url) => { |
|
|
|
|
self.graph.clear(); |
|
|
|
|
if let Err(error) = load_to_graph(&url, &mut self.graph) { |
|
|
|
@ -261,12 +290,11 @@ impl Iterator for TestManifest { |
|
|
|
|
{ |
|
|
|
|
Some(TermRef::BlankNode(list)) => { |
|
|
|
|
self.manifests_to_do.extend( |
|
|
|
|
RdfListIterator::iter(&self.graph, list.into()).filter_map( |
|
|
|
|
|m| match m { |
|
|
|
|
RdfListIterator::iter(&self.graph, list.into()) |
|
|
|
|
.filter_map(|m| match m { |
|
|
|
|
Term::NamedNode(nm) => Some(nm.into_string()), |
|
|
|
|
_ => None, |
|
|
|
|
}, |
|
|
|
|
), |
|
|
|
|
}), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
Some(_) => return Some(Err(anyhow!("invalid tests list"))), |
|
|
|
@ -279,8 +307,10 @@ impl Iterator for TestManifest { |
|
|
|
|
.object_for_subject_predicate(manifest, mf::ENTRIES) |
|
|
|
|
{ |
|
|
|
|
Some(TermRef::BlankNode(list)) => { |
|
|
|
|
self.tests_to_do |
|
|
|
|
.extend(RdfListIterator::iter(&self.graph, list.into())); |
|
|
|
|
self.tests_to_do.extend(RdfListIterator::iter( |
|
|
|
|
&self.graph, |
|
|
|
|
list.into(), |
|
|
|
|
)); |
|
|
|
|
} |
|
|
|
|
Some(term) => { |
|
|
|
|
return Some(Err(anyhow!( |
|
|
|
@ -291,11 +321,12 @@ impl Iterator for TestManifest { |
|
|
|
|
None => (), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
None => return None, |
|
|
|
|
None => None, |
|
|
|
|
} |
|
|
|
|
self.next() |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|