blob: eff542e961224edf08f362f4ea2fafa3b66aa2eb [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.rdf.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
/**
* Test Graph implementation
* <p>
* To add to your implementation's tests, create a subclass with a name ending
* in <code>Test</code> and provide {@link #createFactory()} which minimally
* must support {@link RDFTermFactory#createGraph()} and
* {@link RDFTermFactory#createIRI(String)}, but ideally support all operations.
*
* @see Graph
* @see RDFTermFactory
*/
public abstract class AbstractGraphTest {
private RDFTermFactory factory;
private Graph graph;
private IRI alice;
private IRI bob;
private IRI name;
private IRI knows;
private IRI member;
private BlankNode bnode1;
private BlankNode bnode2;
private Literal aliceName;
private Literal bobName;
private Literal secretClubName;
private Literal companyName;
private Triple bobNameTriple;
public abstract RDFTermFactory createFactory();
@Before
public void createGraphAndAdd() {
factory = createFactory();
graph = factory.createGraph();
assertEquals(0, graph.size());
alice = factory.createIRI("http://example.com/alice");
bob = factory.createIRI("http://example.com/bob");
name = factory.createIRI("http://xmlns.com/foaf/0.1/name");
knows = factory.createIRI("http://xmlns.com/foaf/0.1/knows");
member = factory.createIRI("http://xmlns.com/foaf/0.1/member");
try {
bnode1 = factory.createBlankNode("org1");
bnode2 = factory.createBlankNode("org2");
} catch (UnsupportedOperationException ex) {
// leave as null
}
try {
secretClubName = factory.createLiteral("The Secret Club");
companyName = factory.createLiteral("A company");
aliceName = factory.createLiteral("Alice");
bobName = factory.createLiteral("Bob", "en-US");
} catch (UnsupportedOperationException ex) {
// leave as null
}
if (aliceName != null) {
graph.add(alice, name, aliceName);
}
graph.add(alice, knows, bob);
if (bnode1 != null) {
graph.add(alice, member, bnode1);
}
if (bobName != null) {
try {
bobNameTriple = factory.createTriple(bob, name, bobName);
} catch (UnsupportedOperationException ex) {
// leave as null
}
if (bobNameTriple != null) {
graph.add(bobNameTriple);
}
}
if (bnode1 != null) {
graph.add(factory.createTriple(bob, member, bnode1));
graph.add(factory.createTriple(bob, member, bnode2));
if (secretClubName != null) {
graph.add(bnode1, name, secretClubName);
graph.add(bnode2, name, companyName);
}
}
}
@Test
public void graphToString() {
Assume.assumeNotNull(aliceName, companyName);
//System.out.println(graph);
assertTrue(graph
.toString()
.contains(
"<http://example.com/alice> <http://xmlns.com/foaf/0.1/name> \"Alice\" ."));
assertTrue(graph.toString().contains(
" <http://xmlns.com/foaf/0.1/name> \"A company\" ."));
}
@Test
public void size() throws Exception {
assertTrue(graph.size() > 0);
Assume.assumeNotNull(bnode1, bnode2, aliceName, bobName, secretClubName,
companyName, bobNameTriple);
// Can only reliably predict size if we could create all triples
assertEquals(8, graph.size());
}
@Test
public void iterate() throws Exception {
Assume.assumeTrue(graph.size() > 0);
List<Triple> triples = new ArrayList<>();
for (Triple t : graph.iterate()) {
triples.add(t);
}
assertEquals(graph.size(), triples.size());
if (bobNameTriple != null) {
assertTrue(triples.contains(bobNameTriple));
}
// aborted iteration
Iterator<Triple> it = graph.iterate().iterator();
assertTrue(it.hasNext());
it.next();
// second iteration - should start from fresh and
// get the same count
long count = 0;
Iterable<Triple> iterable = graph.iterate();
for (Triple t : iterable) {
count++;
}
assertEquals(graph.size(), count);
}
@Test
public void iterateFilter() throws Exception {
List<RDFTerm> friends = new ArrayList<>();
IRI alice = factory.createIRI("http://example.com/alice");
IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/knows");
for (Triple t : graph.iterate(alice, knows, null)) {
friends.add(t.getObject());
}
assertEquals(1, friends.size());
assertEquals(bob, friends.get(0));
// .. can we iterate over zero hits?
assertFalse(graph.iterate(bob, knows, alice).iterator().hasNext());
}
@Test
public void contains() throws Exception {
assertFalse(graph.contains(bob, knows, alice)); // or so he claims..
assertTrue(graph.contains(alice, knows, bob));
Optional<? extends Triple> first = graph.getTriples().skip(4)
.findFirst();
Assume.assumeTrue(first.isPresent());
Triple existingTriple = first.get();
assertTrue(graph.contains(existingTriple));
Triple nonExistingTriple = factory.createTriple(bob, knows, alice);
assertFalse(graph.contains(nonExistingTriple));
Triple triple = null;
try {
triple = factory.createTriple(alice, knows, bob);
} catch (UnsupportedOperationException ex) {
}
if (triple != null) {
// FIXME: Should not this always be true?
// assertTrue(graph.contains(triple));
}
}
@Test
public void remove() throws Exception {
long fullSize = graph.size();
graph.remove(alice, knows, bob);
long shrunkSize = graph.size();
assertEquals(1, fullSize - shrunkSize);
graph.remove(alice, knows, bob);
assertEquals(shrunkSize, graph.size()); // unchanged
graph.add(alice, knows, bob);
graph.add(alice, knows, bob);
graph.add(alice, knows, bob);
// Undetermined size at this point -- but at least it
// should be bigger
assertTrue(graph.size() > shrunkSize);
// and after a single remove they should all be gone
graph.remove(alice, knows, bob);
assertEquals(shrunkSize, graph.size());
Optional<? extends Triple> anyTriple = graph.getTriples().findAny();
Assume.assumeTrue(anyTriple.isPresent());
Triple otherTriple = anyTriple.get();
graph.remove(otherTriple);
assertEquals(shrunkSize - 1, graph.size());
graph.remove(otherTriple);
assertEquals(shrunkSize - 1, graph.size()); // no change
graph.add(otherTriple);
assertEquals(shrunkSize, graph.size());
}
@Test
public void clear() throws Exception {
graph.clear();
assertFalse(graph.contains(alice, knows, bob));
assertEquals(0, graph.size());
graph.clear(); // no-op
assertEquals(0, graph.size());
}
@Test
public void getTriples() throws Exception {
long tripleCount = graph.getTriples().count();
assertTrue(tripleCount > 0);
assertTrue(graph.getTriples().allMatch(t -> graph.contains(t)));
// Check exact count
Assume.assumeNotNull(bnode1, bnode2, aliceName, bobName, secretClubName,
companyName, bobNameTriple);
assertEquals(8, tripleCount);
}
@Test
public void getTriplesQuery() throws Exception {
long aliceCount = graph.getTriples(alice, null, null).count();
assertTrue(aliceCount > 0);
Assume.assumeNotNull(aliceName);
assertEquals(3, aliceCount);
Assume.assumeNotNull(bnode1, bnode2, bobName, companyName, secretClubName);
assertEquals(4, graph.getTriples(null, name, null).count());
Assume.assumeNotNull(bnode1);
assertEquals(3, graph.getTriples(null, member, null).count());
}
/**
* An attempt to use the Java 8 streams to look up a more complicated query.
* <p>
* FYI, the equivalent SPARQL version (untested):
* <pre>
* SELECT ?orgName WHERE {
* ?org foaf:name ?orgName .
* ?alice foaf:member ?org .
* ?bob foaf:member ?org .
* ?alice foaf:knows ?bob .
* FILTER NOT EXIST { ?bob foaf:knows ?alice }
* }
* </pre>
*
* @throws Exception
*/
@Test
public void whyJavaStreamsMightNotTakeOverFromSparql() throws Exception {
Assume.assumeNotNull(bnode1, bnode2, secretClubName);
// Find a secret organizations
assertEquals(
"\"The Secret Club\"",
graph.getTriples(null, knows, null)
// Find One-way "knows"
.filter(t -> !graph.contains(
(BlankNodeOrIRI) t.getObject(), knows,
t.getSubject()))
.map(knowsTriple -> graph
// and those they know, what are they member of?
.getTriples(
(BlankNodeOrIRI) knowsTriple
.getObject(), member, null)
// keep those which first-guy is a member of
.filter(memberTriple -> graph.contains(
knowsTriple.getSubject(), member,
// First hit is good enough
memberTriple.getObject())).findFirst()
.get().getObject())
// then look up the name of that org
.map(org -> graph
.getTriples((BlankNodeOrIRI) org, name, null)
.findFirst().get().getObject().ntriplesString())
.findFirst().get());
}
}