diff --git a/testsuite/oxigraph-tests/sparql-results/manifest.ttl b/testsuite/oxigraph-tests/sparql-results/manifest.ttl index 03e276ec..4e9c6473 100644 --- a/testsuite/oxigraph-tests/sparql-results/manifest.ttl +++ b/testsuite/oxigraph-tests/sparql-results/manifest.ttl @@ -24,7 +24,7 @@ mf:name "Duplicated variables are not allowed" ; mf:action . -:results_xml_duplicated_variables rdf:type ox:NegativeTsvResultsSyntaxTest ; +:results_tsv_duplicated_variables rdf:type ox:NegativeTsvResultsSyntaxTest ; mf:name "Duplicated variables are not allowed" ; mf:action . diff --git a/testsuite/rdf-tests b/testsuite/rdf-tests index 43b0eb90..d2cc355b 160000 --- a/testsuite/rdf-tests +++ b/testsuite/rdf-tests @@ -1 +1 @@ -Subproject commit 43b0eb9078f144c0d1c36f2c751b81922030eb1a +Subproject commit d2cc355bf601d8574116f3ee76ca570925f35ac3 diff --git a/testsuite/src/manifest.rs b/testsuite/src/manifest.rs index 66931881..f7f6b26b 100644 --- a/testsuite/src/manifest.rs +++ b/testsuite/src/manifest.rs @@ -73,261 +73,253 @@ impl Iterator for TestManifest { fn next(&mut self) -> Option> { 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) - { - 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) - { - Some(TermRef::Literal(c)) => Some(c.value().to_string()), - _ => None, - }; - let (action, query, update, data, graph_data, service_data) = match self - .graph - .object_for_subject_predicate(&test_node, mf::ACTION) - { - Some(TermRef::NamedNode(n)) => ( - Some(n.as_str().to_owned()), - None, - None, - None, - vec![], - vec![], - ), - Some(TermRef::BlankNode(n)) => { - 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) { - Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), - _ => None, - }; - let data = match self - .graph - .object_for_subject_predicate(n, qt::DATA) - .or_else(|| self.graph.object_for_subject_predicate(n, ut::DATA)) - { - Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), - _ => None, - }; - let graph_data = self - .graph - .objects_for_subject_predicate(n, qt::GRAPH_DATA) - .chain(self.graph.objects_for_subject_predicate(n, ut::GRAPH_DATA)) - .filter_map(|g| match g { - TermRef::NamedNode(q) => { - Some((q.into_owned(), q.as_str().to_owned())) - } - TermRef::BlankNode(node) => { - if let Some(TermRef::NamedNode(graph)) = - self.graph.object_for_subject_predicate(node, ut::GRAPH) - { - if let Some(TermRef::Literal(name)) = self - .graph - .object_for_subject_predicate(node, rdfs::LABEL) - { - Some(( - NamedNode::new(name.value()).unwrap(), - graph.as_str().to_owned(), - )) - } else { - Some(( - graph.into_owned(), - graph.as_str().to_owned(), - )) - } - } else { - None - } - } - _ => None, - }) - .collect(); - let service_data = self - .graph - .objects_for_subject_predicate(n, qt::SERVICE_DATA) - .filter_map(|g| match g { - TermRef::NamedNode(g) => Some(g.into()), - TermRef::BlankNode(g) => Some(g.into()), - _ => None, - }) - .filter_map(|g: SubjectRef<'_>| { - if let ( - Some(TermRef::NamedNode(endpoint)), - Some(TermRef::NamedNode(data)), - ) = ( - 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(), - )) - } else { - None - } - }) - .collect(); - (None, query, update, data, graph_data, service_data) - } - Some(_) => return Some(Err(anyhow!("invalid action"))), - None => { - return Some(Err(anyhow!("action not found for test {}", test_node))); - } - }; - let (result, result_graph_data) = match self - .graph - .object_for_subject_predicate(&test_node, mf::RESULT) - { - Some(TermRef::NamedNode(n)) => (Some(n.as_str().to_owned()), Vec::new()), - Some(TermRef::BlankNode(n)) => ( - if let Some(TermRef::NamedNode(result)) = - self.graph.object_for_subject_predicate(n, ut::DATA) + if let Some(next) = self.next_test() { + return Some(next); + } + if let Err(e) = self.load_next_manifest()? { + return Some(Err(e)); + } + } + } +} + +impl TestManifest { + fn next_test(&mut self) -> Option> { + let test_node = self.tests_to_do.pop_front()?; + let test_node = match test_node { + Term::NamedNode(n) => n, + _ => { + return Some(Err(anyhow!("Invalid test identifier. Got {}", test_node))); + } + }; + + let name = match self + .graph + .object_for_subject_predicate(&test_node, mf::NAME) + { + 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 if test_node + .as_str() + .starts_with("http://www.w3.org/2001/sw/DataAccess/tests/data-r2") + { + self.next_test() //TODO: hack to ignore invalid tests: https://github.com/w3c/rdf-tests/pull/82 + } else { + 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) + { + Some(TermRef::Literal(c)) => Some(c.value().to_string()), + _ => None, + }; + let (action, query, update, data, graph_data, service_data) = match self + .graph + .object_for_subject_predicate(&test_node, mf::ACTION) + { + Some(TermRef::NamedNode(n)) => ( + Some(n.as_str().to_owned()), + None, + None, + None, + vec![], + vec![], + ), + Some(TermRef::BlankNode(n)) => { + 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) { + Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), + _ => None, + }; + let data = match self + .graph + .object_for_subject_predicate(n, qt::DATA) + .or_else(|| self.graph.object_for_subject_predicate(n, ut::DATA)) + { + Some(TermRef::NamedNode(q)) => Some(q.as_str().to_owned()), + _ => None, + }; + let graph_data = self + .graph + .objects_for_subject_predicate(n, qt::GRAPH_DATA) + .chain(self.graph.objects_for_subject_predicate(n, ut::GRAPH_DATA)) + .filter_map(|g| match g { + TermRef::NamedNode(q) => Some((q.into_owned(), q.as_str().to_owned())), + TermRef::BlankNode(node) => { + if let Some(TermRef::NamedNode(graph)) = + self.graph.object_for_subject_predicate(node, ut::GRAPH) { - Some(result.as_str().to_owned()) + if let Some(TermRef::Literal(name)) = + self.graph.object_for_subject_predicate(node, rdfs::LABEL) + { + Some(( + NamedNode::new(name.value()).unwrap(), + graph.as_str().to_owned(), + )) + } else { + Some((graph.into_owned(), graph.as_str().to_owned())) + } } else { None - }, - self.graph - .objects_for_subject_predicate(n, ut::GRAPH_DATA) - .filter_map(|g| match g { - TermRef::NamedNode(q) => { - Some((q.into_owned(), q.as_str().to_owned())) - } - TermRef::BlankNode(node) => { - if let Some(TermRef::NamedNode(graph)) = - self.graph.object_for_subject_predicate(node, ut::GRAPH) - { - if let Some(TermRef::Literal(name)) = self - .graph - .object_for_subject_predicate(node, rdfs::LABEL) - { - Some(( - NamedNode::new(name.value()).unwrap(), - graph.as_str().to_owned(), - )) - } else { - Some(( - graph.into_owned(), - graph.as_str().to_owned(), - )) - } - } else { - None - } - } - _ => None, - }) - .collect(), - ), - Some(_) => return Some(Err(anyhow!("invalid result"))), - None => (None, Vec::new()), - }; - Some(Ok(Test { - id: test_node, - kind, - name, - comment, - action, - query, - update, - data, - graph_data, - service_data, - result, - result_graph_data, - })) - } - Some(Err(error)) => Some(Err(error)), - None => { - match self.manifests_to_do.pop_front() { - Some(url) => { - self.graph.clear(); - if let Err(error) = load_to_graph(&url, &mut self.graph) { - return Some(Err(error)); } - - for manifest in self - .graph - .subjects_for_predicate_object(rdf::TYPE, mf::MANIFEST) + } + _ => None, + }) + .collect(); + let service_data = self + .graph + .objects_for_subject_predicate(n, qt::SERVICE_DATA) + .filter_map(|g| match g { + TermRef::NamedNode(g) => Some(g.into()), + TermRef::BlankNode(g) => Some(g.into()), + _ => None, + }) + .filter_map(|g: SubjectRef<'_>| { + if let ( + Some(TermRef::NamedNode(endpoint)), + Some(TermRef::NamedNode(data)), + ) = ( + 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())) + } else { + None + } + }) + .collect(); + (None, query, update, data, graph_data, service_data) + } + Some(_) => return Some(Err(anyhow!("invalid action"))), + None => { + return Some(Err(anyhow!("action not found for test {}", test_node))); + } + }; + let (result, result_graph_data) = match self + .graph + .object_for_subject_predicate(&test_node, mf::RESULT) + { + Some(TermRef::NamedNode(n)) => (Some(n.as_str().to_owned()), Vec::new()), + Some(TermRef::BlankNode(n)) => ( + if let Some(TermRef::NamedNode(result)) = + self.graph.object_for_subject_predicate(n, ut::DATA) + { + Some(result.as_str().to_owned()) + } else { + None + }, + self.graph + .objects_for_subject_predicate(n, ut::GRAPH_DATA) + .filter_map(|g| match g { + TermRef::NamedNode(q) => Some((q.into_owned(), q.as_str().to_owned())), + TermRef::BlankNode(node) => { + if let Some(TermRef::NamedNode(graph)) = + self.graph.object_for_subject_predicate(node, ut::GRAPH) { - match self - .graph - .object_for_subject_predicate(manifest, mf::INCLUDE) - { - Some(TermRef::BlankNode(list)) => { - self.manifests_to_do.extend( - 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"))), - None => (), - } - - // New tests - match self - .graph - .object_for_subject_predicate(manifest, mf::ENTRIES) + if let Some(TermRef::Literal(name)) = + self.graph.object_for_subject_predicate(node, rdfs::LABEL) { - Some(TermRef::BlankNode(list)) => { - self.tests_to_do.extend(RdfListIterator::iter( - &self.graph, - list.into(), - )); - } - Some(term) => { - return Some(Err(anyhow!( - "Invalid tests list. Got term {}", - term - ))); - } - None => (), + Some(( + NamedNode::new(name.value()).unwrap(), + graph.as_str().to_owned(), + )) + } else { + Some((graph.into_owned(), graph.as_str().to_owned())) } + } else { + None } - continue; } - None => None, - } + _ => None, + }) + .collect(), + ), + Some(_) => return Some(Err(anyhow!("invalid result"))), + None => (None, Vec::new()), + }; + Some(Ok(Test { + id: test_node, + kind, + name, + comment, + action, + query, + update, + data, + graph_data, + service_data, + result, + result_graph_data, + })) + } + + fn load_next_manifest(&mut self) -> Option> { + let url = self.manifests_to_do.pop_front()?; + self.graph.clear(); + if let Err(error) = load_to_graph(&url, &mut self.graph) { + return Some(Err(error)); + } + + let manifests = self + .graph + .subjects_for_predicate_object(rdf::TYPE, mf::MANIFEST) + .collect::>(); + if manifests.len() != 1 { + return Some(Err(anyhow!( + "The file {} should contain a single manifest", + url + ))); + } + for manifest in manifests { + match self + .graph + .object_for_subject_predicate(manifest, mf::INCLUDE) + { + Some(TermRef::BlankNode(list)) => { + self.manifests_to_do.extend( + 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"))), + None => (), + } + + // New tests + match self + .graph + .object_for_subject_predicate(manifest, mf::ENTRIES) + { + Some(TermRef::BlankNode(list)) => { + self.tests_to_do + .extend(RdfListIterator::iter(&self.graph, list.into())); + } + Some(term) => { + return Some(Err(anyhow!("Invalid tests list. Got term {}", term))); } - }; + None => (), + } } + Some(Ok(())) } }