Fork of https://github.com/oxigraph/oxigraph.git for the purpose of NextGraph project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
oxigraph/lib/tests/service_test_cases.rs

303 lines
8.6 KiB

5 years ago
use failure::format_err;
5 years ago
use rudf::model::*;
use rudf::sparql::{
BindingsIterator, GraphPattern, PreparedQuery, QueryOptions, QueryResult, ServiceHandler,
};
use rudf::{GraphSyntax, MemoryRepository, Repository, RepositoryConnection, Result};
5 years ago
use std::io::BufRead;
5 years ago
#[test]
fn simple_service_test() {
5 years ago
struct TestServiceHandler;
impl ServiceHandler for TestServiceHandler {
fn handle<'a>(
&'a self,
_named_node: &NamedNode,
5 years ago
) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
fn pattern_handler<'a>(graph_pattern: GraphPattern) -> Result<BindingsIterator<'a>> {
let triples =
b"<http://example.com/s> <http://example.com/p> <http://example.com/o> ."
.as_ref();
do_pattern(triples, graph_pattern, QueryOptions::default())
};
Some(pattern_handler)
}
5 years ago
}
5 years ago
let query = r#"
5 years ago
SELECT ?s ?p ?o
WHERE
{
SERVICE <http://service1.org>
{ ?s ?p ?o
}
}
5 years ago
"#
.to_string();
let options = QueryOptions::default().with_service_handler(Box::new(TestServiceHandler));
let results = do_query(b"".as_ref(), query, options).unwrap();
let collected = results
.into_values_iter()
.map(move |b| b.unwrap())
.collect::<Vec<_>>();
let solution = vec![vec![
Some(ex(String::from("s"))),
Some(ex(String::from("p"))),
Some(ex(String::from("o"))),
]];
assert_eq!(collected, solution);
5 years ago
}
5 years ago
#[test]
fn two_service_test() {
5 years ago
#[derive(Clone, Copy)]
struct TwoServiceTest;
impl ServiceHandler for TwoServiceTest {
fn handle<'a>(
&'a self,
named_node: &NamedNode,
5 years ago
) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
let service1 = NamedNode::parse("http://service1.org").unwrap();
let service2 = NamedNode::parse("http://service2.org").unwrap();
if named_node == &service1 {
5 years ago
Some(TwoServiceTest::handle_service1)
} else if named_node == &service2 {
5 years ago
Some(TwoServiceTest::handle_service2)
} else {
None
}
}
}
5 years ago
5 years ago
impl TwoServiceTest {
fn handle_service1<'a>(graph_pattern: GraphPattern) -> Result<BindingsIterator<'a>> {
let triples = br#"
5 years ago
<http://example.com/bob> <http://xmlns.com/foaf/0.1/name> "Bob" .
<http://example.com/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
5 years ago
"#
.as_ref();
do_pattern(triples, graph_pattern, QueryOptions::default())
}
5 years ago
5 years ago
fn handle_service2<'a>(graph_pattern: GraphPattern) -> Result<BindingsIterator<'a>> {
let triples = br#"
5 years ago
<http://example.com/bob> <http://xmlns.com/foaf/0.1/mbox> <mailto:bob@example.com> .
<http://example.com/alice> <http://xmlns.com/foaf/0.1/mbox> <mailto:alice@example.com> .
5 years ago
"#
.as_ref();
do_pattern(triples, graph_pattern, QueryOptions::default())
}
5 years ago
}
5 years ago
let query = r#"
5 years ago
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE
{
SERVICE <http://service1.org>
{ ?s foaf:name ?name
}
SERVICE <http://service2.org>
{ ?s foaf:mbox ?mbox
}
}
ORDER BY ?name
5 years ago
"#
.to_string();
let options = QueryOptions::default().with_service_handler(Box::new(TwoServiceTest));
let results = do_query(b"".as_ref(), query, options).unwrap();
let collected = results
.into_values_iter()
.map(move |b| b.unwrap())
.collect::<Vec<_>>();
let solution = vec![
vec![
Some(literal("Alice".to_string())),
Some(mailto("alice@example.com".to_string())),
],
vec![
Some(literal("Bob".to_string())),
Some(mailto("bob@example.com".to_string())),
],
5 years ago
];
5 years ago
assert_eq!(collected, solution);
5 years ago
}
5 years ago
#[test]
5 years ago
fn silent_service_empty_set_test() {
5 years ago
#[derive(Clone, Copy)]
struct ServiceTest;
impl ServiceHandler for ServiceTest {
fn handle<'a>(
&'a self,
_named_node: &NamedNode,
5 years ago
) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
Some(ServiceTest::handle_service)
}
}
5 years ago
5 years ago
impl ServiceTest {
fn handle_service<'a>(_graph_pattern: GraphPattern) -> Result<BindingsIterator<'a>> {
Err(format_err!("This is supposed to fail"))
}
5 years ago
}
5 years ago
let query = r#"
5 years ago
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE
{
5 years ago
SERVICE SILENT <http://service1.org>
5 years ago
{ ?s foaf:name ?name
}
5 years ago
}
ORDER BY ?name
5 years ago
"#
.to_string();
let triples = b"".as_ref();
let options = QueryOptions::default().with_service_handler(Box::new(ServiceTest));
let results = do_query(triples, query, options).unwrap();
let collected = results
.into_values_iter()
.map(move |b| b.unwrap())
.collect::<Vec<_>>();
println!("Collected: {:?}", collected);
assert_eq!(collected.len(), 0);
5 years ago
}
5 years ago
5 years ago
#[test]
fn non_silent_service_test() {
5 years ago
#[derive(Clone, Copy)]
struct ServiceTest;
impl ServiceHandler for ServiceTest {
fn handle<'a>(
&'a self,
_named_node: &NamedNode,
5 years ago
) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
Some(ServiceTest::handle_service)
}
}
5 years ago
5 years ago
impl ServiceTest {
fn handle_service<'a>(_graph_pattern: GraphPattern) -> Result<BindingsIterator<'a>> {
Err(format_err!("This is supposed to fail"))
}
5 years ago
}
5 years ago
let query = r#"
5 years ago
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{
SERVICE <http://service1.org>
{ ?s foaf:name ?name
}
5 years ago
}
ORDER BY ?name
5 years ago
"#
.to_string();
let triples = b"".as_ref();
let options = QueryOptions::default().with_service_handler(Box::new(ServiceTest));
let results = do_query(triples, query, options).unwrap();
let result = results.into_values_iter().next();
match result {
Some(Err(_)) => assert_eq!(true, true),
_ => assert_eq!(
true, false,
"This should have been an error since the service fails"
),
}
5 years ago
}
5 years ago
fn ex(id: String) -> Term {
5 years ago
Term::NamedNode(NamedNode::parse(format!("http://example.com/{}", &id)).unwrap())
5 years ago
}
fn mailto(id: String) -> Term {
5 years ago
Term::NamedNode(NamedNode::parse(format!("mailto:{}", &id)).unwrap())
5 years ago
}
fn literal(str: String) -> Term {
5 years ago
Term::Literal(Literal::new_simple_literal(str))
5 years ago
}
fn make_repository(reader: impl BufRead) -> Result<MemoryRepository> {
5 years ago
let repository = MemoryRepository::default();
let mut connection = repository.connection()?;
connection
.load_graph(reader, GraphSyntax::NTriples, None, None)
.unwrap();
Ok(repository)
}
fn query_repository<'a>(
repository: MemoryRepository,
query: String,
options: QueryOptions<'a>,
) -> Result<BindingsIterator<'a>> {
match repository
.connection()?
.prepare_query(&query, options)?
.exec()?
{
5 years ago
QueryResult::Bindings(iterator) => {
let (varaibles, iter) = iterator.destruct();
let collected = iter.collect::<Vec<_>>();
Ok(BindingsIterator::new(
varaibles,
Box::new(collected.into_iter()),
))
}
_ => Err(format_err!(
"Excpected bindings but got another QueryResult"
)),
}
5 years ago
}
5 years ago
fn pattern_repository<'a>(
repository: MemoryRepository,
pattern: GraphPattern,
options: QueryOptions<'a>,
) -> Result<BindingsIterator<'a>> {
match repository
.connection()?
.prepare_query_from_pattern(&pattern, options)?
.exec()?
{
5 years ago
QueryResult::Bindings(iterator) => {
let (varaibles, iter) = iterator.destruct();
let collected = iter.collect::<Vec<_>>();
Ok(BindingsIterator::new(
varaibles,
Box::new(collected.into_iter()),
))
}
_ => Err(format_err!("Expected bindings but got another QueryResult")),
5 years ago
}
5 years ago
}
5 years ago
fn do_query<'a>(
reader: impl BufRead,
query: String,
options: QueryOptions<'a>,
) -> Result<BindingsIterator<'a>> {
let repository = make_repository(reader)?;
query_repository(repository, query, options)
5 years ago
}
5 years ago
5 years ago
fn do_pattern<'a>(
reader: impl BufRead,
pattern: GraphPattern,
options: QueryOptions<'a>,
) -> Result<BindingsIterator<'a>> {
let repository = make_repository(reader)?;
pattern_repository(repository, pattern, options)
5 years ago
}