|
|
@ -1,7 +1,7 @@ |
|
|
|
use crate::evaluator::TestEvaluator; |
|
|
|
use crate::evaluator::TestEvaluator; |
|
|
|
use crate::files::*; |
|
|
|
use crate::files::*; |
|
|
|
use crate::manifest::*; |
|
|
|
use crate::manifest::*; |
|
|
|
use crate::report::dataset_diff; |
|
|
|
use crate::report::{dataset_diff, format_diff}; |
|
|
|
use crate::vocab::*; |
|
|
|
use crate::vocab::*; |
|
|
|
use anyhow::{anyhow, bail, Result}; |
|
|
|
use anyhow::{anyhow, bail, Result}; |
|
|
|
use oxigraph::model::vocab::*; |
|
|
|
use oxigraph::model::vocab::*; |
|
|
@ -9,10 +9,10 @@ use oxigraph::model::*; |
|
|
|
use oxigraph::sparql::*; |
|
|
|
use oxigraph::sparql::*; |
|
|
|
use oxigraph::store::Store; |
|
|
|
use oxigraph::store::Store; |
|
|
|
use std::collections::HashMap; |
|
|
|
use std::collections::HashMap; |
|
|
|
use std::io::Cursor; |
|
|
|
use std::fmt::Write; |
|
|
|
|
|
|
|
use std::io::{self, Cursor}; |
|
|
|
use std::str::FromStr; |
|
|
|
use std::str::FromStr; |
|
|
|
use std::sync::Arc; |
|
|
|
use std::sync::Arc; |
|
|
|
use std::{fmt, io}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn register_sparql_tests(evaluator: &mut TestEvaluator) { |
|
|
|
pub fn register_sparql_tests(evaluator: &mut TestEvaluator) { |
|
|
|
evaluator.register( |
|
|
|
evaluator.register( |
|
|
@ -206,7 +206,8 @@ fn evaluate_evaluation_test(test: &Test) -> Result<()> { |
|
|
|
|
|
|
|
|
|
|
|
if !are_query_results_isomorphic(&expected_results, &actual_results) { |
|
|
|
if !are_query_results_isomorphic(&expected_results, &actual_results) { |
|
|
|
bail!( |
|
|
|
bail!( |
|
|
|
"Failure on {test}.\nExpected file:\n{expected_results}\nOutput file:\n{actual_results}\nParsed query:\n{}\nData:\n{store}\n", |
|
|
|
"Failure on {test}.\n{}\nParsed query:\n{}\nData:\n{store}\n", |
|
|
|
|
|
|
|
results_diff(expected_results, actual_results), |
|
|
|
Query::parse(&read_file_to_string(query_file)?, Some(query_file)).unwrap() |
|
|
|
Query::parse(&read_file_to_string(query_file)?, Some(query_file)).unwrap() |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
@ -496,33 +497,6 @@ enum StaticQueryResults { |
|
|
|
Boolean(bool), |
|
|
|
Boolean(bool), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for StaticQueryResults { |
|
|
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
|
|
|
|
|
|
match self { |
|
|
|
|
|
|
|
StaticQueryResults::Graph(g) => g.fmt(f), |
|
|
|
|
|
|
|
StaticQueryResults::Solutions { |
|
|
|
|
|
|
|
variables, |
|
|
|
|
|
|
|
solutions, |
|
|
|
|
|
|
|
.. |
|
|
|
|
|
|
|
} => { |
|
|
|
|
|
|
|
write!(f, "Variables:")?; |
|
|
|
|
|
|
|
for v in variables { |
|
|
|
|
|
|
|
write!(f, " {v}")?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for solution in solutions { |
|
|
|
|
|
|
|
write!(f, "\n{{")?; |
|
|
|
|
|
|
|
for (k, v) in solution { |
|
|
|
|
|
|
|
write!(f, "{k} = {v} ")?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
write!(f, "}}")?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Boolean(b) => b.fmt(f), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl StaticQueryResults { |
|
|
|
impl StaticQueryResults { |
|
|
|
fn from_query_results(results: QueryResults, with_order: bool) -> Result<StaticQueryResults> { |
|
|
|
fn from_query_results(results: QueryResults, with_order: bool) -> Result<StaticQueryResults> { |
|
|
|
Self::from_graph(to_graph(results, with_order)?) |
|
|
|
Self::from_graph(to_graph(results, with_order)?) |
|
|
@ -621,3 +595,108 @@ impl StaticQueryResults { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn results_diff(expected: StaticQueryResults, actual: StaticQueryResults) -> String { |
|
|
|
|
|
|
|
match expected { |
|
|
|
|
|
|
|
StaticQueryResults::Solutions { |
|
|
|
|
|
|
|
variables: mut expected_variables, |
|
|
|
|
|
|
|
solutions: expected_solutions, |
|
|
|
|
|
|
|
ordered, |
|
|
|
|
|
|
|
} => match actual { |
|
|
|
|
|
|
|
StaticQueryResults::Solutions { |
|
|
|
|
|
|
|
variables: mut actual_variables, |
|
|
|
|
|
|
|
solutions: actual_solutions, |
|
|
|
|
|
|
|
.. |
|
|
|
|
|
|
|
} => { |
|
|
|
|
|
|
|
let mut out = String::new(); |
|
|
|
|
|
|
|
expected_variables.sort_unstable(); |
|
|
|
|
|
|
|
actual_variables.sort_unstable(); |
|
|
|
|
|
|
|
if expected_variables != actual_variables { |
|
|
|
|
|
|
|
write!( |
|
|
|
|
|
|
|
&mut out, |
|
|
|
|
|
|
|
"Variables diff:\n{}", |
|
|
|
|
|
|
|
format_diff( |
|
|
|
|
|
|
|
&expected_variables |
|
|
|
|
|
|
|
.iter() |
|
|
|
|
|
|
|
.map(|v| v.to_string()) |
|
|
|
|
|
|
|
.collect::<Vec<_>>() |
|
|
|
|
|
|
|
.join("\n"), |
|
|
|
|
|
|
|
&actual_variables |
|
|
|
|
|
|
|
.iter() |
|
|
|
|
|
|
|
.map(|v| v.to_string()) |
|
|
|
|
|
|
|
.collect::<Vec<_>>() |
|
|
|
|
|
|
|
.join("\n"), |
|
|
|
|
|
|
|
"variables", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
write!( |
|
|
|
|
|
|
|
&mut out, |
|
|
|
|
|
|
|
"Solutions diff:\n{}", |
|
|
|
|
|
|
|
format_diff( |
|
|
|
|
|
|
|
&solutions_to_string(expected_solutions, ordered), |
|
|
|
|
|
|
|
&solutions_to_string(actual_solutions, ordered), |
|
|
|
|
|
|
|
"solutions", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
out |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Boolean(actual) => { |
|
|
|
|
|
|
|
format!("Expecting solutions but found the boolean {actual}") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Graph(actual) => { |
|
|
|
|
|
|
|
format!("Expecting solutions but found the graph:\n{actual}") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
StaticQueryResults::Graph(expected) => match actual { |
|
|
|
|
|
|
|
StaticQueryResults::Solutions { .. } => "Expecting a graph but found solutions".into(), |
|
|
|
|
|
|
|
StaticQueryResults::Boolean(actual) => { |
|
|
|
|
|
|
|
format!("Expecting a graph but found the boolean {actual}") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Graph(actual) => { |
|
|
|
|
|
|
|
let expected = expected |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(|t| t.in_graph(GraphNameRef::DefaultGraph)) |
|
|
|
|
|
|
|
.collect(); |
|
|
|
|
|
|
|
let actual = actual |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(|t| t.in_graph(GraphNameRef::DefaultGraph)) |
|
|
|
|
|
|
|
.collect(); |
|
|
|
|
|
|
|
dataset_diff(&expected, &actual) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
StaticQueryResults::Boolean(expected) => match actual { |
|
|
|
|
|
|
|
StaticQueryResults::Solutions { .. } => { |
|
|
|
|
|
|
|
"Expecting a boolean but found solutions".into() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Boolean(actual) => { |
|
|
|
|
|
|
|
format!("Expecting {expected} but found {actual}") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
StaticQueryResults::Graph(actual) => { |
|
|
|
|
|
|
|
format!("Expecting solutions but found the graph:\n{actual}") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn solutions_to_string(solutions: Vec<Vec<(Variable, Term)>>, ordered: bool) -> String { |
|
|
|
|
|
|
|
let mut lines = solutions |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(|mut s| { |
|
|
|
|
|
|
|
let mut out = String::new(); |
|
|
|
|
|
|
|
write!(&mut out, "{{").unwrap(); |
|
|
|
|
|
|
|
s.sort_unstable_by(|(v1, _), (v2, _)| v1.cmp(v2)); |
|
|
|
|
|
|
|
for (variable, value) in s { |
|
|
|
|
|
|
|
write!(&mut out, "{variable} = {value} ").unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
write!(&mut out, "}}").unwrap(); |
|
|
|
|
|
|
|
out |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
|
|
|
if !ordered { |
|
|
|
|
|
|
|
lines.sort_unstable(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
lines.join("\n") |
|
|
|
|
|
|
|
} |
|
|
|