| /* |
| * 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.jena.graph; |
| |
| import static org.apache.jena.testing_framework.GraphHelper.assertContainsAll; |
| import static org.apache.jena.testing_framework.GraphHelper.assertIsomorphic; |
| import static org.apache.jena.testing_framework.GraphHelper.assertOmitsAll; |
| import static org.apache.jena.testing_framework.GraphHelper.graphAddTxn; |
| import static org.apache.jena.testing_framework.GraphHelper.graphWith; |
| import static org.apache.jena.testing_framework.GraphHelper.iteratorToSet; |
| import static org.apache.jena.testing_framework.GraphHelper.memGraph; |
| import static org.apache.jena.testing_framework.GraphHelper.node; |
| import static org.apache.jena.testing_framework.GraphHelper.nodeSet; |
| import static org.apache.jena.testing_framework.GraphHelper.triple; |
| import static org.apache.jena.testing_framework.GraphHelper.tripleArray; |
| import static org.apache.jena.testing_framework.GraphHelper.tripleSet; |
| import static org.apache.jena.testing_framework.GraphHelper.txnBegin; |
| import static org.apache.jena.testing_framework.GraphHelper.txnRun; |
| import static org.apache.jena.testing_framework.GraphHelper.txnCommit; |
| import static org.apache.jena.testing_framework.GraphHelper.txnRollback; |
| import static org.apache.jena.testing_framework.TestUtils.assertDiffer; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.net.URISyntaxException; |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.function.Function; |
| |
| import org.apache.jena.graph.impl.LiteralLabelFactory; |
| import org.apache.jena.mem.TrackingTripleIterator; |
| import org.apache.jena.rdf.model.Model; |
| import org.apache.jena.rdf.model.ModelFactory; |
| import org.apache.jena.rdf.model.impl.ReifierStd; |
| import org.apache.jena.shared.ClosedException; |
| import org.apache.jena.shared.DeleteDeniedException; |
| import org.apache.jena.shared.PrefixMapping; |
| import org.apache.jena.testing_framework.AbstractGraphProducer; |
| import org.apache.jena.testing_framework.NodeCreateUtils; |
| import org.apache.jena.util.iterator.ClosableIterator; |
| import org.apache.jena.util.iterator.ExtendedIterator; |
| import org.junit.After; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.xenei.junit.contract.Contract; |
| import org.xenei.junit.contract.ContractTest; |
| |
| /** |
| * Graph contract test. |
| */ |
| @Contract(Graph.class) |
| public class GraphContractTest<T extends Graph> |
| { |
| |
| private static final Logger LOG = LoggerFactory |
| .getLogger(GraphContractTest.class); |
| |
| private AbstractGraphProducer<T> producer; |
| |
| protected RecordingGraphListener GL = new RecordingGraphListener(); |
| |
| @Contract.Inject |
| public final void setGraphContractTestProducer( |
| AbstractGraphProducer<T> graphProducer) |
| { |
| producer = graphProducer; |
| } |
| |
| @After |
| public final void afterGraphContractTest() |
| { |
| producer.cleanUp(); |
| GL.clear(); |
| } |
| |
| @ContractTest |
| public void testAdd_Triple() |
| { |
| Graph graph = producer.newInstance(); |
| graph.getEventManager().register(GL); |
| txnBegin(graph); |
| graph.add(triple("S P O")); |
| txnCommit(graph); |
| GL.assertHasStart("add", graph, triple("S P O")); |
| txnRun(graph, () -> assertTrue("Graph should contain <S P O>", |
| graph.contains(triple("S P O")))); |
| |
| } |
| |
| /** |
| * Inference graphs can not be truly empty. |
| * |
| * @param g |
| * @param b |
| */ |
| private void assertEmpty(Graph g, Graph b) |
| { |
| if (b.isEmpty()) |
| { |
| assertTrue("Graph should be empty", g.isEmpty()); |
| } else |
| { |
| assertEquals("Graph should be in base state", |
| b.find(Triple.ANY).toList(), g.find(Triple.ANY).toList()); |
| } |
| } |
| |
| /** |
| * Inference graphs can not be truly empty |
| * |
| * @param g |
| * @param b |
| */ |
| private void assertNotEmpty(Graph g, Graph b) |
| { |
| if (b.isEmpty()) |
| { |
| assertFalse("Graph not should be empty", g.isEmpty()); |
| } else |
| { |
| assertNotEquals("Graph should not be in base state", |
| b.find(Triple.ANY).toList(), g.find(Triple.ANY).toList()); |
| } |
| } |
| |
| /** |
| * Test that clear works, in the presence of inferencing graphs that mean |
| * emptyness isn't available. This is why we go round the houses and test |
| * that expected ~= initialContent + addedStuff - removed - initialContent. |
| */ |
| @ContractTest |
| public void testClear_Empty() |
| { |
| Graph graph = producer.newInstance(); |
| Graph base = copy(graph); |
| |
| graph.getEventManager().register(GL); |
| txnRun(graph, () -> graph.clear()); |
| |
| txnRun(graph, () -> assertEmpty(graph, base)); |
| GL.assertHasStart("someEvent", graph, GraphEvents.removeAll); |
| GL.clear(); |
| } |
| |
| @ContractTest |
| public void testClear() |
| { |
| Graph graph = producer.newInstance(); |
| Graph base = copy(graph); |
| // test after adding |
| graphWith(graph, "S P O; S e:ff 27; _1 P P3; S4 P4 'en'"); |
| graph.getEventManager().register(GL); |
| txnRun(graph, () -> graph.clear()); |
| |
| txnRun(graph, () -> assertEmpty(graph, base)); |
| if (GL.contains("delete")) |
| { |
| // deletes are listed -- ensure all deletes are listed |
| GL.assertContains("delete", graph, triple("S P O")); |
| GL.assertContains("delete", graph, triple("S e:ff 27")); |
| GL.assertContains("delete", graph, triple("_1 P P3")); |
| GL.assertContains("delete", graph, triple("S4 P4 'en'")); |
| } |
| GL.assertHasEnd("someEvent", graph, GraphEvents.removeAll); |
| GL.clear(); |
| |
| } |
| |
| @ContractTest |
| public void testClose() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S P2 O2; S3 P P3"); |
| graph.getEventManager().register(GL); |
| assertFalse("Graph was constructed closed", graph.isClosed()); |
| |
| txnRun(graph, () -> graph.close()); |
| |
| assertTrue("Graph should be closed", graph.isClosed()); |
| |
| // exception may be thrown on begin or on execution. |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.add(triple("S P O")); |
| fail("added when closed"); |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } finally |
| { |
| txnRollback(graph); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.delete(triple("x R y")); |
| fail("delete when closed"); |
| } catch (ClosedException c) |
| { |
| // Expected |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| |
| try |
| { |
| graph.add(triple("x R y")); |
| fail("add when closed"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.contains(triple("x R y")); |
| fail("contains[triple] when closed"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.contains(Node.ANY, Node.ANY, Node.ANY); |
| fail("contains[SPO] when closed"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.find(triple("x R y")); |
| fail("find [triple] when closed"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.find(Node.ANY, Node.ANY, Node.ANY); |
| fail("find[SPO] when closed"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| |
| try |
| { |
| txnBegin(graph); |
| try |
| { |
| graph.size(); |
| fail("size when closed (" + this.getClass() + ")"); |
| } catch (ClosedException c) |
| { /* as required */ |
| } finally |
| { |
| txnRollback(graph); |
| GL.assertEmpty(); |
| } |
| } catch (Exception expected) |
| { |
| GL.assertEmpty(); |
| // expected |
| } |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| |
| txnRun(graph, () -> { |
| assertTrue(graph.contains(node("S"), node("P"), node("O"))); |
| assertFalse(graph.contains(node("S"), node("P"), node("O2"))); |
| assertFalse(graph.contains(node("S"), node("P2"), node("O"))); |
| assertFalse(graph.contains(node("S2"), node("P"), node("O"))); |
| assertTrue(graph.contains(Node.ANY, Node.ANY, Node.ANY)); |
| assertTrue(graph.contains(Node.ANY, Node.ANY, node("O"))); |
| assertTrue(graph.contains(Node.ANY, node("P"), Node.ANY)); |
| assertTrue(graph.contains(node("S"), Node.ANY, Node.ANY)); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node_RepeatedSubjectDoesNotConceal() |
| { |
| |
| Graph g = graphWith(producer.newInstance(), "s P o; s Q r"); |
| Node s = node("s"); |
| Node P = node("P"); |
| Node o = node("o"); |
| Node Q = node("Q"); |
| Node r = node("r"); |
| Node any = node("??"); |
| txnRun(g, () -> { |
| assertTrue(g.contains(s, P, o)); |
| assertTrue(g.contains(s, Q, r)); |
| assertTrue(g.contains(any, P, o)); |
| assertTrue(g.contains(any, Q, r)); |
| assertTrue(g.contains(any, P, any)); |
| assertTrue(g.contains(any, Q, any)); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node_ByValue() |
| { |
| Node x = node("x"); |
| Node P = node("P"); |
| Graph g1 = producer.newInstance(); |
| if (g1.getCapabilities().handlesLiteralTyping()) |
| { |
| graphWith(g1, "x P '1'xsd:integer"); |
| txnRun(g1, |
| () -> assertTrue( |
| String.format( |
| "literal type equality failed, does %s really implement literal typing", |
| g1.getClass()), |
| g1.contains(x, P, node("'01'xsd:int")))); |
| // |
| Graph g2 = graphWith(producer.newInstance(), "x P '1'xsd:int"); |
| txnRun(g2, () -> { |
| assertTrue("Literal equality with '1'xsd:integer failed", |
| g2.contains(x, P, node("'1'xsd:integer"))); |
| }); |
| // |
| Graph g3 = graphWith(producer.newInstance(), "x P '123'xsd:string"); |
| txnRun(g3, () -> { |
| assertTrue("Literal equality with '123' failed", |
| g3.contains(x, P, node("'123'"))); |
| }); |
| } |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node_Concrete() |
| { |
| Node s = node("s"); |
| Node P = node("P"); |
| Node o = node("o"); |
| |
| Node _x = node("_x"); |
| Node R = node("R"); |
| Node _y = node("_y"); |
| |
| Node x = node("x"); |
| Node S = node("S"); |
| |
| Graph g = graphWith(producer.newInstance(), "s P o; _x R _y; x S 0"); |
| txnRun(g, () -> { |
| |
| assertTrue("Graph should have contained s P o", |
| g.contains(s, P, o)); |
| assertTrue("Graph should have contained _x _R _y", |
| g.contains(_x, R, _y)); |
| assertTrue("Graph should have contained x S 'O'", |
| g.contains(x, S, node("0"))); |
| /* */ |
| assertFalse(g.contains(s, P, node("Oh"))); |
| assertFalse(g.contains(S, P, node("O"))); |
| assertFalse(g.contains(s, node("p"), o)); |
| assertFalse(g.contains(_x, node("_r"), _y)); |
| assertFalse(g.contains(x, S, node("1"))); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node_Concrete_BlankPredicate() |
| { |
| Node s = node("s"); |
| Node P = node("P"); |
| Node o = node("o"); |
| |
| Node _x = node("_x"); |
| Node _R = node("_R"); |
| Node _y = node("_y"); |
| |
| Node x = node("x"); |
| Node S = node("S"); |
| |
| Graph g = graphWith(producer.newInstance(), "s P o; _x _R _y; x S 0"); |
| txnRun(g, () -> { |
| |
| assertTrue("Graph should have contained _x _R _y", |
| g.contains(_x, _R, _y)); |
| assertFalse(g.contains(_x, node("_r"), _y)); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Node_Node_Node_Fluid() |
| { |
| Node x = node("x"); |
| Node R = node("R"); |
| Node P = node("P"); |
| Node y = node("y"); |
| Node a = node("a"); |
| Node b = node("b"); |
| Graph g = graphWith(producer.newInstance(), "x R y; a P b"); |
| |
| txnRun(g, () -> { |
| assertTrue(g.contains(Node.ANY, R, y)); |
| assertTrue(g.contains(x, Node.ANY, y)); |
| assertTrue(g.contains(x, R, Node.ANY)); |
| assertTrue(g.contains(Node.ANY, P, b)); |
| assertTrue(g.contains(a, Node.ANY, b)); |
| assertTrue(g.contains(a, P, Node.ANY)); |
| assertTrue(g.contains(Node.ANY, R, y)); |
| /* */ |
| assertFalse(g.contains(Node.ANY, R, b)); |
| assertFalse(g.contains(a, Node.ANY, y)); |
| assertFalse(g.contains(x, P, Node.ANY)); |
| assertFalse(g.contains(Node.ANY, R, x)); |
| assertFalse(g.contains(x, Node.ANY, R)); |
| assertFalse(g.contains(a, node("S"), Node.ANY)); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Triple() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| txnRun(graph, () -> { |
| assertTrue(graph.contains(triple("S P O"))); |
| assertFalse(graph.contains(triple("S P O2"))); |
| assertFalse(graph.contains(triple("S P2 O"))); |
| assertFalse(graph.contains(triple("S2 P O"))); |
| assertTrue(graph.contains(Triple.ANY)); |
| assertTrue( |
| graph.contains(new Triple(Node.ANY, Node.ANY, node("O")))); |
| assertTrue( |
| graph.contains(new Triple(Node.ANY, node("P"), Node.ANY))); |
| assertTrue( |
| graph.contains(new Triple(node("S"), Node.ANY, Node.ANY))); |
| }); |
| |
| } |
| |
| @ContractTest |
| public void testContains_Triple_RepeatedSubjectDoesNotConceal() |
| { |
| |
| Graph g = graphWith(producer.newInstance(), "s P o; s Q r"); |
| txnRun(g, () -> { |
| assertTrue(g.contains(triple("s P o"))); |
| assertTrue(g.contains(triple("s Q r"))); |
| assertTrue(g.contains(triple("?? P o"))); |
| assertTrue(g.contains(triple("?? Q r"))); |
| assertTrue(g.contains(triple("?? P ??"))); |
| assertTrue(g.contains(triple("?? Q ??"))); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Triple_ByValue() |
| { |
| Graph g1 = producer.newInstance(); |
| if (g1.getCapabilities().handlesLiteralTyping()) |
| { |
| graphWith(g1, "x P '1'xsd:integer"); |
| txnRun(g1, () -> { |
| assertTrue( |
| String.format( |
| "did not find x P '01'xsd:int, does %s really implement literal typing", |
| g1.getClass()), |
| g1.contains(triple("x P '01'xsd:int"))); |
| }); |
| // |
| Graph g2 = graphWith(producer.newInstance(), "x P '1'xsd:int"); |
| txnRun(g2, () -> { |
| assertTrue("did not find x P '1'xsd:integer", |
| g2.contains(triple("x P '1'xsd:integer"))); |
| }); |
| // |
| Graph g3 = graphWith(producer.newInstance(), "x P '123'xsd:string"); |
| txnRun(g3, () -> assertTrue("did not find x P '123'xsd:string", |
| g3.contains(triple("x P '123'")))); |
| } |
| } |
| |
| @ContractTest |
| public void testContains_Triple_Concrete() |
| { |
| Graph g = graphWith(producer.newInstance(), "s P o; _x R _y; x S 0"); |
| txnRun(g, () -> { |
| assertTrue(g.contains(triple("s P o"))); |
| assertTrue(g.contains(triple("_x R _y"))); |
| assertTrue(g.contains(triple("x S 0"))); |
| /* */ |
| assertFalse(g.contains(triple("s P Oh"))); |
| assertFalse(g.contains(triple("S P O"))); |
| assertFalse(g.contains(triple("s p o"))); |
| assertFalse(g.contains(triple("_x _r _y"))); |
| assertFalse(g.contains(triple("x S 1"))); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Triple_Concrete_BlankPredicate() |
| { |
| Graph g = graphWith(producer.newInstance(), "s P o; _x _R _y; x S 0"); |
| txnRun(g, () -> { |
| assertTrue(g.contains(triple("s P o"))); |
| assertTrue(g.contains(triple("_x _R _y"))); |
| assertTrue(g.contains(triple("x S 0"))); |
| /* */ |
| assertFalse(g.contains(triple("s P Oh"))); |
| assertFalse(g.contains(triple("S P O"))); |
| assertFalse(g.contains(triple("s p o"))); |
| assertFalse(g.contains(triple("_x _r _y"))); |
| assertFalse(g.contains(triple("x S 1"))); |
| }); |
| } |
| |
| @ContractTest |
| public void testContains_Triple_Fluid() |
| { |
| Graph g = graphWith(producer.newInstance(), "x R y; a P b"); |
| txnRun(g, () -> { |
| |
| assertTrue(g.contains(triple("?? R y"))); |
| assertTrue(g.contains(triple("x ?? y"))); |
| assertTrue(g.contains(triple("x R ??"))); |
| assertTrue(g.contains(triple("?? P b"))); |
| assertTrue(g.contains(triple("a ?? b"))); |
| assertTrue(g.contains(triple("a P ??"))); |
| assertTrue(g.contains(triple("?? R y"))); |
| /* */ |
| assertFalse(g.contains(triple("?? R b"))); |
| assertFalse(g.contains(triple("a ?? y"))); |
| assertFalse(g.contains(triple("x P ??"))); |
| assertFalse(g.contains(triple("?? R x"))); |
| assertFalse(g.contains(triple("x ?? R"))); |
| assertFalse(g.contains(triple("a S ??"))); |
| }); |
| } |
| |
| /** |
| * Inference graphs can not be empty |
| */ |
| @ContractTest |
| public void testDelete_Triple() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| Graph base = producer.newInstance(); |
| graph.getEventManager().register(GL); |
| |
| try |
| { |
| txnBegin(graph); |
| graph.delete(triple("S P O")); |
| txnCommit(graph); |
| } catch (DeleteDeniedException expected) |
| { |
| txnRollback(graph); |
| fail("delete( S P O ) failed: " + expected.getMessage()); |
| } |
| |
| GL.assertContains("delete", graph, triple("S P O")); |
| |
| txnRun(graph, () -> { |
| assertFalse("Graph should not contain <S P O>", |
| graph.contains(triple("S P O"))); |
| assertNotEmpty(graph, base); |
| assertTrue("Graph should contain <S2 P2 O2>", |
| graph.contains(triple("S2 P2 O2"))); |
| assertTrue("Graph should contain <S3 P3 O3>", |
| graph.contains(triple("S3 P3 O3"))); |
| }); |
| } |
| |
| @ContractTest |
| public void testDelete_Triple_Wildcard() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| Graph base = producer.newInstance(); |
| graph.getEventManager().register(GL); |
| |
| // should not modify anything on wildcard delete |
| GL.clear(); |
| try |
| { |
| txnBegin(graph); |
| graph.delete(new Triple(node("S2"), node("P2"), Node.ANY)); |
| txnCommit(graph); |
| } catch (DeleteDeniedException expected) |
| { |
| txnRollback(graph); |
| } |
| txnRun(graph, () -> { |
| |
| assertTrue("Graph should contain <S2 P2 O2>", |
| graph.contains(triple("S2 P2 O2"))); |
| assertTrue("Graph should contain <S3 P3 O3>", |
| graph.contains(triple("S3 P3 O3"))); |
| }); |
| GL.assertHas("delete", graph, |
| new Triple(node("S2"), node("P2"), Node.ANY)); |
| } |
| |
| @ContractTest |
| public void testDelete_Triple_FromNothing() |
| { |
| Graph g = producer.newInstance(); |
| g.getEventManager().register(GL); |
| txnBegin(g); |
| g.delete(triple("quint rdf:subject S")); |
| txnCommit(g); |
| GL.assertContains("delete", g, triple("quint rdf:subject S")); |
| } |
| |
| @ContractTest |
| public void testDependsOn() |
| { |
| Graph g = producer.newInstance(); |
| Graph[] depGraphs = producer.getDependsOn(g); |
| if (depGraphs != null) |
| { |
| for (Graph dg : depGraphs) |
| { |
| assertTrue( |
| String.format("Graph %s should depend upon %s", g, dg), |
| g.dependsOn(dg)); |
| } |
| } |
| depGraphs = producer.getNotDependsOn(g); |
| if (depGraphs != null) |
| { |
| for (Graph dg : depGraphs) |
| { |
| assertFalse(String.format("Graph %s should not depend upon %s", |
| g, dg), g.dependsOn(dg)); |
| } |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Node_Node_Node() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| txnBegin(graph); |
| List<Triple> s = graph.find(Node.ANY, Node.ANY, Node.ANY).toList(); |
| assertEquals(3, s.size()); |
| List<Triple> expected = Arrays.asList(new Triple[] { triple("S P O"), |
| triple("S2 P2 O2"), triple("S3 P3 O3") }); |
| assertTrue("Missing some values", |
| expected.containsAll(s) && s.containsAll(expected)); |
| |
| s = graph.find(node("S"), Node.ANY, Node.ANY).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(Node.ANY, node("P"), Node.ANY).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(Node.ANY, Node.ANY, node("O")).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(node("S2"), node("P2"), node("O2")).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S2 P2 O2"))); |
| |
| s = graph.find(node("S2"), node("P3"), node("O2")).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(Node.ANY, node("P3"), node("O2")).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(node("S3"), Node.ANY, node("O2")).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(node("S3"), node("P2"), Node.ANY).toList(); |
| assertEquals(0, s.size()); |
| txnRollback(graph); |
| } |
| |
| @ContractTest |
| public void testFind_Node_Node_Node_ByFluidTriple() |
| { |
| Node x = node("x"); |
| Node y = node("y"); |
| Node z = node("z"); |
| Graph g = graphWith(producer.newInstance(), "x y z "); |
| Set<Triple> expect = tripleSet("x y z"); |
| txnBegin(g); |
| assertEquals(expect, g.find(Node.ANY, y, z).toSet()); |
| assertEquals(expect, g.find(x, Node.ANY, z).toSet()); |
| assertEquals(expect, g.find(x, y, Node.ANY).toSet()); |
| txnRollback(g); |
| } |
| |
| @ContractTest |
| public void testFind_Node_Node_Node_ProgrammaticValues() |
| { |
| Graph g = producer.newInstance(); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node ab = NodeFactory.createLiteral(LiteralLabelFactory |
| .createTypedLiteral(new Byte((byte) 42))); |
| Node as = NodeFactory.createLiteral(LiteralLabelFactory |
| .createTypedLiteral(new Short((short) 42))); |
| Node ai = NodeFactory.createLiteral( |
| LiteralLabelFactory.createTypedLiteral(new Integer(42))); |
| Node al = NodeFactory.createLiteral( |
| LiteralLabelFactory.createTypedLiteral(new Long(42))); |
| |
| Node SB = NodeCreateUtils.create("SB"); |
| Node SS = NodeCreateUtils.create("SS"); |
| Node SI = NodeCreateUtils.create("SI"); |
| Node SL = NodeCreateUtils.create("SL"); |
| Node P = NodeCreateUtils.create("P"); |
| |
| txnBegin(g); |
| try |
| { |
| g.add(Triple.create(SB, P, ab)); |
| g.add(Triple.create(SS, P, as)); |
| g.add(Triple.create(SI, P, ai)); |
| g.add(Triple.create(SL, P, al)); |
| } catch (Exception e) |
| { |
| txnRollback(g); |
| fail(e.getMessage()); |
| } |
| txnCommit(g); |
| txnBegin(g); |
| assertEquals( |
| String.format( |
| "Should have found 4 elements, does %s really implement literal typing", |
| g.getClass()), |
| 4, |
| iteratorToSet( |
| g.find(Node.ANY, P, NodeCreateUtils.create("42"))) |
| .size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Node_Node_Node_MatchLanguagedLiteralCaseInsensitive() |
| { |
| Graph g = graphWith(producer.newInstance(), "a p 'chat'en"); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node chaten = node("'chat'en"), chatEN = node("'chat'EN"); |
| assertDiffer(chaten, chatEN); |
| assertTrue(chaten.sameValueAs(chatEN)); |
| assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue()); |
| txnBegin(g); |
| assertEquals(1, g.find(Node.ANY, Node.ANY, chaten).toList().size()); |
| assertEquals(1, g.find(Node.ANY, Node.ANY, chatEN).toList().size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Node_Node_Node_NoMatchAgainstUnlanguagesLiteral() |
| { |
| Graph g = graphWith(producer.newInstance(), "a p 'chat'en; a p 'chat'"); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node chaten = node("'chat'en"), chatEN = node("'chat'EN"); |
| assertDiffer(chaten, chatEN); |
| assertTrue(chaten.sameValueAs(chatEN)); |
| assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue()); |
| txnBegin(g); |
| assertEquals(1, g.find(Node.ANY, Node.ANY, chaten).toList().size()); |
| assertEquals(1, g.find(Node.ANY, Node.ANY, chatEN).toList().size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Triple() |
| { |
| Graph graph = graphWith(producer.newInstance(), |
| "S P O; S2 P2 O2; S3 P3 O3"); |
| txnBegin(graph); |
| List<Triple> s = graph.find(Triple.ANY).toList(); |
| assertEquals(3, s.size()); |
| List<Triple> expected = Arrays.asList(new Triple[] { triple("S P O"), |
| triple("S2 P2 O2"), triple("S3 P3 O3") }); |
| assertTrue("Missing some values", expected.containsAll(s)); |
| |
| s = graph.find(new Triple(node("S"), Node.ANY, Node.ANY)).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(new Triple(Node.ANY, node("P"), Node.ANY)).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(new Triple(Node.ANY, Node.ANY, node("O"))).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S P O"))); |
| |
| s = graph.find(new Triple(node("S2"), node("P2"), node("O2"))).toList(); |
| assertEquals(1, s.size()); |
| assertTrue("Missing some values", s.contains(triple("S2 P2 O2"))); |
| |
| s = graph.find(new Triple(node("S2"), node("P3"), node("O2"))).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(new Triple(Node.ANY, node("P3"), node("O2"))).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(new Triple(node("S3"), Node.ANY, node("O2"))).toList(); |
| assertEquals(0, s.size()); |
| |
| s = graph.find(new Triple(node("S3"), node("P2"), Node.ANY)).toList(); |
| assertEquals(0, s.size()); |
| txnRollback(graph); |
| } |
| |
| @ContractTest |
| public void testFind_Triple_ByFluidTriple() |
| { |
| Graph g = graphWith(producer.newInstance(), "x y z "); |
| Set<Triple> expect = tripleSet("x y z"); |
| txnBegin(g); |
| assertEquals(expect, g.find(triple("?? y z")).toSet()); |
| assertEquals(expect, g.find(triple("x ?? z")).toSet()); |
| assertEquals(expect, g.find(triple("x y ??")).toSet()); |
| txnRollback(g); |
| } |
| |
| @ContractTest |
| public void testFind_Triple_ProgrammaticValues() |
| { |
| Graph g = producer.newInstance(); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node ab = NodeFactory.createLiteral(LiteralLabelFactory |
| .createTypedLiteral(new Byte((byte) 42))); |
| Node as = NodeFactory.createLiteral(LiteralLabelFactory |
| .createTypedLiteral(new Short((short) 42))); |
| Node ai = NodeFactory.createLiteral( |
| LiteralLabelFactory.createTypedLiteral(new Integer(42))); |
| Node al = NodeFactory.createLiteral( |
| LiteralLabelFactory.createTypedLiteral(new Long(42))); |
| |
| Node SB = NodeCreateUtils.create("SB"); |
| Node SS = NodeCreateUtils.create("SS"); |
| Node SI = NodeCreateUtils.create("SI"); |
| Node SL = NodeCreateUtils.create("SL"); |
| Node P = NodeCreateUtils.create("P"); |
| |
| txnBegin(g); |
| try |
| { |
| g.add(Triple.create(SB, P, ab)); |
| g.add(Triple.create(SS, P, as)); |
| g.add(Triple.create(SI, P, ai)); |
| g.add(Triple.create(SL, P, al)); |
| } catch (Exception e) |
| { |
| txnRollback(g); |
| fail(e.getMessage()); |
| } |
| txnCommit(g); |
| txnBegin(g); |
| assertEquals( |
| String.format( |
| "Should have found 4 elements, does %s really implement literal typing", |
| g.getClass()), |
| 4, iteratorToSet(g.find(new Triple(Node.ANY, P, |
| NodeCreateUtils.create("42")))).size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Triple_MatchLanguagedLiteralCaseInsensitive() |
| { |
| Graph g = graphWith(producer.newInstance(), "a p 'chat'en"); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node chaten = node("'chat'en"), chatEN = node("'chat'EN"); |
| assertDiffer(chaten, chatEN); |
| assertTrue(chaten.sameValueAs(chatEN)); |
| assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue()); |
| txnBegin(g); |
| assertEquals(1, g.find(new Triple(Node.ANY, Node.ANY, chaten)) |
| .toList().size()); |
| assertEquals(1, g.find(new Triple(Node.ANY, Node.ANY, chatEN)) |
| .toList().size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testFind_Triple_NoMatchAgainstUnlanguagesLiteral() |
| { |
| Graph g = graphWith(producer.newInstance(), "a p 'chat'en; a p 'chat'"); |
| if (g.getCapabilities().handlesLiteralTyping()) |
| { |
| Node chaten = node("'chat'en"), chatEN = node("'chat'EN"); |
| assertDiffer(chaten, chatEN); |
| assertTrue(chaten.sameValueAs(chatEN)); |
| assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue()); |
| txnBegin(g); |
| assertEquals(1, g.find(new Triple(Node.ANY, Node.ANY, chaten)) |
| .toList().size()); |
| assertEquals(1, g.find(new Triple(Node.ANY, Node.ANY, chatEN)) |
| .toList().size()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testGetCapabilities() |
| { |
| Graph g = producer.newInstance(); |
| Capabilities c = g.getCapabilities(); |
| assertNotNull("Capabilities are not returned", c); |
| try |
| { |
| c.sizeAccurate(); |
| } catch (Exception e) |
| { |
| fail("sizeAccurate() threw Exception: " + e.toString()); |
| } |
| try |
| { |
| c.addAllowed(); |
| } catch (Exception e) |
| { |
| fail("addAllowed() threw Exception: " + e.toString()); |
| } |
| try |
| { |
| c.deleteAllowed(); |
| } catch (Exception e) |
| { |
| fail("deleteAllowed() threw Exception: " + e.toString()); |
| } |
| } |
| |
| @ContractTest |
| public void testGetEventManager() |
| { |
| assertNotNull("Must return an EventManager", |
| producer.newInstance().getEventManager()); |
| } |
| |
| @ContractTest |
| public void testGetPrefixMapping() |
| { |
| Graph g = producer.newInstance(); |
| txnBegin(g); |
| PrefixMapping pm = g.getPrefixMapping(); |
| assertNotNull("Must return prefix mapping", pm); |
| assertSame("getPrefixMapping must always return the same object", pm, |
| g.getPrefixMapping()); |
| txnRollback(g); |
| pm.setNsPrefix("pfx1", "http://example.com/"); |
| pm.setNsPrefix("pfx2", "scheme:rope/string#"); |
| |
| txnBegin(g); |
| // assert same after adding to other mapl |
| assertSame("getPrefixMapping must always return the same object", pm, |
| g.getPrefixMapping()); |
| txnRollback(g); |
| |
| } |
| |
| @ContractTest |
| public void testGetTransactionHandler() |
| { |
| Graph g = producer.newInstance(); |
| assertNotNull("Must return a Transaction handler", |
| g.getTransactionHandler()); |
| } |
| |
| @ContractTest |
| public void testIsClosed() |
| { |
| Graph g = producer.newInstance(); |
| assertFalse("Graph created in closed state", g.isClosed()); |
| txnBegin(g); |
| g.close(); |
| txnCommit(g); |
| txnBegin(g); |
| assertTrue("Graph does not report closed state after close called", |
| g.isClosed()); |
| txnRollback(g); |
| } |
| |
| @ContractTest |
| public void testIsEmpty() |
| { |
| Graph g = producer.newInstance(); |
| txnBegin(g); |
| if (!g.isEmpty()) |
| { |
| LOG.warn(String.format( |
| "Graph type %s can not be empty (Empty test skipped)", |
| g.getClass())); |
| txnRollback(g); |
| } else |
| { |
| txnRollback(g); |
| graphAddTxn(g, "S P O"); |
| txnBegin(g); |
| assertFalse("Graph reports empty after add", g.isEmpty()); |
| txnRollback(g); |
| |
| txnBegin(g); |
| g.add(NodeCreateUtils.createTriple("Foo B C")); |
| g.delete(NodeCreateUtils.createTriple("S P O")); |
| txnCommit(g); |
| txnBegin(g); |
| assertFalse("Should not report empty", g.isEmpty()); |
| txnRollback(g); |
| |
| txnBegin(g); |
| g.delete(NodeCreateUtils.createTriple("Foo B C")); |
| txnCommit(g); |
| txnBegin(g); |
| assertTrue("Should report empty after all entries deleted", |
| g.isEmpty()); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testIsIsomorphicWith_Graph() |
| { |
| Graph graph = producer.newInstance(); |
| Graph g2 = memGraph(); |
| txnBegin(graph); |
| assertTrue("Empty graphs should be isomorphic", |
| graph.isIsomorphicWith(g2)); |
| txnRollback(graph); |
| graphWith(graph, "S P O; S2 P2 O2; S3 P3 O3"); |
| g2 = graphWith("S3 P3 O3; S2 P2 O2; S P O"); |
| txnBegin(graph); |
| assertTrue("Should be isomorphic", graph.isIsomorphicWith(g2)); |
| txnRollback(graph); |
| txnBegin(graph); |
| graph.add(triple("_1, P4 S4")); |
| txnCommit(graph); |
| |
| txnBegin(g2); |
| g2.add(triple("_2, P4 S4")); |
| txnCommit(g2); |
| txnBegin(graph); |
| assertTrue("Should be isomorphic after adding anonymous nodes", |
| graph.isIsomorphicWith(g2)); |
| txnRollback(graph); |
| |
| txnBegin(graph); |
| graph.add(triple("_1, P3 S4")); |
| txnCommit(graph); |
| |
| txnBegin(g2); |
| g2.add(triple("_2, P4 S4")); |
| txnCommit(g2); |
| txnBegin(graph); |
| assertFalse("Should not be isomorphic", graph.isIsomorphicWith(g2)); |
| txnRollback(graph); |
| } |
| |
| private Graph copy(Graph g) |
| { |
| Graph result = producer.newInstance(); |
| txnBegin(result); |
| GraphUtil.addInto(result, g); |
| txnCommit(result); |
| return result; |
| } |
| |
| private Graph remove(Graph toUpdate, Graph toRemove) |
| { |
| txnBegin(toUpdate); |
| GraphUtil.deleteFrom(toUpdate, toRemove); |
| txnCommit(toUpdate); |
| return toUpdate; |
| } |
| |
| /** |
| * Test that remove(s, p, o) works, in the presence of inferencing graphs |
| * that mean emptyness isn't available. This is why we go round the houses |
| * and test that expected ~= initialContent + addedStuff - removed - |
| * initialContent. |
| */ |
| @ContractTest |
| public void testRemove_Node_Node_Node() |
| { |
| for (int i = 0; i < cases.length; i += 1) |
| for (int j = 0; j < 3; j += 1) |
| { |
| Graph content = producer.newInstance(); |
| |
| Graph baseContent = copy(content); |
| graphAddTxn(content, cases[i][0]); |
| Triple remove = triple(cases[i][1]); |
| Graph expected = graphWith(cases[i][2]); |
| Triple[] removed = tripleArray(cases[i][3]); |
| content.getEventManager().register(GL); |
| GL.clear(); |
| txnBegin(content); |
| content.remove(remove.getSubject(), remove.getPredicate(), |
| remove.getObject()); |
| txnCommit(content); |
| |
| // check for optional delete notifications |
| if (GL.contains("delete")) |
| { |
| // if it contains any it must contain all. |
| for (Triple t : removed) |
| { |
| GL.assertContains("delete", content, t); |
| } |
| } |
| GL.assertHasEnd("someEvent", content, |
| GraphEvents.remove(remove.getSubject(), |
| remove.getPredicate(), remove.getObject())); |
| |
| content.getEventManager().unregister(GL); |
| Graph finalContent = remove(copy(content), baseContent); |
| txnBegin(finalContent); |
| assertIsomorphic(cases[i][1], expected, finalContent); |
| txnRollback(finalContent); |
| } |
| } |
| |
| @ContractTest |
| public void testRemove_ByIterator() |
| { |
| testRemove("?? ?? ??", "?? ?? ??"); |
| testRemove("S ?? ??", "S ?? ??"); |
| testRemove("S ?? ??", "?? P ??"); |
| testRemove("S ?? ??", "?? ?? O"); |
| testRemove("?? P ??", "S ?? ??"); |
| testRemove("?? P ??", "?? P ??"); |
| testRemove("?? P ??", "?? ?? O"); |
| testRemove("?? ?? O", "S ?? ??"); |
| testRemove("?? ?? O", "?? P ??"); |
| testRemove("?? ?? O", "?? ?? O"); |
| } |
| |
| private void testRemove(String findRemove, String findCheck) |
| { |
| Graph g = graphWith(producer.newInstance(), "S P O"); |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g |
| .find(NodeCreateUtils.createTriple(findRemove)); |
| txnRollback(g); |
| try |
| { |
| it.next(); |
| it.remove(); |
| it.close(); |
| assertEquals("remove with " + findRemove + ":", 0, g.size()); |
| assertFalse(g.contains(NodeCreateUtils.createTriple(findCheck))); |
| } catch (UnsupportedOperationException e) |
| { |
| it.close(); |
| } |
| } |
| |
| /** |
| * This test case was generated by Ian and was caused by GraphMem not |
| * keeping up with changes to the find interface. |
| */ |
| @ContractTest |
| public void testFindAndContains() |
| { |
| Graph g = producer.newInstance(); |
| Node r = NodeCreateUtils.create("r"), s = NodeCreateUtils.create("s"), |
| p = NodeCreateUtils.create("P"); |
| txnBegin(g); |
| try |
| { |
| g.add(Triple.create(r, p, s)); |
| txnCommit(g); |
| txnBegin(g); |
| assertTrue(g.contains(r, p, Node.ANY)); |
| assertEquals(1, g.find(r, p, Node.ANY).toList().size()); |
| } catch (Exception e) |
| { |
| fail(e.getMessage()); |
| } finally |
| { |
| txnRollback(g); |
| } |
| } |
| |
| /** |
| * Check that contains respects by-value semantics. |
| */ |
| |
| @ContractTest |
| public void testAGraph() |
| { |
| String title = this.getClass().getName(); |
| Graph g = producer.newInstance(); |
| txnBegin(g); |
| int baseSize = g.size(); |
| txnRollback(g); |
| graphAddTxn(g, "x R y; p S q; a T b"); |
| /* */ |
| txnBegin(g); |
| assertContainsAll(title + ": simple graph", g, "x R y; p S q; a T b"); |
| assertEquals(title + ": size", baseSize + 3, g.size()); |
| txnRollback(g); |
| |
| graphAddTxn(g, |
| "spindizzies lift cities; Diracs communicate instantaneously"); |
| txnBegin(g); |
| assertEquals(title + ": size after adding", baseSize + 5, g.size()); |
| |
| g.delete(triple("x R y")); |
| g.delete(triple("a T b")); |
| txnCommit(g); |
| txnBegin(g); |
| assertEquals(title + ": size after deleting", baseSize + 3, g.size()); |
| assertContainsAll(title + ": modified simple graph", g, |
| "p S q; spindizzies lift cities; Diracs communicate instantaneously"); |
| assertOmitsAll(title + ": modified simple graph", g, "x R y; a T b"); |
| /* */ |
| ClosableIterator<Triple> it = g.find(Node.ANY, node("lift"), Node.ANY); |
| assertTrue(title + ": finds some triple(s)", it.hasNext()); |
| assertEquals(title + ": finds a 'lift' triple", |
| triple("spindizzies lift cities"), it.next()); |
| assertFalse(title + ": finds exactly one triple", it.hasNext()); |
| txnRollback(g); |
| it.close(); |
| } |
| |
| @ContractTest |
| public void testAddWithReificationPreamble() |
| { |
| Graph g = producer.newInstance(); |
| txnBegin(g); |
| xSPO(g); |
| txnCommit(g); |
| txnBegin(g); |
| assertFalse(g.isEmpty()); |
| txnRollback(g); |
| } |
| |
| protected void xSPOyXYZ(Graph g) |
| { |
| xSPO(g); |
| ReifierStd.reifyAs(g, NodeCreateUtils.create("y"), |
| NodeCreateUtils.createTriple("X Y Z")); |
| } |
| |
| protected void aABC(Graph g) |
| { |
| ReifierStd.reifyAs(g, NodeCreateUtils.create("a"), |
| NodeCreateUtils.createTriple("Foo B C")); |
| } |
| |
| protected void xSPO(Graph g) |
| { |
| ReifierStd.reifyAs(g, NodeCreateUtils.create("x"), |
| NodeCreateUtils.createTriple("S P O")); |
| } |
| |
| @ContractTest |
| public void failingTestDoubleRemoveAll() |
| { |
| final Graph g = producer.newInstance(); |
| try |
| { |
| graphAddTxn(g, "c S d; e:ff GGG hhhh; _i J 27; Ell Em 'en'"); |
| txnBegin(g); |
| Iterator<Triple> it = new TrackingTripleIterator(g.find(Triple.ANY)) |
| { |
| @Override |
| public void remove() |
| { |
| super.remove(); // removes current |
| g.delete(current); // no-op. |
| } |
| }; |
| txnRollback(g); |
| while (it.hasNext()) |
| { |
| it.next(); |
| it.remove(); |
| } |
| txnBegin(g); |
| assertTrue(g.isEmpty()); |
| txnRollback(g); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| /** |
| * Test cases for RemoveSPO(); each entry is a triple (add, remove, result). |
| * <ul> |
| * <li>add - the triples to add to the graph to start with |
| * <li>remove - the pattern to use in the removal |
| * <li>result - the triples that should remain in the graph |
| * </ul> |
| */ |
| protected static String[][] cases = { { "x R y", "x R y", "", "x R y" }, |
| { "x R y; a P b", "x R y", "a P b", "x R y" }, |
| { "x R y; a P b", "?? R y", "a P b", "x R y" }, |
| { "x R y; a P b", "x R ??", "a P b", "x R y" }, |
| { "x R y; a P b", "x ?? y", "a P b", "x R y" }, |
| { "x R y; a P b", "?? ?? ??", "", "x R y; a P b" }, |
| { "x R y; a P b; c P d", "?? P ??", "x R y", "a P b; c P d" }, |
| { "x R y; a P b; x S y", "x ?? ??", "a P b", "x R y; x S y" }, }; |
| |
| /** |
| * testIsomorphism from file data |
| * |
| * @throws URISyntaxException |
| * @throws MalformedURLException |
| */ |
| @ContractTest |
| public void testIsomorphismFile() |
| throws URISyntaxException, MalformedURLException |
| { |
| testIsomorphismXMLFile(1, true); |
| testIsomorphismXMLFile(2, true); |
| testIsomorphismXMLFile(3, true); |
| testIsomorphismXMLFile(4, true); |
| testIsomorphismXMLFile(5, false); |
| testIsomorphismXMLFile(6, false); |
| testIsomorphismNTripleFile(7, true); |
| testIsomorphismNTripleFile(8, false); |
| |
| } |
| |
| private void testIsomorphismNTripleFile(int i, boolean result) |
| { |
| testIsomorphismFile(i, "N-TRIPLE", "nt", result); |
| } |
| |
| private void testIsomorphismXMLFile(int i, boolean result) |
| { |
| testIsomorphismFile(i, "RDF/XML", "rdf", result); |
| } |
| |
| private InputStream getInputStream(int n, int n2, String suffix) |
| { |
| String urlStr = String.format("regression/testModelEquals/%s-%s.%s", n, |
| n2, suffix); |
| return GraphContractTest.class.getClassLoader() |
| .getResourceAsStream(urlStr); |
| } |
| |
| private void testIsomorphismFile(int n, String lang, String suffix, |
| boolean result) |
| { |
| Graph g1 = producer.newInstance(); |
| Graph g2 = producer.newInstance(); |
| Model m1 = ModelFactory.createModelForGraph(g1); |
| Model m2 = ModelFactory.createModelForGraph(g2); |
| |
| txnBegin(g1); |
| m1.read(getInputStream(n, 1, suffix), "http://www.example.org/", lang); |
| txnCommit(g1); |
| |
| txnBegin(g2); |
| m2.read(getInputStream(n, 2, suffix), "http://www.example.org/", lang); |
| txnCommit(g2); |
| |
| txnBegin(g1); |
| boolean rslt = g1.isIsomorphicWith(g2) == result; |
| txnRollback(g1); |
| if (!rslt) |
| { |
| System.out.println("g1:"); |
| m1.write(System.out, "N-TRIPLE"); |
| System.out.println("g2:"); |
| m2.write(System.out, "N-TRIPLE"); |
| } |
| assertTrue("Isomorphism test failed", rslt); |
| } |
| |
| protected Graph getClosed() |
| { |
| Graph result = producer.newInstance(); |
| result.close(); |
| return result; |
| } |
| |
| /** |
| * This test exposed that the update-existing-graph functionality was broken |
| * if the target graph already contained any statements with a subject S |
| * appearing as subject in the source graph - no further Spo statements were |
| * added. |
| */ |
| @ContractTest |
| public void testPartialUpdate() |
| { |
| Graph source = graphWith(producer.newInstance(), "a R b; b S e"); |
| Graph dest = graphWith(producer.newInstance(), "b R d"); |
| txnBegin(source); |
| try |
| { |
| GraphExtract e = new GraphExtract(TripleBoundary.stopNowhere); |
| e.extractInto(dest, node("a"), source); |
| txnCommit(source); |
| } catch (RuntimeException e) |
| { |
| txnRollback(source); |
| e.printStackTrace(); |
| fail(e.getMessage()); |
| |
| } |
| txnBegin(source); |
| assertIsomorphic(graphWith("a R b; b S e; b R d"), dest); |
| txnRollback(source); |
| } |
| |
| /** |
| * Ensure that triples removed by calling .remove() on the iterator returned |
| * by a find() will generate deletion notifications. |
| */ |
| @ContractTest |
| public void testIterator_Remove() |
| { |
| Graph graph = graphWith(producer.newInstance(), "a R b; b S e"); |
| graph.getEventManager().register(GL); |
| txnBegin(graph); |
| Triple toRemove = triple("a R b"); |
| ExtendedIterator<Triple> rtr = graph.find(toRemove); |
| assertTrue("ensure a(t least) one triple", rtr.hasNext()); |
| txnRollback(graph); |
| try |
| { |
| rtr.next(); |
| rtr.remove(); |
| rtr.close(); |
| GL.assertHas("delete", graph, toRemove); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| @ContractTest |
| public void testTransactionHandler_Commit() |
| { |
| Graph g = producer.newInstance(); |
| if (g.getTransactionHandler().transactionsSupported()) |
| { |
| Graph initial = graphWith("initial hasValue 42; also hasURI hello"); |
| Graph extra = graphWith("extra hasValue 17; also hasURI world"); |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, initial); |
| g.getTransactionHandler().commit(); |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, extra); |
| g.getTransactionHandler().commit(); |
| Graph union = memGraph(); |
| GraphUtil.addInto(union, initial); |
| GraphUtil.addInto(union, extra); |
| g.getTransactionHandler().begin(); |
| assertIsomorphic(union, g); |
| g.getTransactionHandler().abort(); |
| // Model inFiIProducer<TransactionHandler>le = |
| // ModelFactory.createDefaultModel(); |
| // inFile.read( "file:///" + foo, "N-TRIPLES" ); |
| // assertIsomorphic( union, inFile.getGraph() ); |
| } |
| } |
| |
| @ContractTest |
| public void testTransactionHandler_Abort() |
| { |
| Graph g = producer.newInstance(); |
| if (g.getTransactionHandler().transactionsSupported()) |
| { |
| Graph initial = graphWith(producer.newInstance(), |
| "initial hasValue 42; also hasURI hello"); |
| Graph extra = graphWith(producer.newInstance(), |
| "extra hasValue 17; also hasURI world"); |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, initial); |
| g.getTransactionHandler().commit(); |
| |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, extra); |
| g.getTransactionHandler().abort(); |
| |
| g.getTransactionHandler().begin(); |
| assertIsomorphic(initial, g); |
| g.getTransactionHandler().abort(); |
| } |
| } |
| |
| @ContractTest |
| public void testTransactionHandler_CommitThenAbort() |
| { |
| Graph g = producer.newInstance(); |
| if (g.getTransactionHandler().transactionsSupported()) |
| { |
| Graph initial = graphWith(producer.newInstance(), |
| "Foo pings B; B pings C"); |
| Graph extra = graphWith(producer.newInstance(), |
| "C pingedBy B; fileGraph rdf:type Graph"); |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, initial); |
| g.getTransactionHandler().commit(); |
| g.getTransactionHandler().begin(); |
| GraphUtil.addInto(g, extra); |
| g.getTransactionHandler().abort(); |
| g.getTransactionHandler().begin(); |
| assertIsomorphic(initial, g); |
| g.getTransactionHandler().abort(); |
| // Model inFile = ModelFactory.createDefaultModel(); |
| // inFile.read( "file:///" + foo, "N-TRIPLES" ); |
| // assertIsomorphic( initial, inFile.getGraph() ); |
| } |
| } |
| |
| // |
| // Test that literal typing works when supported |
| // |
| |
| // used to find the object set from the returned set for literal testing |
| |
| private static final Function<Triple, Node> getObject = new Function<Triple, Node>() |
| { |
| @Override |
| public Node apply(Triple t) |
| { |
| return t.getObject(); |
| } |
| }; |
| |
| private void testLiteralTypingBasedFind(final String data, final int size, |
| final String search, final String results, boolean reqLitType) |
| { |
| |
| Graph g = producer.newInstance(); |
| |
| if (!reqLitType || g.getCapabilities().handlesLiteralTyping()) |
| { |
| graphWith(g, data); |
| |
| Node literal = NodeCreateUtils.create(search); |
| // |
| txnBegin(g); |
| assertEquals("graph has wrong size", size, g.size()); |
| Set<Node> got = g.find(Node.ANY, Node.ANY, literal) |
| .mapWith(getObject).toSet(); |
| assertEquals(nodeSet(results), got); |
| txnRollback(g); |
| } |
| } |
| |
| @ContractTest |
| public void testLiteralTypingBasedFind() |
| { |
| testLiteralTypingBasedFind("a P 'simple'", 1, "'simple'", "'simple'", |
| false); |
| testLiteralTypingBasedFind("a P 'simple'xsd:string", 1, "'simple'", |
| "'simple'xsd:string", true); |
| testLiteralTypingBasedFind("a P 'simple'", 1, "'simple'xsd:string", |
| "'simple'", true); |
| // ensure that adding identical strings one with type yields single |
| // result |
| // and that querying with or without type works |
| testLiteralTypingBasedFind("a P 'simple'xsd:string", 1, |
| "'simple'xsd:string", "'simple'xsd:string", false); |
| testLiteralTypingBasedFind("a P 'simple'; a P 'simple'xsd:string", 1, |
| "'simple'", "'simple'xsd:string", true); |
| testLiteralTypingBasedFind("a P 'simple'; a P 'simple'xsd:string", 1, |
| "'simple'xsd:string", "'simple'", true); |
| testLiteralTypingBasedFind("a P 'simple'; a P 'simple'xsd:string", 1, |
| "'simple'", "'simple'", true); |
| testLiteralTypingBasedFind("a P 'simple'; a P 'simple'xsd:string", 1, |
| "'simple'xsd:string", "'simple'xsd:string", true); |
| testLiteralTypingBasedFind("a P 1", 1, "1", "1", false); |
| testLiteralTypingBasedFind("a P '1'xsd:float", 1, "'1'xsd:float", |
| "'1'xsd:float", false); |
| testLiteralTypingBasedFind("a P '1'xsd:double", 1, "'1'xsd:double", |
| "'1'xsd:double", false); |
| testLiteralTypingBasedFind("a P '1'xsd:float", 1, "'1'xsd:float", |
| "'1'xsd:float", false); |
| testLiteralTypingBasedFind("a P '1.1'xsd:float", 1, "'1'xsd:float", "", |
| false); |
| testLiteralTypingBasedFind("a P '1'xsd:double", 1, "'1'xsd:int", "", |
| false); |
| testLiteralTypingBasedFind("a P 'abc'rdf:XMLLiteral", 1, "'abc'", "", |
| false); |
| testLiteralTypingBasedFind("a P 'abc'", 1, "'abc'rdf:XMLLiteral", "", |
| false); |
| // |
| // floats & doubles are not compatible |
| // |
| testLiteralTypingBasedFind("a P '1'xsd:float", 1, "'1'xsd:double", "", |
| false); |
| testLiteralTypingBasedFind("a P '1'xsd:double", 1, "'1'xsd:float", "", |
| false); |
| testLiteralTypingBasedFind("a P 1", 1, "'1'", "", false); |
| testLiteralTypingBasedFind("a P 1", 1, "'1'xsd:integer", |
| "'1'xsd:integer", false); |
| testLiteralTypingBasedFind("a P 1", 1, "'1'", "", false); |
| testLiteralTypingBasedFind("a P '1'xsd:short", 1, "'1'xsd:integer", |
| "'1'xsd:short", true); |
| testLiteralTypingBasedFind("a P '1'xsd:int", 1, "'1'xsd:integer", |
| "'1'xsd:int", true); |
| } |
| |
| @ContractTest |
| public void testQuadRemove() |
| { |
| Graph g = producer.newInstance(); |
| txnBegin(g); |
| assertEquals(0, g.size()); |
| txnRollback(g); |
| Triple s = triple("x rdf:subject s"); |
| Triple p = triple("x rdf:predicate p"); |
| Triple o = triple("x rdf:object o"); |
| Triple t = triple("x rdf:type rdf:Statement"); |
| txnBegin(g); |
| g.add(s); |
| g.add(p); |
| g.add(o); |
| g.add(t); |
| txnCommit(g); |
| txnBegin(g); |
| assertEquals(4, g.size()); |
| txnRollback(g); |
| txnBegin(g); |
| g.delete(s); |
| g.delete(p); |
| g.delete(o); |
| g.delete(t); |
| txnCommit(g); |
| txnBegin(g); |
| assertEquals(0, g.size()); |
| txnRollback(g); |
| } |
| |
| @ContractTest |
| public void testSizeAfterRemove() |
| { |
| Graph g = graphWith(producer.newInstance(), "x p y"); |
| try |
| { |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g.find(triple("x ?? ??")); |
| txnRollback(g); |
| it.removeNext(); |
| txnBegin(g); |
| assertEquals(0, g.size()); |
| txnRollback(g); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| @ContractTest |
| public void testBrokenIndexes() |
| { |
| Graph g = graphWith(producer.newInstance(), "x R y; x S z"); |
| try |
| { |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g.find(Node.ANY, Node.ANY, Node.ANY); |
| txnRollback(g); |
| it.removeNext(); |
| it.removeNext(); |
| txnBegin(g); |
| assertFalse(g.find(node("x"), Node.ANY, Node.ANY).hasNext()); |
| assertFalse(g.find(Node.ANY, node("R"), Node.ANY).hasNext()); |
| assertFalse(g.find(Node.ANY, Node.ANY, node("y")).hasNext()); |
| txnRollback(g); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| @ContractTest |
| public void testBrokenSubject() |
| { |
| Graph g = graphWith(producer.newInstance(), "x brokenSubject y"); |
| try |
| { |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g.find(node("x"), Node.ANY, Node.ANY); |
| txnRollback(g); |
| it.removeNext(); |
| txnBegin(g); |
| assertFalse(g.find(Node.ANY, Node.ANY, Node.ANY).hasNext()); |
| txnRollback(g); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| @ContractTest |
| public void testBrokenPredicate() |
| { |
| Graph g = graphWith(producer.newInstance(), "x brokenPredicate y"); |
| try |
| { |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g.find(Node.ANY, |
| node("brokenPredicate"), Node.ANY); |
| txnRollback(g); |
| it.removeNext(); |
| txnBegin(g); |
| assertFalse(g.find(Node.ANY, Node.ANY, Node.ANY).hasNext()); |
| txnRollback(g); |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| } |
| |
| @ContractTest |
| public void testBrokenObject() |
| { |
| Graph g = graphWith(producer.newInstance(), "x brokenObject y"); |
| |
| try |
| { |
| txnBegin(g); |
| ExtendedIterator<Triple> it = g.find(Node.ANY, Node.ANY, node("y")); |
| txnRollback(g); |
| it.removeNext(); |
| txnBegin(g); |
| assertFalse(g.find(Node.ANY, Node.ANY, Node.ANY).hasNext()); |
| txnRollback(g); |
| |
| } catch (UnsupportedOperationException e) |
| { |
| // No Iterator.remove |
| } |
| |
| } |
| |
| } |