Makes RDF test suite local

pull/10/head
Tpt 6 years ago
parent 7efd962374
commit ebb74d1560
  1. 3
      .gitmodules
  2. 1
      lib/tests/rdf-tests
  3. 112
      lib/tests/rdf_test_cases.rs

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "lib/tests/rdf-tests"]
path = lib/tests/rdf-tests
url = https://github.com/w3c/rdf-tests.git

@ -0,0 +1 @@
Subproject commit 280e9de3aaefa6b292a151bd455204d49a0c09db

@ -1,7 +1,5 @@
///! Integration tests based on [RDF 1.1 Test Cases](https://www.w3.org/TR/rdf11-testcases/) ///! Integration tests based on [RDF 1.1 Test Cases](https://www.w3.org/TR/rdf11-testcases/)
use failure::format_err; use failure::format_err;
use reqwest::Client;
use reqwest::Response;
use rudf::model::vocab::rdf; use rudf::model::vocab::rdf;
use rudf::model::vocab::rdfs; use rudf::model::vocab::rdfs;
use rudf::model::*; use rudf::model::*;
@ -11,15 +9,15 @@ use rudf::rio::xml::read_rdf_xml;
use rudf::store::isomorphism::GraphIsomorphism; use rudf::store::isomorphism::GraphIsomorphism;
use rudf::store::MemoryGraph; use rudf::store::MemoryGraph;
use rudf::Result; use rudf::Result;
use std::error::Error;
use std::fmt; use std::fmt;
use std::io::BufReader; use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use url::Url; use url::Url;
#[test] #[test]
fn turtle_w3c_testsuite() { fn turtle_w3c_testsuite() {
let manifest_url = Url::parse("http://www.w3.org/2013/TurtleTests/manifest.ttl").unwrap(); let manifest_url = Url::parse("http://www.w3.org/2013/TurtleTests/manifest.ttl").unwrap();
let client = RDFClient::default();
//TODO: make blacklist pass //TODO: make blacklist pass
let test_blacklist = vec![ let test_blacklist = vec![
//UTF-8 broken surrogates in BNode ids //UTF-8 broken surrogates in BNode ids
@ -43,26 +41,31 @@ fn turtle_w3c_testsuite() {
.join("#localName_with_nfc_PN_CHARS_BASE_character_boundaries") .join("#localName_with_nfc_PN_CHARS_BASE_character_boundaries")
.unwrap(), .unwrap(),
), ),
NamedNode::new(manifest_url.join("#IRI-resolution-01").unwrap()),
NamedNode::new(manifest_url.join("#IRI-resolution-02").unwrap()),
NamedNode::new(manifest_url.join("#IRI-resolution-07").unwrap()),
NamedNode::new(manifest_url.join("#turtle-subm-01").unwrap()),
NamedNode::new(manifest_url.join("#turtle-subm-27").unwrap()),
]; ];
for test_result in TestManifest::new(&client, manifest_url) { for test_result in TestManifest::new(manifest_url) {
let test = test_result.unwrap(); let test = test_result.unwrap();
if test_blacklist.contains(&test.id) { if test_blacklist.contains(&test.id) {
continue; continue;
} }
if test.kind == "TestTurtlePositiveSyntax" { if test.kind == "TestTurtlePositiveSyntax" {
if let Err(error) = client.load_turtle(test.action.clone()) { if let Err(error) = load_turtle(test.action.clone()) {
assert!(false, "Failure on {} with error: {}", test, error) assert!(false, "Failure on {} with error: {}", test, error)
} }
} else if test.kind == "TestTurtleNegativeSyntax" { } else if test.kind == "TestTurtleNegativeSyntax" {
assert!( assert!(
client.load_turtle(test.action.clone()).is_err(), load_turtle(test.action.clone()).is_err(),
"Failure on {}", "Failure on {}",
test test
); );
} else if test.kind == "TestTurtleEval" { } else if test.kind == "TestTurtleEval" {
match client.load_turtle(test.action.clone()) { match load_turtle(test.action.clone()) {
Ok(action_graph) => match client.load_turtle(test.result.clone().unwrap()) { Ok(action_graph) => match load_turtle(test.result.clone().unwrap()) {
Ok(result_graph) => assert!( Ok(result_graph) => assert!(
action_graph.is_isomorphic(&result_graph).unwrap(), action_graph.is_isomorphic(&result_graph).unwrap(),
"Failure on {}. Expected file:\n{}\nParsed file:\n{}\n", "Failure on {}. Expected file:\n{}\nParsed file:\n{}\n",
@ -81,11 +84,11 @@ fn turtle_w3c_testsuite() {
Err(error) => assert!(false, "Failure to parse {} with error: {}", test, error), Err(error) => assert!(false, "Failure to parse {} with error: {}", test, error),
} }
} else if test.kind == "TestTurtleNegativeEval" { } else if test.kind == "TestTurtleNegativeEval" {
let action_graph = client.load_turtle(test.action.clone()); let action_graph = load_turtle(test.action.clone());
let result_graph = test let result_graph = test
.result .result
.clone() .clone()
.map(|r| client.load_turtle(r)) .map(|r| load_turtle(r))
.unwrap_or_else(|| Ok(MemoryGraph::default())); .unwrap_or_else(|| Ok(MemoryGraph::default()));
assert!( assert!(
action_graph.is_err() action_graph.is_err()
@ -104,18 +107,17 @@ fn turtle_w3c_testsuite() {
#[test] #[test]
fn ntriples_w3c_testsuite() { fn ntriples_w3c_testsuite() {
let client = RDFClient::default();
let manifest_url = Url::parse("http://www.w3.org/2013/N-TriplesTests/manifest.ttl").unwrap(); let manifest_url = Url::parse("http://www.w3.org/2013/N-TriplesTests/manifest.ttl").unwrap();
for test_result in TestManifest::new(&client, manifest_url) { for test_result in TestManifest::new(manifest_url) {
let test = test_result.unwrap(); let test = test_result.unwrap();
if test.kind == "TestNTriplesPositiveSyntax" { if test.kind == "TestNTriplesPositiveSyntax" {
if let Err(error) = client.load_ntriples(test.action.clone()) { if let Err(error) = load_ntriples(test.action.clone()) {
assert!(false, "Failure on {} with error: {}", test, error) assert!(false, "Failure on {} with error: {}", test, error)
} }
} else if test.kind == "TestNTriplesNegativeSyntax" { } else if test.kind == "TestNTriplesNegativeSyntax" {
assert!( assert!(
client.load_ntriples(test.action.clone()).is_err(), load_ntriples(test.action.clone()).is_err(),
"Failure on {}", "Failure on {}",
test test
); );
@ -128,7 +130,6 @@ fn ntriples_w3c_testsuite() {
#[test] #[test]
fn rdf_xml_w3c_testsuite() -> Result<()> { fn rdf_xml_w3c_testsuite() -> Result<()> {
let manifest_url = Url::parse("http://www.w3.org/2013/RDFXMLTests/manifest.ttl")?; let manifest_url = Url::parse("http://www.w3.org/2013/RDFXMLTests/manifest.ttl")?;
let client = RDFClient::default();
//TODO: make blacklist pass //TODO: make blacklist pass
let test_blacklist = vec![ let test_blacklist = vec![
NamedNode::new(manifest_url.join("#xml-canon-test001")?), NamedNode::new(manifest_url.join("#xml-canon-test001")?),
@ -136,7 +137,7 @@ fn rdf_xml_w3c_testsuite() -> Result<()> {
NamedNode::new(manifest_url.join("#rdf-containers-syntax-vs-schema-test004")?), NamedNode::new(manifest_url.join("#rdf-containers-syntax-vs-schema-test004")?),
]; ];
for test_result in TestManifest::new(&client, manifest_url) { for test_result in TestManifest::new(manifest_url) {
let test = test_result?; let test = test_result?;
if test_blacklist.contains(&test.id) { if test_blacklist.contains(&test.id) {
continue; continue;
@ -144,13 +145,13 @@ fn rdf_xml_w3c_testsuite() -> Result<()> {
if test.kind == "TestXMLNegativeSyntax" { if test.kind == "TestXMLNegativeSyntax" {
/*TODO assert!( /*TODO assert!(
client.load_rdf_xml(test.action.clone()).is_err(), load_rdf_xml(test.action.clone()).is_err(),
"Failure on {}", "Failure on {}",
test test
);*/ );*/
} else if test.kind == "TestXMLEval" { } else if test.kind == "TestXMLEval" {
match client.load_rdf_xml(test.action.clone()) { match load_rdf_xml(test.action.clone()) {
Ok(action_graph) => match client.load_ntriples(test.result.clone().unwrap()) { Ok(action_graph) => match load_ntriples(test.result.clone().unwrap()) {
Ok(result_graph) => assert!( Ok(result_graph) => assert!(
action_graph.is_isomorphic(&result_graph)?, action_graph.is_isomorphic(&result_graph)?,
"Failure on {}. Expected file:\n{}\nParsed file:\n{}\n", "Failure on {}. Expected file:\n{}\nParsed file:\n{}\n",
@ -175,43 +176,42 @@ fn rdf_xml_w3c_testsuite() -> Result<()> {
Ok(()) Ok(())
} }
pub struct RDFClient { fn load_turtle(url: Url) -> Result<MemoryGraph> {
client: Client, Ok(read_turtle(read_file(&url)?, Some(url))?.collect())
} }
impl Default for RDFClient { fn load_ntriples(url: Url) -> Result<MemoryGraph> {
fn default() -> Self { read_ntriples(read_file(&url)?).collect()
Self {
client: Client::new(),
}
}
} }
impl RDFClient { fn load_rdf_xml(url: Url) -> Result<MemoryGraph> {
pub fn load_turtle(&self, url: Url) -> Result<MemoryGraph> { read_rdf_xml(read_file(&url)?, Some(url)).collect()
Ok(read_turtle(self.get(&url)?, Some(url))?.collect()) }
}
pub fn load_ntriples(&self, url: Url) -> Result<MemoryGraph> { fn to_relative_path(url: &Url) -> Result<String> {
read_ntriples(self.get(&url)?).collect() let url = url.as_str();
if url.starts_with("http://www.w3.org/2013/N-TriplesTests") {
Ok(url.replace(
"http://www.w3.org/2013/N-TriplesTests",
"rdf-tests/ntriples/",
))
} else if url.starts_with("http://www.w3.org/2013/TurtleTests/") {
Ok(url.replace("http://www.w3.org/2013/TurtleTests/", "rdf-tests/turtle/"))
} else if url.starts_with("http://www.w3.org/2013/RDFXMLTests/") {
Ok(url.replace("http://www.w3.org/2013/RDFXMLTests/", "rdf-tests/rdf-xml/"))
} else {
Err(format_err!("Not supported url for file: {}", url))
} }
}
pub fn load_rdf_xml(&self, url: Url) -> Result<MemoryGraph> { fn read_file(url: &Url) -> Result<impl BufRead> {
read_rdf_xml(BufReader::new(self.get(&url)?), Some(url)).collect() let mut base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
} base_path.push("tests");
base_path.push(to_relative_path(url)?);
fn get(&self, url: &Url) -> Result<Response> { Ok(BufReader::new(File::open(&base_path).map_err(|e| {
match self.client.get(url.clone()).send() { format_err!("Opening file {} failed with {}", base_path.display(), e)
Ok(response) => Ok(response), })?))
Err(error) => {
if error.description() == "parsed HTTP message from remote is incomplete" {
self.get(url)
} else {
Err(format_err!("HTTP request error: {}", error.description()))
}
}
}
}
} }
pub struct Test { pub struct Test {
@ -237,17 +237,15 @@ impl fmt::Display for Test {
} }
} }
pub struct TestManifest<'a> { pub struct TestManifest {
client: &'a RDFClient,
graph: MemoryGraph, graph: MemoryGraph,
tests_to_do: Vec<Term>, tests_to_do: Vec<Term>,
manifests_to_do: Vec<Url>, manifests_to_do: Vec<Url>,
} }
impl<'a> TestManifest<'a> { impl TestManifest {
pub fn new(client: &'a RDFClient, url: Url) -> TestManifest<'a> { pub fn new(url: Url) -> TestManifest {
Self { Self {
client,
graph: MemoryGraph::default(), graph: MemoryGraph::default(),
tests_to_do: Vec::default(), tests_to_do: Vec::default(),
manifests_to_do: vec![url], manifests_to_do: vec![url],
@ -279,7 +277,7 @@ pub mod mf {
} }
} }
impl<'a> Iterator for TestManifest<'a> { impl Iterator for TestManifest {
type Item = Result<Test>; type Item = Result<Test>;
fn next(&mut self) -> Option<Result<Test>> { fn next(&mut self) -> Option<Result<Test>> {
@ -345,7 +343,7 @@ impl<'a> Iterator for TestManifest<'a> {
match self.manifests_to_do.pop() { match self.manifests_to_do.pop() {
Some(url) => { Some(url) => {
let manifest = NamedOrBlankNode::from(NamedNode::new(url.clone())); let manifest = NamedOrBlankNode::from(NamedNode::new(url.clone()));
match self.client.load_turtle(url) { match load_turtle(url) {
Ok(g) => g Ok(g) => g
.iter() .iter()
.unwrap() .unwrap()

Loading…
Cancel
Save